I have a table records and another table categories
I want to get get all the records in this categories
$all_categories = '5,6,7,8';
So I am using this code:
$query = $this->Records->find('all',[
'contain' => ['Categories']
]);
if(!empty($search)){
$query->where(['Records.title LIKE' => '%'.$search.'%']);
}
if(!empty($wilaya)){
$query->where(['Records.adresse LIKE' => '%'.$wilaya.'%']);
}
if(!empty($cat)){
$query->where(['Records.category_id =' => $cat]);
} else {
$categories_array = explode(',',$all_categories);
foreach($categories_array as $category) {
$query->where(['Records.category_id =' => $category]);
}
}
When I use this, I'm getting AND-conditions by default.
How can I get OR-conditions instead?
Use IN:
$all_categories = '5,6,7,8';
$categories_array = explode(',',$all_categories);
$query->where(['Records.category_id IN' => $categories_array]);
This should work:
$all_categories = '5,6,7,8';
$array=explode(',',$all_categories);
$query->where(['Records.category_id' => $array], ['Records.category_id' => 'integer[]']);
Note: Edited answer to add information about the column data type. Won't work without this in CakePHP 3.x.
This equals to:
$all_categories = '5,6,7,8';
$array=explode(',',$all_categories);
$query->where(['Records.category_id IN' => $array]);
See Automatically Creating IN Clauses.
Related
I'm trying to store the results of a query in an arrow, but need to do so in a specific format (I think).
The required format I need the results to be in is as follows:
'screenshots' => 'Plugin Screenshots',
This is what I have so far, along with my failed attempt to store the results:
$my_fake_pages = array();
$args = array(
'parent' => 8,
'orderby' => 'name',
'order' => 'ASC'
);
$categories = get_categories($args);
foreach($categories as $category) {
$my_fake_pages[] = $category->slug . '=>' . $category->slug;
}
What troubles me most is I do not understand how I would go about getting the => in there, as without the inverted commas dreamweaver throws up PHP errors.
This is what it would look like normally:
$my_fake_pages = array(
'installation' => 'Plugin Installation',
'usage' => 'Plugin Usage',
'screenshots' => 'Plugin Screenshots',
'changelog' => 'Plugin Changelog',
'feedbacks' => 'Users\' Feedbacks',
);
Any help is appreciated.
foreach($categories as $category) {
$my_fake_pages[$category->slug] = $category->slug;
}
print_r($my_fake_pages);
The notation 'something' => 'another thing' means it's a key/value pair. So all you need to do is change your assignment line to something like $my_fake_pages[$category->slug] = $category->name.
See http://php.net/manual/en/language.types.array.php#language.types.array.examples
I have a table called items and a table called item_pics.
item_pics has an item_id, file_name and a rank field (among others).
What I'm looking for is for each item my index page's $items array to contain the file_name from the item_pics matching the item's item_id with the lowest rank. So I can access like (or something like) this in my Items/index.ctp:
foreach ($items as $item):
$img = $item['Item']['ItemPic']['file_name'];
...
I'm pretty new to CakePHP, this is my first project. I thought that this within the Item model would cause item_pics data to be pulled (although I figured all related item_pics for each item would get pulled rather than just the one with the lowest rank):
public $hasMany = array(
'ItemPic' => array(
'className' => 'ItemPic',
'foreignKey' => 'item_id',
'dependent' => false
)
}
but I can see that no item_pics data is loaded (at the bottom of items/index):
SELECT `Item`.`id`, `Item`.`title`, `Item`.`description`, `Item`.`created`, `Item`.`modified`, `Item`.`type`, `Project`.`id`, `Project`.`item_id`, `Project`.`title`, `Project`.`description`, `Project`.`rank`, `Project`.`created`, `Project`.`modified`
FROM `laurensabc`.`items` AS `Item`
LEFT JOIN `laurensabc`.`projects`
AS `Project`
ON (`Project`.`item_id` = `Item`.`id`)
WHERE `Item`.`type` IN (1, 2)
LIMIT 20
also, while I would like projects to be joined in the view pages, I don't really need them in the index page.
I've done some searching and haven't been able to find exactly what I'm looking for. I suppose I could do a query within the index view item loop, but I'm trying to make sure I do things the right way... the CakePHP way. I assume I need to change something about my model relationships but I haven't had any luck.
CakePHP - Associations - HasMany, this makes it seem like I could order by rank and limit 1. But this didn't work... and even if it did, I wouldn't want that to affect the view pages but rather just the index page.
My Controller looks like this:
public function index($type = null) {
$this->Item->recursive = 0;
$conditions = array();
if ($type == "sale") {
$conditions = array(
"Item.type" => array(self::FOR_SALE, self::FOR_SALE_OR_RENT)
);
} else if ($type == "rent" ) {
$conditions = array(
"Item.type" => array(self::FOR_RENT, self::FOR_SALE_OR_RENT)
);
} else {
$conditions = array("Item.type !=" => self::HIDDEN);
}
$paginated = $this->Paginator->paginate($conditions);
debug($paginated);
$this->set('items', $paginated);
$this->set('title', ($type == null ? "Items for Sale or Rent" : "Items for " . ucwords($type)));
}
I have also tried this on my controller, but it doesn't seem to do anything either:
$this->paginate = array(
'conditions' => $conditions,
'joins' => array(
array(
'alias' => 'ItemPic',
'table' => 'item_pics',
'type' => 'left',
'conditions' => array('ItemPic.item_id' => 'Item.id'),
'order' => array('ItemPic.rank' => 'asc'),
'limit' => 1
)
)
);
$paginated = $this->paginate($this->Item);
First, set containable behavior in AppModel (or if you don't want it on each model, put it on Item model):
public $actsAs = array('Containable');
Then, on your find query:
$items = $this->Item->find('all', array(
'contain' => array(
'ItemPic' => array(
'fields' => array('file_name'),
'order' => 'rank',
'limit' => 1
)
)
));
Then the result array you can access it like:
foreach ($items as $item):
$img = $item['ItemPic']['file_name'];
Edit: Then you should put it on the paginate query:
$this->paginate = array(
'conditions' => $conditions,
'contain' => array(
'ItemPic' => array(
'fields' => array('file_name'),
'order' => 'rank',
'limit' => 1
)
)
);
In this case, I would probably order by rank and limit 1 as you said, and make that a dynamic association just for the index page (See http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#creating-and-destroying-associations-on-the-fly). So use $this->Item->bindModel(array('hasMany' => array('ItemPic' => $options))); (which I believe should replace your current settings for HasMany ItemPic, but you may have to unbindmodel first)
Associations created through bindModel will go through for the next query only, then it'll revert to your normal settings, unless you specifically set an option to keep using the new association.
As for why it's not getting ItemPics with Items, or why trying to order by rank and limit 1 didn't work for you, I can't really say without seeing more of your code.
I am using codeigniter to produce a left join of two tables, but need to remove the brackets that active record applies to the table name. you know SELECT blah FROM ('some table') I really need these brackets to disappear.
here is my input array:
$retrieve_arr = array(
'table' => 'entries',
'select' => array('entries.entry_id', 'entries.score', 'sc_users.name', 'clients.name'),
'joins' => array(
'clients' => 'entries.client_id = clients.client_id',
'sc_users' => 'entries.sc_user_id = sc_users.sc_user_id'
),
'joinType' => 'left',
'where' => 'null'
);
here is my model:
$retrieve = new Data();
if($get_arr['select'] != 'null')
{
$query = $retrieve->db->select($get_arr['select']);
}
foreach($get_arr['joins'] as $additional => $value)
{
$retrieve->db->join($additional, $value, $get_arr['joinType']);
}
if($get_arr['where'] != 'null')
{
foreach ($get_arr['where'] as $name => $value)
{
$retrieve->db->where($name, $value);
}
}
$query = $retrieve->db->get($get_arr['table']);
$queryData = $query->result_array();
return $queryData;
and here is what my query string:
SELECT `entries`.`entry_id`, `entries`.`score`, `sc_users`.`name`, `clients`.`name` FROM (`entries`) LEFT JOIN `sc_users` ON `entries`.`sc_user_id` = `sc_users`.`sc_user_id` LEFT JOIN `clients` ON `sc_users`.`client_id` = `clients`.`client_id`Array
I have been looking for this for a while so your help is very much appreciated.
If you are referring to the ` backticks, in the Select() portion, use a FALSE as the second parameter (refer to the Users Guide for more info)
Please help me to retrieve data from a table by multiple condition in Cakephp
I have one table name: article; I have tried to retrieve data with the code below
I want to get specific id as given in the parameter; article_price > 0 and article_status > 1
public function getArticle($artID = ''){
return $this->find('all', array(
'condition' => array(
'article_id =' => $artID,
'article_price' => '> 0',
'article_status = ' => '1'),
'order' => 'article_id DESC'
));
}
// the out put was selected all data without condition that I want.
What was the problem with my code?
What I found out is I print: echo $this->element ('sql_dump'); and I got the following sql statement:
SELECT `article`.`article_id`, `article`.`name`, `article`.`article_price`, `article`.`article_status` FROM `db_1stcakephp`.`article` AS `article` WHERE 1 = 1 ORDER BY `article_id` DESC
Please help me.
Thank!
If your model name is Article:
public function getArticle($art_id) {
return $this->find('first', array(
'conditions' => array(
'Article.article_id' => $art_id,
'Article.article_price >' => 0,
'Article.article_status >' => 1,
),
));
}
Using 'Model.field' syntax is optional, until your models have relationship and have the same names - for example Article.status and Author.status.
Moving comparison sign into array's key part allows you to do:
'Article.price >' => $minPrice,
'Article.price <=' => $maxPrice,
And I didn't really notice typo in 'conditions'.
I'm using CakePHP's tree behavior and need to know if there is any products in category or it's subcategories since I don't want to view empty categories.
I would like to do something like this:
$cat = $this->Category->find('first',array('conditions'=>array('id'=>$id)));
$test = $this->Category->find('threaded', array(
'conditions' => array(
'Category.lft >=' => $cat['Category']['lft'],
'Category.rght <=' => $cat['Category']['rght'],
'Product.InStock >'=>0 //NOT WORKING
)
));
That would be a starting point to unset not needed array dimensions. In database, categories hasMany products.
What could be best solution to this problem? Is it possible to avoid Product->find in foreach loop with category_id?
Untested
$this->Category->Behaviors->attach->('Containable');
$cat = $this->Category->find('first',array('conditions'=>array('id'=>$id)));
$test = $this->Category->find('threaded', array(
'conditions' => array(
'Category.lft >=' => $cat['Category']['lft'],
'Category.rght <=' => $cat['Category']['rght']),
// use containable behaviour and apply the condition
'contain'=>array('Product'=>array('conditions'=>
array('Product.InStock >'=> 0)
)
)
));