how to add condition to pagination in cakephp 1.3 - cakephp

how to convert this statment to pagination with condition rules
$comment = $this->Article->Comment->find('all',
array('conditions' =>
array('Comment.article_id' => $id, 'Comment.status' => 1)));
i do this but i get parce error
var $paginate = array(
'limit' => 5,
'page' => 1,
'order' => array('Comment.created'=>'desc'),
'conditions' => array('Comment.article_id' => $id, 'Comment.status' => 1)
);
$this->Article->Comment->recursive = 1;
this->set('comment', $this->paginate());

Follow the step-by-step instructions here.

Related

Paginator not generating links

I'm stuck on this... Here's my code:
private function moderators () {
$this->loadModel('Moderator');
$this->Moderator->Behaviors->load('Containable');
$this->Paginator = $this->Components->load('Paginator');
$this->Paginator->settings = array(
'contain' => array(
'ModeratorPersonalData' => array(
'conditions' => array('language' => $this->params['language']),
),
'Thumb',
'Image',
),
'limit' => 1,
'conditions' => array('role' => 'moderator'),
);
$moderators = $this->Paginator->paginate('Moderator');
$this->set('moderators', $moderators);
}
The pagination works, when I type the url for page 2 manually it takes me there, but it isn't showing clickable links.
You did use Paginator helper in your view file, did't you?
http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper

Cake php count distinct

How can this Cakephp query be made to count distinct?
$matches = $this->Product->find('count', array(
'conditions' => array(
"Product.brand_id" => $brand['Brand']['id'],
'Product.active' => 1
));
Something like this?
$matches = $this->Product->find('count', array(
'fields' => 'DISTINCT Product.brand_id',
'conditions' => array("Product.brand_id" => $brand['Brand']['id'],
'Product.active' => 1)
));

Pagination is not working in cakephp

My code for controller:
public $paginate = array(
'paramType' => 'querystring',
'limit' => 3,
);
$this->paginate['Comment'] = array(
'conditions' => array('Comment.post_id' => $this->params['id']));
$this->set('comments',$this->paginate('Commant'));
When I do
pr($this->paginate['Comment'] = array(
'conditions' => array('Comment.post_id' => $this->params['id']))); exit;
The output is
Array
(
[conditions] => Array
(
[Response.claim_id] => 4
)
)
But instead of finding comment related to post it shows all post from db
Once I tried
pr($this->paginate['Comment'] = array(
'conditions' => array('Comment.id' => $this->params['id']))); exit;
And the Result was same
Array
(
[conditions] => Array
(
[Response.id] => 4
)
)
Can any one suggest me why pagination is not woking
Use
public $paginate = array(
'paramType' => 'querystring',
'limit' => 3,
);
in controller
$this->set('comments',$this->paginate('Response',
array('Response.claim_id' => $id)));
in your function
And define Paginator component in controller
You don't need to index your $this->paginate array with the model.
As you are using a Controller variable $this->paginate means that it doesn't need to be indexed using the model.

CakeDC Search and Tag plugin - search for multiple tags

Hopefully I'm missing something simple here. I'm using the CakeDC Search and Tags plugin for my cake (2.3.4) app.
Along with generic search by field functionality I want the user to be able to search by tags. I've almost got this working but the search will only display results if you search for a single tag not multiples. For example, if I add an article with the following tags - black, white, red. The article will only show in the search results if I search for a single tag (say, black) and not all 3, or even 2... What am I missing?
Heres my code:
Article.php model
class Article extends AppModel {
public $actsAs = array(
'Upload.Upload' => array(
'screenshot1' => array (
'fields' => array (
'dir' => 'dir'
),
'thumbnailMethod' => 'php',
'thumbnailSizes' => array(
'xvga' => '1024x768',
'vga' => '640x480',
'thumb' => '80x80'
),
),
),
'Search.Searchable',
'Tags.Taggable'
);
// Search plugin filters
public $filterArgs = array(
'title' => array('type' => 'like'),
'environment' => array('type' => 'like'),
'description' => array('type' => 'like'),
'error' => array('type' => 'like'),
'cause' => array('type' => 'like'),
'resolution' => array('type' => 'like'),
'live' => array('type' => 'value'),
'synced' => array('type' => 'value'),
'tags' => array('type' => 'subquery', 'method' => 'findByTags', 'field' => 'Article.id'),
array('name' => 'search', 'type' => 'query', 'method' => 'filterQuery'),
);
// This is the OR query that runs when the user uses the client side signle field search
public function filterQuery($data = array()) {
if(empty($data['search'])) { // search is the name of my search field
return array();
}
$query = '%'.$data['search'].'%';
return array(
'OR' => array(
'Article.title LIKE' => $query,
'Article.description LIKE' => $query,
'Article.error LIKE' => $query,
)
);
}
// Find by tags method
public function findByTags($data = array()) {
$this->Tagged->Behaviors->attach('Containable', array('autoFields' => false));
$this->Tagged->Behaviors->attach('Search.Searchable');
$query = $this->Tagged->getQuery('all', array(
'conditions' => array('Tag.name' => $data['tags']),
'fields' => array('foreign_key'),
'contain' => array('Tag')
));
return $query;
}
public $hasAndBelongsToMany = array(
'Category' => array(
'className' => 'Category',
'joinTable' => 'articles_categories',
'foreignKey' => 'article_id',
'associationForeignKey' => 'category_id',
'unique' => 'keepExisting',
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
),
'Tag' => array('with' => 'Tagged')
);
Controller method
public function admin_advancedSearch() {
// Disable validation for this action
$this->Article->validate = array();
// For search plugin
$this->Prg->commonProcess();
// Set searched for details
$this->set('searchedFor', $this->passedArgs);
// If passed args are all empty
if ($this->passedArgs) {
if (empty($this->passedArgs['title']) AND
empty($this->passedArgs['environment']) AND
empty($this->passedArgs['description']) AND
empty($this->passedArgs['error']) AND
empty($this->passedArgs['cause']) AND
empty($this->passedArgs['resolution']) AND
empty($this->passedArgs['live']) AND
empty($this->passedArgs['synced']) AND
empty($this->passedArgs['tags'])) {
$this->Session->setFlash('Please enter at least one search criteria', 'flash_failure');
// Set this var for checks in view
$this->set('emptySeach', true);
} else {
$paginateConditions = $this->Article->parseCriteria($this->passedArgs);
$this->paginate = array('conditions' => array(
$paginateConditions),
'limit' => 10,
'order' => array('Article.modified' => 'DESC'));
$this->set('articles', $this->paginate());
// Count number of results
$count = 0;
foreach ($this->paginate() as $result) {
$count++;
}
$this->set('resultsCount', $count);
// Search was not empty - set flag for view
$this->set('emptySeach', false);
}
}
// Set layout
$this->layout = 'admin';
//debug($this->passedArgs);
}
All plugins are loaded successfully from bootstrap, searches work fine without tags. Searches with tags only work if one tag is entered....
*EDIT *
If I debug $query from the findByTags method I get this:
'SELECT `Tagged`.`foreign_key` FROM `knowledgebase`.`tagged` AS `Tagged` LEFT JOIN `knowledgebase`.`tags` AS `Tag` ON (`Tagged`.`tag_id` = `Tag`.`id`) WHERE `Tag`.`name` = 'kia, rio, red''
So it looks like its trying to find a single tag with all the searched for tags in its name. How can I make the WHERE part an IN?
For example:
WHERE `Tag`.`name` IN ('kia', 'rio', 'red')
Thanks
Use the "method" https://github.com/cakedc/search#behavior-and-model-configuration key her to pass the search args to a customized method.
The example here shows you exactly how this works https://github.com/cakedc/search#full-example-for-modelcontroller-configuration-with-overriding
public $filterArgs = array(
'some_related_table_id' => array('type' => 'value'),
'search'=> array('type' => 'like', 'encode' => true, 'before' => false, 'after' => false, 'field' => array('ThisModel.name', 'OtherModel.name')),
'name'=> array('type' => 'query', 'method' => 'searchNameCondition')
);
public function searchNameCondition($data = array()) {
$filter = $data['name'];
$cond = array(
'OR' => array(
$this->alias . '.name LIKE' => '' . $this->formatLike($filter) . '',
$this->alias . '.invoice_number LIKE' => '' . $this->formatLike($filter) . '',
));
return $cond;
}
Inside your custom method explode() the tags and make them an array so that CakePHP is using them as IN() or better (in can become slow) make it a chain of AND or OR.

cakephp find() question

I want to convert following mysql statement into cakephp query syntax.Please help me. Here is my query.SELECT * FROM post WHERE (user_id == $id OR awarded_to = $id ) AND id = $id
Here is my cakephp query. is it wrong.
$this->Post->find('all',
array('conditions' => array('OR' =>
array('Post.user_id' => $id),
array('Post.awarded_to' => $id)
),
'AND' =>
array('Post.id' => $id)
))
This one's on the house, but next time read the docs.
$this->Post->find('all', array(
'conditions' => array(
'OR' => array(
array('Post.user_id' => $id),
array('Post.awarded_to' => $id)
),
'Post.id' => $id
)
));
The 2 OR arrays need to be inside an array themself, and there's no need for AND.
Just add Post.id = $id below the OR condition without you give "and" it's automatic read as and condition...
$this->Post->find('all', array(
'conditions' => array(
'OR' => array('Post.user_id' => $id),
array('Post.awarded_to' => $id)
),
'Post.id' => $id
));
You are very close with your query, just you need little modification like to remove 'AND' in conditions array after 'OR' as:
$this->Post->find('all', array(
'conditions' => array(
'OR' => array(
array('Post.user_id' => $id),
array('Post.awarded_to' => $id)
),
'Post.id' => $id
)
));
Or
$this->Post->find('all', array(
'conditions' => array(
'Post.id' => $id
)
));
The second option will be the best for you if you are passing tables primary key 'id' in AND conditions.

Resources