Originaly posted on cakephp Q&A but i'll put it up here in hope of getting some answers.
I have a bunch of companies that has a status of 0 as default but sometimes get a higher status. Now i want to use the high status if exists but revert to 0 if not. i have tried a bunch of different approaches but i always get either only the ones with status 0 or the ones with the status i want, never giving me status if exists and 0 if not.
Gives me only the status i specify, not giving me the ones with status 0:
'Company' => array (
'conditions' => array (
'OR' => array(
'Company.status' => 0,
'Company.status' => $status,
)
)
)
Gives me only status of 0:
'Company' => array (
'conditions' => array (
'OR' => array(
'Company.status' => $status,
'Company.status' => 0
)
)
)
Status definition and retrieving data in code:
function getCountry($id = null, $status = null) {
// Bunch of code for retrieving country with $id and all it's companies etc, all with status 0.
$status_less_companies = $this->Country->find...
if ($status) {
$status_companies = $this->Country->find('first', array(
'conditions' => array(
'Country.id' => $id
),
'contain' => array(
'Product' => array (
'Company' => array (
'conditions' => array (
'OR' => array(
'Company.status' => $status,
'Company.status' => 0
)
)
)
)
)
)
}
// Mergin $status_less_companies and $status_companies and returning data to flex application.
}
I changed the name for the models for this question just to make more sense, people are generaly frighten away when i tell them i work with cakephp for my flex application. I guess the logic to this question doesn't make sense but trust me that it makes sense in my application.
Thanks!
Try
'Company' => array (
'conditions' => array (
'OR' => array(
array('Company.status' => 0),
array('Company.status' => $status),
)
)
)
In the cookbook it says to wrap the or conditions in arrays if they are pertaining to the same field
http://book.cakephp.org/2.0/en/models/retrieving-your-data.html#complex-find-conditions
I'm not sure to have understood what results you expect. If you want to retrieve all records having status = 0, plus let's say the one having status = 3, you could use an 'IN' instead of an 'OR'.
In Cake, you would write it like this:
$status = 3;
$conditions = array('Company.status' => array(0, $status));
You can also fetch record by using following method:
put values in an array
e.g. $arr=array(1,2);
$res = $this->Model->find('all', array(
'conditions' =>array('Model.filedname'=>$arr),
'model.id' => 'desc'
));
I hope you will find answer.
$this->loadModel('Color');
$colors = $this->Color->find('all', [
'conditions' => [
'Color.is_blocked' => 0,
'Color.is_deleted' => 0,
'OR' => [
[
'Color.isAdmin' => $user_data['id'],
],
[
'Color.isAdmin' => 0,
]
],
]
]);
Related
I have a multi array and I need to combine it with other. This array is made for send in XML format to SOAP, so it need to have the correct structure.
This array is like an invoice, it have "items" which i have to repeat. So, i think in make two arrays (one have always the same structure) and add the items array.
The problem is that if I use merge, I could not put the second array in the correct key. Here an example.
This is the correct array structure:
$params = array(
'authRequest' =>
array( 'token' => 'token',
'sign' => 'sign',
'cuitRepresentada' => 'CUIT' ),
'comprobanteRequest' =>
array( 'codigoTipoComprobante' => $codtipcbte,
'numeroPuntoVenta' => $ptovta,
'numeroComprobante' => $cbte,
**'arrayItems' =>
array( 'item' =>
array(
array(
'tipo'=> $compreqitem['tipo'],
'codigoTurismo'=> $compreqitem['codTur'],
'descripcion'=> $compreqitem['descrip'],
'codigoAlicuotaIVA'=> $compreqitem['codAlic'],
'importeIVA'=> $compreqitem['impIva'],
'importeItem'=> $compreqitem['impItem'],
),
array(
'tipo'=> $compreqitem['tipo'],
'codigoTurismo'=> $compreqitem['codTur'],
'descripcion'=> $compreqitem['descrip'],
'codigoAlicuotaIVA'=> $compreqitem['codAlic'],
'importeIVA'=> $compreqitem['impIva'],
'importeItem'=> $compreqitem['impItem'],
),
),
),**
'arraySubtotalesIVA' =>
array( 'subtotalIVA' =>
array(
'codigo'=> $compreqiva['codIva'],
'importe'=> $compreqiva['importe'],
),
),
),
);
So, i build the array with "arrayItems" empty
'arrayItems' => array(),
Then i build the arrayItem array:
$arrayitems =
array('arrayItems' =>
array( 'item' =>
array(
array(
'tipo'=> $compreqitem['tipo'],
'codigoTurismo'=> $compreqitem['codTur'],
'descripcion'=> $compreqitem['descrip'],
'codigoAlicuotaIVA'=> $compreqitem['codAlic'],
'importeIVA'=> $compreqitem['impIva'],
'importeItem'=> $compreqitem['impItem'],
),
array(
'tipo'=> $compreqitem['tipo'],
'codigoTurismo'=> $compreqitem['codTur'],
'descripcion'=> $compreqitem['descrip'],
'codigoAlicuotaIVA'=> $compreqitem['codAlic'],
'importeIVA'=> $compreqitem['impIva'],
'importeItem'=> $compreqitem['impItem'],
),
),
),
);
Then i use merge to join both array:
$resultado = array_merge($params['comprobanteRequest'], $arrayitems);
Works, but the first key is deleted...
'authRequest' =>
array( 'token' => 'token',
'sign' => 'sign',
'cuitRepresentada' => 'CUIT' ),
I dont know why is deleted, maybe the merge function is not the corect way...
Thanks in advance!
If in your first array, arrayItems is always empty, then you don't need a merge, just set the value :
$params['comprobanteRequest']['arrayItems'] = $arrayItems['arrayItems'];
Of course this can be simplified, since $arrayItems contains only one key, but you get the spirit.
Sorry for confusing title. But I don't know how to explain this.(I don't speak that good English)
Here is a picture to make it alittle bit more clear:
http://img823.imageshack.us/img823/8812/edxt.png
If pic_name=328.jpg AND user=myhrmans return value of 1
else if you cant find value user=myhrmans return 0 for example. Anyway I can pull this off?
Thank you :)
Not sure to understand precisely what you mean, but I'm going to make an attempt.
Your query should be written somehow like this one:
SELECT user, pic_name,
IF(user = 'myhrmans' AND pic_name = '328.jpg', 1, 0) AS value
FROM yourtable
WHERE user = myhrmans;
When executed from PHP (and after fetching the values), your query will return this array:
$result = array(
0 => array(
'user' => 'myhrmans',
'pic_name' => '326.jpg',
'value' => 0
),
1 => array(
'user' => 'myhrmans',
'pic_name' => '329.jpg',
'value' => 0
),
2 => array(
'user' => 'myhrmans',
'pic_name' => '328.jpg',
'value' => 1
),
3 => array(
'user' => 'myhrmans',
'pic_name' => '319.jpg',
'value' => 0
)
);
Which, if I understood, approaches what you want.
I want to match course_id with $courseInfo which is fetching from $cLID.
When I change this $clID['Relationscl']['course_id'] line as 1 everything is ok, but the other way an error appears like Undefined index: Relationscl.
Here is my code:
$this->loadModel('Course');
$this->loadModel('Lecturer');
$clID = $this->Relationscl->find('all', array(
'conditions' => array(
'student_id' => $id
),
'fields' => array(
'course_id','lecturer_id'
)
));
$this->set('clIDs', $clID);
$courseInfo = $this->Course->find('first',array(
'conditions' => array(
'course_id' => $clID['Relationscl']['course_id']
),
'fields' => array(
'course_name','course_code','course_credit'
)
));
$this->set('cInfos', $courseInfo);
Correct me if I'm wrong, but the find('all') function returns and indexed array, so it should be something like
$clID = array( 0 => array('Relationscl'=>array('course_id'=>1 /*and more fields*/)),
1 => array('Relationscl'=>array('course_id'=>2 /*and more fields*/))
/*etc*/);
So clearly $clID['Relationscl'] is undefined. Try with $clID[0]['Relationscl']. Though even that seems weird, why would you do a find('all') if you only plan on using the one record, isn't find('first') better? Or set that $courseInfo definition inside a loop?
how do I build a find() query in cakePHP using these conditions:
Find where
MyModel.x = 1 and MyModel.y = 2 OR
MyModel.x = 1 and MyModel.y value does not exist (or is equal to empty string)
Can somebody tell me how I can go about building such find query?
I'm gonna give you some pointers, but you need to try to do this as it's very basic and it's always good to practice.
A basic find in cake is in the form of
$this->ModelName->find('all');
This in its default form does a SELECT * from model_names (convention is to have singular ModelName for plural table name - model_names)
To add conditions:
$this->ModelName->find('all', array('conditions' => array('ModelName.x' => 1));
To add AND conditions
$this->ModelName->find('all', array('conditions' => array(
'ModelName.x' => 1, 'ModelName.y' => 2
));
To add OR conditions
$this->ModelName->find('all', array('conditions' => array(
'OR' => array(
'ModelName.x' => 1, 'ModelName.y' => 2
)
));
To combine both
$this->ModelName->find('all', array('conditions' => array(
'ModelName.y is not' => null,
'OR' => array(
'ModelName.x' => 1, 'ModelName.y' => 2
)
));
// where y is not null and (x = 1 or y = 2)
http://book.cakephp.org/1.3/view/1030/Complex-Find-Conditions
(btw I'm sure there will be users giving you the exact answers, so just take my answer for your reference :) )
$this->MyModel->find('all', array('conditions' => array(
'OR' => array(
array(
'MyModel.x' => 1,
'MyModel.y' => 1
),
array(
'MyModle.x' => 1,
'OR' => array(
array('MyModel.y' => NULL),
array('MyModel.y' => '')
)
)
)
)));
I apologize for the horrible title, I couldn't think of how to explain my problem.
In my database I have the following tables, articles, tags, and articles_tags. An article can have many tags.
Currently I am able to grab all the articles, with all the tags, but I want to be able to find articles based upon it's tags.
My select is simple:
$articles = $this->Article->find('all', array(
// extra condition to check for tag, maybe?
'conditions' => array('Article.status' => 'active'),
'limit' => $this->articles_per_page,
'offset' => ($page_num-1)*$this->articles_per_page
));
My return from the database is as follows:
Array
(
[0] => Array
(
[Article] => Array
(
[id] => 1
)
[Tag] => Array
(
[0] => Array
(
[id] => 1
[name] => Ruby
[slug] => ruby
[uses] => 1
[ArticlesTag] => Array
(
[id] => 1
[article_id] => 1
[tag_id] => 1
)
)
)
)
What do I do if I only want to return the articles with a Ruby tag?
Try this
// In your Article model
function getArticleByTagSql($tag)
{
$dbo = $this->getDataSource();
$subQuery = $dbo->buildStatement(
array(
'fields' => array('DISTINCT(ArticlesTag.article_id)'),
'table' => "articles_tags",
'joins' => array(
array('table' => 'tags',
'alias' => 'Tag',
'type' => 'INNER',
'conditions' => array('ArticlesTag.tag_id = Tag.id')
)
),
'alias'=>"ArticlesTag",
'conditions' => array("Tag.name"=>Sanitize::clean($tag_words)),
'order' => null,
'group' => "ArticlesTag.article_id"
),
$this
);
$subQuery = ' Article.id IN (' . $subQuery . ')';
return $dbo->expression($subQuery);
}
// In your Articles Controller
$this->paginate['conditions'][] = $this->Article->getArticleByTagSql($tag_name);
$this->paginate['conditions'][] = array('Article.status' => 'active');
$this->paginate['limit'] = $this->articles_per_page;
// or as per your example
$articles = $this->Article->find('all', array(
// extra condition to check for tag, maybe?
'conditions' => array('Article.status' => 'active',$this->Article->getArticleByTagSql($tag_name)),
'limit' => $this->articles_per_page,
'offset' => ($page_num-1)*$this->articles_per_page
));
For conditions like this you can use the LinkableBehavior. It's designed for exact your wanted result. In case you don't want to use it, you have to do a query on the tag controller:
$this->Tag->find('all', array('conditions' => array('Tag.name' => 'ruby')));
Not possible directly.
The easiest way is to make the query through the tag controller
I'm updating this question with an answer for CakePHP 3.x.
You can find all articles for a given tag using an INNER JOIN. The benefit of this join is that it keeps articles as the primary table in the query. Making this an easy solution when you're paginating results by a HABTM join.
$tag_id = 3; // the ID of the tag
$query = $this->Articles->find('all')
->innerJoin('articles_tags', [
'Articles.id = articles_tags.article_id',
'articles_tags.tag_id' => $tag_id
]);
The first join condition has to be the array key. If you use a => array assignment then CakePHP will pass the articles_tags.article_id as a string argument to the join condition. Which won't work.
You can also stack innerJoin for multiple HABTM conditions. For example; find all articles for a tag and also for a category. You can also use the in query expression to match multiple tags.
You can also use the above in pagination like this $articles = $this->paginate($query);
I'm sure this information is out on the web, but this question was the top of google's results. So maybe this will help others.