Cakephp Pagination in DropDown? - cakephp

I'm looking for a way, to handle the Pagination-options in a dropdown menu.
I'd like my users to select the sorting order in the same form with my filtering options, so when they hit "Send", pagination-order is already set.orm
e.g. like:
$this->Form->input('paginationorder',array(
'label' => 'order',
'options' => array(
'sort:id/direction:desc' => 'New Items, desc',
'sort:id/direction:asc' => 'New Items,asc',
),
'div' => false
)
);

$(function() {
$('#sort-properties').change(function() { // replace the ID_OF_YOUR_SELECT_BOX with the id to your select box given by Cake
var price = $(this).val();
window.location = baseUrl + 'properties/property_view/'+price;
});
});
<?php
echo $this->Form->input('orderby', array(
'id' => 'sort-properties',
'options' => array(
'sort:sale_rent_price/direction:asc' => 'Sort by Price Low to High',
'sort:sale_rent_price/direction:desc' => 'Sort by Price High to Low',
'sort:created/direction:asc' => 'Sort by Date Old to New',
'sort:created/direction:desc' => 'Sort by Date New to Old'
),
'label' => false,
'empty' => 'Default Order'
));
?>

I would change the values of the options to e.g. fieldname.desc, like :
$this->Form->input('paginationorder',array(
'label' => 'order',
'options' => array(
'id.desc' => 'New Items, desc',
'id.asc' => 'New Items,asc',
),
'div' => false
)
);
Afterwards in the controller put the values to an array via the explode method:
$order = explode(".", $this->request->data['Model']['field']);
then you can use the values in your find condition, like:
$result = $this->Model->find('all', array(
'order' => array( $order[0] => $order[1] )
));
There is propably a more elegant way to make this, but this should work.

Related

Cakephp 2 use the id of the record as index when retrieving data

Is it possible to retrieve records where the index is the record id?
I have a model with a hasMany Relation. So my study can have multiple texts and questions etc.
The custom retrieve function looks like this:
protected function _findStudyWithSequence($state, $query, $results=array()){
if ($state === 'before') {
$query['contain'] = array(
'SubjectFilter'=>array('fields'=>'SubjectFilter.studyCode'),
'Text'=>array('fields'=>'Text.position,Text.id,Text.text','order'=>array('position')),
'Image'=>array('fields'=>'Image.position, Image.id','order'=>array('position')),
'Video'=>array('fields'=>'Video.position, Video.id','order'=>array('position')),
'Web'=>array('fields'=>'Web.position, Web.id','order'=>array('position')),
'Likert'=>array('fields'=>'Likert.position, Likert.id','order'=>array('position')),
'Question'=>array('fields'=>'Question.position, Question.id','order'=>array('position')),
'Star'=>array('fields'=>'Star.position, Star.id','order'=>array('position')),
'Multiple_choice'=>array('fields'=>'Multiple_choice.position, Multiple_choice.id','order'=>array('position'))
);
$query['recursive']=-1;
$query['order']=array('Study.started DESC');
$query['fields']=array(
'Study.id', 'Study.user_id','Study.title','Study.description','Study.numberParticipants','Study.state','Study.created','Study.modified','Study.started','Study.completed','Study.numberParticipants');
return $query;
}
}
return $results;
}
As you can see I am using containable
The results look like this:
array(
'Study' => array(
'id' => '1845346986',
'user_id' => '1402402538',
'title' => 'bla bla',
'description' => '',
'numberParticipants' => '10',
'state' => 'active',
'created' => '2017-08-21 14:06:11',
'modified' => '2017-08-21 14:29:56',
'started' => '2017-08-21 14:30:06',
'completed' => '0000-00-00 00:00:00',
),
'SubjectFilter' => array(
'studyCode' => null
),
'Text' => array(
(int) 0 => array(
'position' => '0',
'id' => '1423909242',
'text' => '<p>Bla <b>bla </b></p><p>blub</p><p><br /></p>',
'study_id' => '1845346986'
)
),
'Question' => array(
(int) 0 => array(
'position' => '4',
'id' => '729521908',
'study_id' => '1845346986'
)
), etc
But I want the Text and Question index to be the ids. Like this:
'Text' => array(
(int) 1423909242 => array(
'position' => '0',
'id' => '1423909242',
'text' => '<p>Bla <b>bla </b></p><p>blub</p><p><br /></p>',
'study_id' => '1845346986'
)
),
How can i manage this?
You can use CakePHP's amazing Hash::combine() method.
Something like:
$results['Text'] = Hash::combine($results['Text'], '{n}.id', '{n}');
$results['Question'] = Hash::combine($results['Question'], '{n}.id', '{n}');
return $results;
It's not tested code, but I believe it's correct (or at least close), and you should get the idea from here.
Notes on Hash::combine:
Creates an associative array using a $keyPath as the path to build its
keys, and optionally $valuePath as path to get the values. If
$valuePath is not specified, or doesn’t match anything, values will be
initialized to null. You can optionally group the values by what is
obtained when following the path specified in $groupPath.
Hash::combine(array $data, $keyPath, $valuePath = null, $groupPath =
null)

Using "Advanced Custom Fields" checkbox fields in custom queries

I’m trying to write a WP_Query which uses some data from two ACF checkboxes as part of the arguments.
I found the documentation showing how to use fields in custom queries however I cannot work out what the correct syntax for my checkboxes is.
My ACF’s:
Label: Promote to homepage?
Name: promote_to_homepage
Choices: Promoteto homepage : Promote to homepage
Label: Make feature?
Name: make_feature
Choices: Show as feature : Show as feature (top of homepage)
This is the query I have:
$the_query = new WP_Query(
array
(
'posts_per_page' => 1,
'meta_key' => 'promote_to_homepage',
'meta_value' => 'Promote to homepage',
'meta_key' => 'make_feature',
'meta_value' => 'Make feature'
)
);
I guess what I can’t figure out is why data is actually needed for meta_key and meta_value. Is the key the label? Is the value one of the choices? Or do I need to use meta_value => true or something? I have tried many variations and cannot get it to work.
Essentially what I want to do is output the most recent post that is checked for “Promote to homepage” and “Make feature”.
I have also tried:
array
(
'posts_per_page' => 1,
'meta_key' => 'promote_to_homepage',
'meta_value' => true,
'meta_key' => 'make_feature',
'meta_value' => true
)
Edit
This is the new code I have tried:
$args = array(
'post_type' => 'post',
'posts_per_page' => 1,
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'promote_to_homepage',
'value' => true,
),
array(
'key' => 'make_feature',
'value' => true,
),
)
);
$the_query = new WP_Query($args);
if ( $the_query->have_posts() ) {
while ( $the_query->have_posts() ) {
$the_query->the_post();
echo '<h2>' . get_the_title() . '</h2>';
echo '<p>' . get_the_excerpt() . '</p>';
echo '<p>Read more</p>';
}
}
wp_reset_postdata();
Another option is to get a lot of posts like this:
$args = array(
'post_type' => 'posts',
);
$posts = get_posts($args);
foreach($posts as $item) :
$make_feature = get_post_meta($item->ID, 'make_feature', true );
var_dump($make_feature); //test
$promote_to_homepage = get_post_meta($item->ID, 'promote_to_homepage', true );
var_dimp($promote_to_homepage); //test
if(isset($make_feature) && isset($promote_to_homepage)):
print_r($item);
endif;
endforeach;
Check if this works first before limiting posts. If you don't get any results from var_dump variables, there's something up with ACF.
$args = array(
'post_type' => 'post', //replace 'post' with cpt if you need to.
'posts_per_page' => 1,
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'promote_to_homepage',
'value' => '1',
'compare' => '=='
),
array(
'key' => 'make_feature',
'value' => '1',
'compare' => '=='
),
)
);
$the_query = new WP_Query($args); // This will return posts and other data
$the_query = get_posts( $args ); // This will return the posts
How's that for ya? Choose WP_Query OR get_posts: get_posts will return the posts data from wp_query anyway so you may as well just use that.
I'm not entirely sure what you mean by 'true/yes' but you can play around with the values. If the key value in the custom field is literally 'true/yes' then you better have that as the value in the args - otherwise yes or true will do.

Can't get formhelper to pre-populate multiple records

I have a model called Category which hasMany Expense. I am trying to generate an accordion type interface where a user can expand a category and edit the expenses. I can generate the input fields but they don't seem to be in "edit" mode because they are not pre-populated.
I've searched online and found a few related articles such as this one CakePHP: How to update multiple records at the same time with the Form helper and also this one CakePHP: Form helper with saveMany() to edit multiple rows at once. I have tried to emulate their code but with no success.
My CategoriesController Index function looks like this ...
public function index($project_id) {
$data = $this->Category->find('all', array(
'conditions'=>array('Category.project_id' => $project_id),
'order'=>array('Category.category_name')
));
$this->set('categories', $data);
$this->request->data = $data;
}
I have read that cakephp2 requires $this->request->data to be set for FormHelper to work. But in the examples I have found online everyone seems to use the plural of the model name so I tried that as well.
My Categories\index.ctp looks like this. I'm not at the "accordion" stage yet. I'm just trying to get input boxes on the screen that are pre-populated.
$i=0;
foreach ($categories as $category)
{
echo $this->Form->input("Category.$i.category_id");
echo $this->Form->input("Category.$i.category_name");
$j=0;
foreach($category['Expense'] as $expense)
{
echo $this->Form->input('Expense.' . $j . '.expense_id');
echo $this->Form->input('Expense.' . $j . '.expense_name');
echo $this->Form->input('Expense.' . $j . '.dollar_amount');
echo $this->Form->input('Expense.' . $j . '.sqft_amount');
$j++;
}
$i++;
}
This code seems to be iterating properly because it spits out the correct input fields. The big problem right now is just getting the fields to pre-populate. It doesn't seem to be in "edit" mode and I'm worried that that will be a problem down the road when I try to save the data.
Also, I have tried it with and without $this->form->create('Category') at the top. It doesn't seem to make a difference.
The $categories array looks like this ...
array(
(int) 0 => array(
'Category' => array(
'category_id' => '1',
'category_name' => 'Category 1',
'category_index' => '1',
'project_id' => '1'
),
'Project' => array(
'project_id' => '1',
'project_name' => '131 Anndale Dr',
'project_sqft' => '1700',
'project_cost' => '318',
'project_cost_per_sqft' => '0'
),
'Expense' => array(
(int) 0 => array(
'expense_id' => '2',
'expense_name' => 'Nails',
'category_id' => '1',
'dollar_amount' => '50',
'sqft_amount' => '1',
'expense_index' => '2'
),
(int) 1 => array(
'expense_id' => '1',
'expense_name' => 'Wood',
'category_id' => '1',
'dollar_amount' => '99',
'sqft_amount' => '1',
'expense_index' => '1'
)
)
),
(int) 1 => array(
'Category' => array(
'category_id' => '3',
'category_name' => 'Category 2',
'category_index' => '2',
'project_id' => '1'
),
'Project' => array(
'project_id' => '1',
'project_name' => '131 Anndale Dr',
'project_sqft' => '1700',
'project_cost' => '318',
'project_cost_per_sqft' => '0'
),
'Expense' => array(
(int) 0 => array(
'expense_id' => '3',
'expense_name' => 'Bed',
'category_id' => '3',
'dollar_amount' => '99',
'sqft_amount' => '2',
'expense_index' => '1'
),
(int) 1 => array(
'expense_id' => '4',
'expense_name' => 'Chair',
'category_id' => '3',
'dollar_amount' => '70',
'sqft_amount' => '1',
'expense_index' => '2'
)
)
)
)
Any help would be greatly appreciated. Thanks!!
Coincidentally, I've been doing almost exactly the same thing today.
In order to automatically populate the form, you need to have your data in $this->data in the view. You can do this by assigning to $this->request->data in your controller.
Then you need to have your field names reflect the structure of that array exactly. So using your example, you might have:
echo $this->Form->input("$i.Category.category_name");
for the category fields, and
echo $this->Form->input("$i.Expense.$j.expense_id");
for your expense fields.

Joining two tables in CakePHP using bindModel method Cakephp

I am working on a cakephp 2.x .. I have two tables in my database both have the userid I am using bindModel.. my query is working fine ... I just have one problem .. I want to add the condition in where clause that
**where userid = $userid**
function getMessages($userid){
$this->bindModel(array(
'belongsTo' => array(
'Contact' => array(
'className' => 'Contact',
'foreignKey' => false,
'conditions' => array(
'Message.user_id = Contact.user_id',
'AND' =>
array(
array('OR' => array(
array('Message.mobileNo = Contact.mobileNo'),
array('Message.mobileNo = Contact.workNo'),
)),
)
),
'type' => 'LEFT',
)
)
), false);
return $this->find('all', array('conditions' => array(),
'fields' => array('Message.mobileNo'
),
'group' => 'Message.mobileNo',
'limit' => 6));
}
I am getting user id in parameter ... so I want to add the condition that get the following result where
message.userid and contact.userid = $userid ...
Just split the conditions in two lines like:
'conditions' => array(
'Contact.user_id' => $userid,
'Message.user_id = Contact.user_id',
[...]
)
But the approach that makes more sense is to leave the bind as is - after all the bind is generally between message users and contact users with the same id - and add the condition for the specific case in your find('all') with 'Message.user_id' => $userid.

How to set selection in mulitiselect list box in cakephp

I want to set the multi selection to my multi list box.
I have two results in my view page.
$inr1 = 0;
$arr1 = array();
$str_arr = '';
foreach ($result as $rows){
$inr1 = $rows['Employees']['employee_id'];
$arr1[$inr1] = $rows['Employees']['first_name'].' '.$rows['Employees']['last_name'];
$str_arr = $str_arr.$inr1.',';
}
$str_arr = substr($str_arr,0,-1);
//print_r($arr1);
$inr = 0;
$arr = array();
foreach ($options as $option){
$inr = $option['Employee']['employee_id'];
$arr[$inr] = $option['Employee']['first_name'].' '.$option['Employee']['last_name'];
}
//print_r($arr);
echo $this->Form->input('emp_id_one', array( 'options' => array( $arr),
'empty' => '(choose one)',
'div'=>'formfield',
'error' => array( 'wrap' => 'div',
'class' => 'formerror'
),
'label' => 'Team Members',
'type' => 'select', 'multiple' => true,
'selected' => $arr1,
'style' => 'width:210px; height:125px;',
));
But the values in $arr1 not selected in the list box.
The $arr1 have the selected values.
The $arr have the options to the list.
The problem is that the selction is not working..There have no selection...
How can i do this?
If there is any problem in my code..?
Finally i solved my problem by chaing some code:
Add the one line of code after this $str_arr = substr($str_arr,0,-1);'.
That is....
$str_arr = substr($str_arr,0,-1);
$sel = explode(',',$str_arr);
Then change the name of variable as like this :
echo $this->Form->input('emp_id_one', array( 'options' => array( $arr),
'empty' => '(choose one)',
'div'=>'formfield',
'error' => array( 'wrap' => 'div',
'class' => 'formerror'
),
'label' => 'Team Members',
'type' => 'select', 'multiple' => true,
'selected' => $sel,
'style' => 'width:210px; height:125px;',
));
Now the values in $sel is selected in the multi list

Resources