Pagination by conditions in cakephp - cakephp

i am having a doubt in using pagination like thing in my application..
where mytable looks like
Entry Firstname Last Name Residential Address Degree Gender Submitter
1 Aruna Chinnamuthu MDu BE Female aruna#gmail.com
2 Nisha Durgaeni MS BE Female nisha#gmail.com
3 Nathiya N Mumbai BE Female nathiya#gmail.com
In my view i am trying to bring the First entry at first and on clicking the next link in the View it must show the Entries for the second submitter and goes on ..
I have seen the pagination concepts in book.cakephp.org. But in all those they have mentioned only to paginate by using limit and order and not by using conditions.. how to do so..
It is possible ??
My submitters is in the array as
function view($formid){
$submitters=$this->Result->find('all',array('conditions'=>array('Result.form_id'=>$formid),'group'=>array('Result.submitter_id')));
foreach($submitters as $submitter)
{
echo $submitter['Result']['submitter_id'];
}
}
That is i am trying to paginate by SUbmitters of my form .. Is it possible in cakephp??Please suggest me..

I think you might be looking to use the Containable behavior. That will let you specify conditions that will apply to the model's data retrievals.
I can't quite discern the rest of your code, as the formatting didn't make it from the OP very well, but I think your conditions are limited to form_id=$formid, right? I'd suggest (before that line) dynamically attaching a Containable behavior that limits the forms to just $formid.
I'm not 100% that this is what you're after, but I might be understanding the question incorrectly.

I am unsure of the CakePHP version that you are using, but in CakePHP 1.2, the Paginate method takes a second parameter. This is the conditions array:
$this->paginate('Result', array( 'id' => 1, 'someOtherCondition' => 'condition' ) );

Related

Get each item in a collection with one query

I have a collection of slugs and want to get each corresponding page with one query.
Something like ...
Page::whereIn('slug', $slugs)->get();
... does only return the first page matching any slug in the collection.
Currently there is a loop, but that are dozens of queries I want to avoid.
Try using the whereRaw method and imploding your array into a string:
Page::whereRaw('slug IN ("' . $slugs->implode('","') . ')')->get();
As it turned out, whereIn was the right way. There was one minor mistake in my logic, and at the same time insufficient seeding data, that blowed everything up.
If someone does not know: whereRaw should be used with caution. To avoid SQL injection vulnerability, all user-submitted entries have to be passed as parameters.
Page::whereRaw('slug IN (?)', [$slug]);
Beware: Wrapping ? with quotes is a syntax error. The passed data will be single-quoted by default, at least on my machineâ„¢.
select * from `pages` where `slug` in ('page');

What is the difference between the way data in input and hidden form types are handled?

Finally, a simple, straight-answer question :D
Background: My company has changed the way that that they handle when certain sites are used. Previously, certain sites were only delivered to on certain weeks; now, every site delivers every week. They have asked me to get rid of the weeks field on their "add new site" form. The link between week and site is still necessary for the code to work, however, so I am trying to hide the field and populate it with every single week.
Auto-populating it is simple. I just do this:
echo $this->Form->input('Week', array('value'=>array('1','2','3','4','5')));
And when I debug the data getting sent from the form, I get the following, which is exactly the way I want it to work.
'Week' => array(
'Week' => array(
(int) 0 => '1',
(int) 1 => '2',
(int) 2 => '3',
(int) 3 => '4',
(int) 4 => '5'
)
So the next step is simply hide that input. Easy, right? I just do one of the following two things to the form:
echo $this->Form->hidden('Week', array('value'=>array('1','2','3','4','5')));
or
echo $this->Form->input('Week', array('value'=>array('1','2','3','4','5'), 'type'=>'hidden'));
All I have done is change the type to hidden. But now, the data returned from debugging the data from the form looks like this:
'Week' => array(
'Week' => '1 2 3 4 5'
So my question is, what is the difference in the way data is handled between a normal "input" field and a "hidden" field. Why does that difference occur, and why is it important? And for this particular issue, how do I get hidden data to behave in the same way as normal input data?
As you said in the comments, Week is a multiple choice input, so that's why the difference in value handling. If the input is something that allows multiple choice (like multiple select or checkboxes), then it's logical all values comes as an array. But the hidden type is basically a hidden text input (ok, maybe not, but I'm simplifying). Look, if you put
echo $this->Form->input('Week', array('type'=>'text', 'value'=>array('1','2','3','4','5')));
you'll get the same string as you have with the input field, so it isn't a matter of if it's hidden or not.
Now, for your case, you can add the week values as an string and change the way you handle the value on post, as a string instead of an array.
But, if by some reason that's not a possibility (too much code to change, etc), then keep the same code you have now, and hide it with css. Something like
echo $this->Form->input('Week', array('value'=>array('1','2','3','4','5'),
'div'=>array('style'=>'display:none')));
should do the trick (maybe a few more styles needs to be added, try with just that first).
I don't like the css solution that much, browsers can interpret css different ways and etc etc... But it fits your needs and you don't have to change anything else.
EDIT
On second though, it is possible to achieve the same array output with just hidden fields. It isn't pretty though. You have to change the name of every input to tell php it's an array, like this
echo $this->Form->input('Week1', array('type'=>'hidden', 'value'=>1, 'name'=>'data[Week][Week][]'));
echo $this->Form->input('Week2', array('type'=>'hidden', 'value'=>3, 'name'=>'data[Week][Week][]'));
echo $this->Form->input('Week3', array('type'=>'hidden', 'value'=>4, 'name'=>'data[Week][Week][]'));
The important part is the name option for every input, see the array reference? Specially the last empty []. This is actually how cakephp sends all data as an array. Have you tried to create a form without the FormHelper in cake? You wouldn't get the post data in $this->request->data['form_name'] unless you set the input names for all your form fields.
Cake sends all post data inside the $data array by naming all the inputs with <input name="data[ModelName][field_name]" and for multiple inputs is <input name="data[ModelName][field_name][]" (with the empty array at the end, so it gets numerically indexed). You can see that using any html inspector on any other form created with the formhelper in cake.
I hope it's clear... I'll stick with the css solution here. The multiple hidden inputs seems messier.

CakeDC Search Plugin producting duplicate conditions

So I'm using the (totally awesome) Cake DC Search plugin. Among other things, I want to have a 'min' and 'max' input, and search for records where 'amount' is within 'min' and 'max', if both are set, or greater-than/less-than min/max if only one is set.
I've got it working - the only problem is that the condition is being included twice in the SQL query. It's pretty obvious why... here's my model code:
public $filterArgs = array(
'range_min' => array('type' => 'query', 'method' => 'findByAmountRange'),
'range_max' => array('type' => 'query', 'method' => 'findByAmountRange'),
// Other rules go here
);
public function findByAmountRange($data = array()) {
// Returns a condition something like 'Model.amount BETWEEN 1 and 100'
}
So because both the 'range_min' and 'range_max' keys of $filterArgs both use the same method (findByAmountRange), then the condition is being included twice.
So, there are three solutions:
Don't worry about it, let the condition be there twice
Create a instance variable in the model, like findByAmountRangeHasBeenCalled, and set it true the first time the method is called, so we know not to call it again in future
Find a more elegant solution. Does the Search plugin have any way to deal with this? Can you set it to make two fields share a common filterArgs method, so that it only gets called once?
Thanks in advance.
PS - I know the test cases for the Search Plugin include a 'make range condition' example, but that's not what I want - I want two fields, with the user able to input into both of them.
OK, so it doesn't look like I'll get a proper answer. So, I've gone for option 1 - just leaving the duplicate condition in the query. Apparently MySQL will run a query optimiser prior to executing, and remove the duplicate condition, and so it won't affect speed in any significant way.

Apply pagination using Sunburnt highlighted search

I am using Sunburnt Python Api for Solr Search. I am using highlighted search in Sunburnt it works fine.
I am using the following code:
search_record = solrconn.query(search_text).highlight("content").highlight("title")
records = search_record.execute().highlighting
Problem is it returns only 10 records. I know it can be change from solr-config.xml but issue is I want all records
I want to apply pagination using highlighted search of Sunburnt.
Given the SOLR-534 issue, which is still unresolved, you can't tell Solr to give you all results, but you can use a really high rows parameter depending on how many documents you expect to have in your index. I don't know anything about sunburnt but I believe something like this should work:
search_record = solrconn.query(search_text).paginate(rows=10000).highlight("content").highlight("title")
You just have to replace the rows value with something enough big depending on your index size.
The general approach to this is to use a paginator:
from django.core.paginator import Paginator
paginator = Paginator(si.query("black"), 30)
Once that's done, you can just paginate through everything:
for result in paginator.object_list:
print result

Incrementing Cakephp database field by a value

I have this field whose value i have to increment the field value by a specific value.
I am using this
$data['quantity'] = 'Order.quantity+1';
which doesnt works for me quantity is a integer coloumn here.
Also will it work when nothing is in database?.
Regards
Himanshu Sharma
I used updateAll in my code to increment views in an article. Therefore, every time an article is visited, I call the following function from within my view action in my articles controller:
function incrementViewCount($id) {
$this->updateAll(
array('Article.viewed' => 'Article.viewed+1'),
array('Article.id' => $id)
);
}
Then in your controller…
$this->MyModel->incrementViewCount(123);
Basically similar to the tutorial suggested in the previous answer.
you can use updateAll() for this
a little googling reveals this pretty quick:
http://cakephp.1045679.n5.nabble.com/Auto-Increment-A-Field-td3491697.html
You can try this code also. Works fine for simple ++/-- operations without the need of additional querying.
https://gist.github.com/denchev/8209318
Using saveField:
<?php
$this->Article->id = $id;
$this->Article->saveField('viewed', (int)$this->Article->field('viewed') + 1);
?>

Resources