I have a database of locations the user can select from by typing and autocompletion. In my CakePHP controller, I do this:
$locations = $this->Location->find('all', array(
'conditions' => array('Location.name like' => '%'.$term.'%'),
'fields' => array('Location.id', 'Location.name', 'Region.name'),
'order' => array(
array('Location.name = "'.mysql_real_escape_string($term).'"'
=> 'desc'),
'Location.name'
),
'limit' => 10,
'recursive' => 1,
));
It works perfectly fine, but it feels like a hack, and I'd rather not escape SQL literals myself.
The first order by clause is needed since a perfect match might otherwise not make it to the top of the alphabetically sorted list.
I considered moving the equality-test into a virtual field, but I don't feel it's a very elegant solution when the $term is dynamic.
How do I implement this in a better way?
As far as the structure of your query is written this is fine.
In regards to having to escape SQL yourself, this is from the Cookbook:
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.
Related
I have a converted ssp.class.php for PostgreSQL which works fine. However, I need to add ARRAY support to it.
I am hoping someone can give me some guidance/tips on the best way to do approach this, and/or give some example code if possible. I would appreciate it a lot.
You can get the modified file here: ssp.class.pg.php
About DataTables server side processing: https://datatables.net/examples/data_sources/server_side with an example.
I'm a little late to the party, but I found this question while searching google for an answer and wanted to post what I figured out to help the next person who might stumble upon this.
Note: I am using the referenced ssp.class.pg.php
My Solution - Use Heredoc
Using heredoc, you can better define your query using array functions, inner and outer joins, subqueries etc.
In my example, I have a PostgreSQL table that contains a jsonb column named properties. I want to select the value from the last_seen key.
Using Heredoc, I define my table as a query that will return the users last seen date value as a column.
$table = <<<EOT
(
SELECT
id,
unique_id,
properties->>'last_seen' as last_seen
FROM users
WHERE token = '$token'
) temp
EOT;
Then, I can define my columns for the SSP PG class using the returned columns from my table query.
$columns = array(
array( 'db' => 'id', 'dt' => 'id' ),
array( 'db' => 'unique_id', 'dt' => 'unique_id' ),
array( 'db' => 'last_seen', 'dt' => 'last_seen' ));
Finally, I'll use the defined variables to call the simple function.
$data_result = $ssp_pg->simple($request, $conn, $table, $primaryKey, $columns);
can someone help me with this cakephp code ?
i try to append a field in an UpdateAll...
$this->MyModel->updateAll(
array(
'MyModel.Field1' => ***MyModel.Field1 & 'ok'***,
),
array('MyModel.Field2' => 'lorem')
);
As mentioned in the docs, the $fields argument of Model::updateAll() accepts SQL expressions, so just pass whatever is needed, in your case probably a CONCAT operation:
$this->MyModel->updateAll(
array('MyModel.Field1' => "CONCAT(MyModel.Field1, 'ok')"),
array('MyModel.Field2' => 'lorem')
);
And don't forget that the values are not being escaped! In case you are planning to inject user data, make sure that you prepare it properly using DboSource::value(). Unfortunately there is no way to bind parameters when using updateAll(), which should always be the method of choice to insert data when no automatic escaping is being applied.
See also http://book.cakephp.org/2.0/en/models/saving-your-data.html#model-updateall-array-fields-mixed-conditions
is it good or bad practice in CakePHP to have conditions set in the contain of a find query like:
$data = $this->SomeModel->find('all', array(
'contain' => array(
'AnotherModel' => array(
'conditions' => array(
// some conditions
)
)
)
));
In which cases will putting conditions inside a contain be useful, and when should I use it or not. Sorry, this is still confusing to me.
Thank you
I'm not sure whether this is a good idea... First of all, I'm going to assume that this specific case requires you to specify conditions that unique to this case, i.e. not general enough for you to put into your SomeModel model relationship criteria to AnotherModel.
My suggestions would be that you should put those conditions in your overall find conditions, as contain specifies which linked models to return (controlling the joins under the hood). Like in SQL, you can join another table and specify which records to match in your WHERE clause.
From the manual, you can specify conditions in your contain, but they won't affect the results that don't join your model like the overall conditions will.
I'd do this:
$data = $this->SomeModel->find('all', array(
'contain' => array('AnotherModel'),
'conditions' => array(
// some conditions relating to AnotherModel
)
));
Good morning,
I need some help in a survey, which I am not able to do.
Imagine a web application (php), which makes use cakephp.
In this application I have a search field, one normal input.
And imagine that this application has a table in the database with 3 fields, (produtoNome), (categoria), (tags).
how can this research below, I already search for table field (produtoNome).
$this->Anuncio->find('all',array('conditions' => array('produtoNome'=> array('$regex' => (string)$pesq))));
The question is:
How can I do a search, that search the 3 fields of the table not only one?
In other words, when someone types something into the search field, it will perform this search in more than one field of the table.
I tried this:
$produtos = $this->Anuncio->find('all',
array('conditions' =>
array('OR' =>
array(
array('produtoNome'=> array('$regex' => (string)$pesq)),
array('categoria'=> array('$regex' => (string)$pesq))
)
),
)
);
but does not work. Returns nothing.
$produtos = $this->Anuncio->find('all',
array('conditions' =>
array('OR' =>
array(
'produtoNome'=> array('$regex' => (string)$pesq),
'categoria'=> array('$regex' => (string)$pesq)
)
),
)
);
Not sure, but this should do the trick.
I would love to see the query from cake.
Never seen that '$regex' syntax for cake, can't find it in documentation, can't find any reference on the internet - where did you get that from? I'm using cake quite a while now and never came about that (though I never needed regexp for queries)
[sorry, low reputation, could not put this on a comment]
So, I got to do this research.
To work, so I had to modify the 'OR' to '$or'
I have long query on mongodb. I want to write that in php
The query looks like
"department":"xxx","rank":"xxx",
$and:[{"emails.email" :{$ne : ""}},{"emails.email":{$ne:null}}];
I want to convert into php.
"department"=>$xxx,"rank"=>$xxx..??
for converting 'and' I cant come up. please help
The best way to work with the $ modifiers is to use single quotes as seen below. It's close on the syntax however you will want to double check it as I'm certain there may have been a missed bracket.
array(
'department'=>'',
'rank=>'',
'$and'=>array(
'emails.email'=>array('$ne'=>''),
'emails.email'=>array('$ne'=>NULL)
)
);
Good Luck!
You can commit the query that #Frederico wrote however this query could do with some optimisation. Here is a suggestion:
array(
'department' => '',
'rank' => '',
'emails.email' => array('$nin' => array('', null))
)
That will do the job just as good without the $and and the two separate $ne.