Is it possible in a criteria to have AND & OR Operators between addCondition and addInCondition? I have something like this:
$criteria = new CDbCriteria;
//if value is TRUE
$criteria->addCondition('t.value = TRUE');
//if value is False
$criteria->addCondition('t.value = FALSE');
$criteria->addInCondition('t.id',$array);
I don't know where I will put the operators. Thanks.
According the class reference (http://www.yiiframework.com/doc/api/1.1/CDbCriteria#addInCondition-detail':
public CDbCriteria addInCondition(string $column, array $values, string $operator='AND')
The third parameter is the operator which will be added to the existing one, so for you it will be:
$criteria->addInCondition('t.id',$array, 'OR');
Related
Please, i'm writing a function and i need guidance
function($file_name='*'){
File::where('filename',$file_name)->get();
}
I want the filename to pull all the filename columns in the database table when file name is not defined, and when it is it should use the value to pull the right data.
My question is, what should i use as default for filename in in the function input to work?
Even if is raw sql i will appreciate
First of all you are missing, your functions name
function getFile($file_name = null){
$q = File::query();
if($file_name == null ){
// Do nothing this will get all files at the end since you haven't applied a where clause.
}else{
$q = File::where('filename',$file_name);
}
$result = $q->get();
return $result;
}
How do I write a filter which will compare Mylist-values to MyKeyTable-values?
I tried something like the following:
List<string> Mylist = new List<string>();
Mylist.Add("Welcome");
Mylist.Add("Hello");
var output = await client.For<MyKeyTable>()
//this is wrong I knew I need to correct this
.Filter(Mylist.Contains(x=>x.Key))
.FindEntriesAsync();
So output will come with all the values whoes Key-value matches as welcome and hello
Thanks in advance.
Done I tried it using custom expression
ParameterExpression pe = Expression.Parameter(typeof(MyTableClass), "entity");
Expression expression = null;
Expression predicateBody = null;
Expression leftExpression = Expression.Property(pe, "Key");
Expression rightExpression = Expression.Constant("Welcome");
expression = Expression.Equal(leftExpression, rightExpression);
predicateBody = predicateBody == null
? expression
: Expression.OrElse(predicateBody, expression);
function mysql_insert($data_array){
$sql = "insert into `". $this->table_name. '`';
$array_keys = array_keys($data_array);
$array_keys_comma = implode(",\n", preg_replace('/^(.*?)$/', "`$1`", $array_keys));
for($a=0,$b=count($data_array); $a<$b; $a++){ $question_marks .="?,"; }
$array_values = array_values($data_array);
$array_values_comma = implode(",", $array_values);
$sql.= " ($array_keys_comma) ";
$sql.= " values(". substr($question_marks, 0,-1) .")";
$prepare = $this->connDB->prepare($sql);
$insert = $prepare->execute(array($array_values_comma));
}
I want to creat like this universal functions, $data_array-comes from $_POST
This function will work for all form. But i dont know what is my wrong :S
I don't know what is my wrong
That's quite easy to know: number of bound variables does not match number of tokens.
I want to creat like this universal functions, $data_array-comes from $_POST
Here you go: Insert/update helper function using PDO
$array_values_comma is a scalar after you implode() the array. So you always pass an array of one element to your execute() function. You should pass $array_values.
Here's how I'd write this function:
function mysql_insert($data_array){
$columns = array_keys($data_array);
$column_list_delimited = implode(",",
array_map(function ($name) { return "`$name`"; }, $columns));
$question_marks = implode(",", array_fill(1, count($data_array), "?"));
$sql = "insert into `{$this->table_name}` ($column_list_delimited)
values ($question_marks)";
// always check for these functions returning FALSE, which indicates an error
// or alternatively set the PDO attribute to use exceptions
$prepare = $this->connDB->prepare($sql);
if ($prepare === false) {
trigger_error(print_r($this->connDB->errorInfo(),true), E_USER_ERROR);
}
$insert = $prepare->execute(array_values($data_array));
if ($insert === false) {
trigger_error(print_r($prepare->errorInfo(),true), E_USER_ERROR);
}
}
A further improvement would be to do some validation of $this->table_name and the keys of $data_array so you know they match an existing table and its columns.
See my answer to escaping column name with PDO for an example of validating column names.
I kwnow that using an ORM like Doctrine2 for building queries is safe, meaning that parameters are escaped by default.
But i'm guessing that this is not so obvious when using literals and when this literal comes directly from the query string:
$builder = $this->getRepository()->createQueryBuilder('e');
$request = $this->getRequest();
// Loop each allowed filter field and check if exists in $request
foreach($this->getFilterFields() as $filter) :
// Skip falsy values in $request
if(!$value = $request->get($filter)) continue;
// Add OR LIKE %$value% where $value is GET paramter
$like = $builder->expr()->literal("%$value%");
$builder->orWhere($builder->expr()->like("e.$filter", $like));
endforeach;
Should safety be improved in some way?
$queryBuilder->expr returns an ExpressionBuilder object. Inside ExpressionBuilder we find:
public function literal($input, $type = null)
{
return $this->connection->quote($input, $type);
}
So literals do get quoted and should be fine to use.
We also find:
public function like($x, $y)
{
return $this->comparison($x, 'LIKE', $y);
}
public function comparison($x, $operator, $y)
{
return $x . ' ' . $operator . ' ' . $y;
}
$y is fine because it goes through literal first. Do want to be a bit careful about $x. As long as your filterFields are internal then no problem. If they are coming from the user then you need to make sure they are valid.
In Dashcode, if I have a dataSource that has, for example, 2 fields called 'FirstName' and 'Last Name', how do I concatenate the 2 fields into one text field in a list view?
I'm fairly sure it must be to use a value transformer, so say that I assign the 'FirstName' field to the textfield, and add a value transformer... how do I then add the 'LastName' value to the 'value' variable in the transformer.
I'm sure it's to do with dashcode.getDataSource and valueForKeyPath and I think I'm close to the solution but it all seems a bit ungainly so any help would be much appreciated.
Correct - you need to use a Value Transformer.
In the Transformer, you would code as follows:
itemDescription = Class.create(DC.ValueTransformer,{
transformedValue: function(value){
var itemDataSource = dashcode.getDataSource('itemsList'); // The Data Source Name here
var lastName = itemDataSource.selection().valueForKey('lastName'); // Presumes you have a field called lastName
return value + " " + lastName;
}
});
Hope this helps - I battled with this for a day!!!
For future googlers, since there is absolutely no documentation anywhere about this :
When in detailed view to concatenate two fields from same the datasource :
XML
<?xml version="1.0" encoding="utf-8"?>
<immobilier>
<bien>
<ID>1453</ID>
<Titre>Maison / Villa F4</Titre>
<Ville>Sainte Clotilde</Ville>
<Quartier>BRETAGNE</Quartier>
</bien>
</immobilier>
To combine the fields Ville and Quartier create a value transformer like so :
mapAdresse = Class.create(DC.ValueTransformer,{
transformedValue: function(value){
if (value.trim() != "") {
//Replace immoListe with your source name
var itemDataSource = dashcode.getDataSource('immoListe');
//THIS IS THE MOST IMPORTANT : HOW TO FIND THE CURRENTLY SELECTED ITEM INDEX
var selectedIndex = document.getElementById('list').selectedIndex;
//Use the selectedIndex to find the record in the datasource
var quartier = itemDataSource.selection().valueForKey("bien")[selectedIndex].valueForKey("Quartier");
//Concatenate to your liking
if (quartier.trim() != "") value = value + ", "+ quartier;
}
return value;
}
});
Why is this not documented anywhere ?? Beats me !!