Cakephp : Sort by a displayed value - cakephp-2.0

I have a table in my view in which one of the columns is returned by a Helper.
How can I sort by this column?
Thanks
Edit
Controller
$this->set('myArray', $this->paginate('MyModel'));
View
foreach($myArray as $line) {
echo $line['MyModel']['col1'];
echo $line['MyModel']['col2'];
echo $line['MyModel']['col3'];
echo $line['MyModel']['col4'];
echo $this->MyModel->someHelper($line['MyModel']['id']);
}
I want to sort the table by the $this->MyModel->someHelper($line['MyModel']['id']);

If your data comes via pagination, use.
echo $this->Paginator->sort('you_field_name');
in your table head.

Related

Associations in CakePHP

I have 2 db tables : Users & Projects.
Fields of Users table are :
id, name, username, password, email, address, phone.
Fields of Projects table are :
id, name, description, user_id, deadline, budget.
What I need is that, I'll have 1 form, where there will be all fields from these 2 tables. And, when I submit the form, these fields will be saved in these 2 tables.
For example, my form will be like this :
<?php
echo $this->Form->create('User');
echo $this->Form->input('name',array('type'=>'text','div'=>false));
echo $this->Form->input('username',array('type'=>'text','div'=>false));
echo $this->Form->input('password',array('type'=>'password','div'=>'false));
echo $this->Form->input('email',array('type'=>'email','div'=>false));
echo $this->Form->input('address',array('type'=>'textarea','div'=>false));
echo $this->Form->input('phone',array('type'=>'tel','div'=>false));
echo $this->Form->input('name',array('type'=>'text','div'=>false));
echo $this->Form->input('description',array('type'=>'text','div'=>false));
echo $this->Form->input('deadline',array('type'=>'date','div'=>false));
echo $this->Form->input('budget',array('type'=>'num','div'=>false));
echo $this->Form->submit('Save');
echo $this->Form->end();
?>
Now, I want that when I submit the form, the fields will be saved in the corresponding tables; Users table will receive & save its fields, and Projects table will receive & save its fields.
For this, I tried hasMany association between Users & Projects tables, means, each user from Users table will have many projects from Projects table.
In User.php, I tried this :
class User extends AppModel{
public $hasMany=array(
'Project'=>array(
'className'=>'Project')
);
}
I thought it'd work, but it didn't, only Users table get its values, no value goes to Project table. What is the problem here ? What should I do ?
Thanks.
try this in your view
echo $this->Form->create('User');
echo $this->Form->input('name',array('type'=>'text','div'=>false));
echo $this->Form->input('username',array('type'=>'text','div'=>false));
echo $this->Form->input('password',array('type'=>'password','div'=>false));
echo $this->Form->input('email',array('type'=>'email','div'=>false));
echo $this->Form->input('address',array('type'=>'textarea','div'=>false));
echo $this->Form->input('phone',array('type'=>'tel','div'=>false));
echo $this->Form->input('Project.0.name',array('type'=>'text','div'=>false));
echo $this->Form->input('Project.0.description',array('type'=>'text','div'=>false));
echo $this->Form->input('Project.0.deadline',array('type'=>'date','div'=>false));
echo $this->Form->input('Project.0.budget',array('type'=>'num','div'=>false));
echo $this->Form->submit('Save');
echo $this->Form->end();
And in your controller you have to use
$this->User->saveAssociated($data);
see the manual about how to save associated data
At first, add the model names User and Project as prefix to your form fields to separate them:
View:
<?php
echo $this->Form->create('User');
echo $this->Form->input('User.name',array('type'=>'text','div'=>false));
echo $this->Form->input('User.username',array('type'=>'text','div'=>false));
echo $this->Form->input('User.password',array('type'=>'password','div'=>false));
echo $this->Form->input('User.email',array('type'=>'email','div'=>false));
echo $this->Form->input('User.address',array('type'=>'textarea','div'=>false));
echo $this->Form->input('User.phone',array('type'=>'tel','div'=>false));
echo $this->Form->input('Project.name',array('type'=>'text','div'=>false));
echo $this->Form->input('Project.description',array('type'=>'text','div'=>false));
echo $this->Form->input('Project.deadline',array('type'=>'date','div'=>false));
echo $this->Form->input('Project.budget',array('type'=>'num','div'=>false));
echo $this->Form->submit('Save');
echo $this->Form->end();
At second, use the separation to save your data into different models. Do not forget to add an associated column user_id to your table projects.
Controller
class UserController extends AppController
{
function create()
{
$this->loadModel('Project');
if($this->request->is('post', 'put'))
{
$this->User->getDataSource()->begin($this); // Starts transaction
if($this->User->save($this->request->data['User']))
{
// Success, save project now
$this->request->data['Project']['user_id'] = $this->User->getLastInsertId();
if($this->Project->save($this->request->data['Project']))
{
$this->User->getDataSource()->commit($this); // Commit
// success
} else {
$this->User->getDataSource()->rollback($this); // Rollback
}
} else {
$this->User->getDataSource()->rollback($this); // Rollback
}
}
}
}
I tested this code → works.
Your question is not very clear to me but what I see is you need to save data using associations.
But an association is a connection between two Active Record models. Associations are created to maintain Primary Key-Foreign Key information between instances of the two models.
You will need to save your USERS table data first and get the primary ID of last saved and use it as user_id for PROJECTS table and save PROJECT table information creating a PROJECT instance.
view:
<?php
echo $this->Form->create('User');
echo $this->Form->input('name',array('type'=>'text','div'=>false));
echo $this->Form->input('username',array('type'=>'text','div'=>false));
echo $this->Form->input('password',array('type'=>'password','div'=>'false));
echo $this->Form->input('email',array('type'=>'email','div'=>false));
echo $this->Form->input('address',array('type'=>'textarea','div'=>false));
echo $this->Form->input('phone',array('type'=>'tel','div'=>false));
// adding associate model name to every field..
echo $this->Form->input('Project.name',array('type'=>'text','div'=>false));
echo $this->Form->input('Project.description',array('type'=>'text','div'=>false));
echo $this->Form->input('Project.deadline',array('type'=>'date','div'=>false));
echo $this->Form->input('Project.budget',array('type'=>'num','div'=>false));
echo $this->Form->submit('Save');
echo $this->Form->end();
Note: You can disable all 'div' on form creation.. Look documentation for details...
User model:
class User extends AppModel{
public $hasMany=array('Project');
}
UsersController:
public function add(){
if($this->request->is('post')){
$this->User->create();
if($this->User->save($this->request->data)){// if you association is correct, all associated data will save automatically.
$this->Session->setFlash('saved');
$this->redirect('where you wants to redirect');
}else{
$this->Session->setFlash('Something went wrong. Try again');
}
}
}
Easy way with saveAll
<!-- View -->
<?php
echo $this->Form->create('User');
echo $this->Form->input('name',array('type'=>'text','div'=>false));
echo $this->Form->input('username',array('type'=>'text','div'=>false));
echo $this->Form->input('password',array('type'=>'password','div'=>false));
echo $this->Form->input('email',array('type'=>'email','div'=>false));
echo $this->Form->input('address',array('type'=>'textarea','div'=>false));
echo $this->Form->input('phone',array('type'=>'tel','div'=>false));
echo $this->Form->input('Project.0.name',array('type'=>'text','div'=>false));
echo $this->Form->input('Project.0.description',array('type'=>'text','div'=>false));
echo $this->Form->input('Project.0.deadline',array('type'=>'date','div'=>false));
echo $this->Form->input('Project.0.budget',array('type'=>'num','div'=>false));
echo $this->Form->submit('Save');
echo $this->Form->end();
?>
<!-- Controller -->
<?php
class UserController extends AppController
{
function create()
{
if($this->request->is('post', 'put'))
{
if($this->User->saveAll($this->request->data))
{
// Success - set your flashMessage
} else {
// Error - set your flashMessage
}
}
}
}
?>

Multiple values in cakephp session

I would like to store multiple values in cakephp session where some value come through database and some from manually
I have created a session in controller which is like this.
$this->Session->write('Cart.'.$count,$this->Product->findById($id[0], array('id','category','name','price'))); //controller
And I have wrote this code in view page
foreach( $this -> Session -> read(Cart) as $value)
{
echo $value['Product']['id'];
echo $value['Product']['category'];
echo $value['Product']['name'];
echo $value['Product']['price'];
}
by using this line i can print all information id,category,name,price which is stored from database in session
but i want to add one more variable which is $quantity and it will manually not coming from database so how can i add this field in session and how can i print this.
Thanks in advance
When you write session do somthing like given below:
$sessionInfo = $this->Product->findById($id[0], array('id','category','name','price'));
foreach($sessionInfo as $key=>$value){
$sessionInfo[$key]['Product']['quantity'] = $count;
}
$this->Session->write('Cart',$sessionInfo); //controller
View session data:
foreach( $this->Session->read('Cart') as $value)
{
echo $value['Product']['id'];
echo $value['Product']['category'];
echo $value['Product']['name'];
echo $value['Product']['price'];
echo $value['Product']['quantity'];
}

CakePHP remove empty relations

I have relation Holiday hasMany Place (Place belongsTo Holiday).
I prepare some form in Holiday view:
echo $this->Form->input('name');
echo $this->Form->input('Place.0.name');
echo $this->Form->input('Place.1.name');
echo $this->Form->input('Place.2.name');
Now, when I add Holiday with 2 places, I can't save because the one is empty.
How remove empty record in model?
Loop through them, if it's empty, unset it.
foreach ($data['Place'] as $key => $place) {
if (empty($place['name'])) {
unset($data['Place'][$key]);
}
}
Not sure about the paths, just update them accordingly to what your post data looks like.

Edit multiple rows with one form in cake

In my cake app I have a model called faqs, controller called faqs_controller & view called faqsindex.php.
I'm making a CMS so users can change the FAQs. The db table 'faqs' has 5 columns id, category, question, answer and number. "Number" is the order in which the FAQ's will appear.
The loop that lists all of the FAQs looks more or less like this:
<?php
foreach ($faqs as $faq):
<tr>
<td><?php echo $faq['Faq']['category']; ?></td>
<td><?php echo $faq['Faq']['number']; ?></td>
<td><?php echo $faq['Faq']['question']; ?></td>
<td><?php echo $faq['Faq']['answer']; ?></td>
</tr>
<?php endforeach; ?>
I want to make it so that the user can change the "number" cell from this screen, instead of going into a separate edit screen for each row and changing the number there.
You know, like how netflix's queue works, where the user can reorder it from the list, you don't have to click on the movie you want to see to change its order in your queue.
EDIT I set up edit in faqs_controller.php like this:
function edit() {
if(!empty($this->data)) {
$this->Faq->saveAll($this->data['Faq']);
}
else {
$this->data['Faq'] = Set::combine($this->Faq->find('all'), '{n}.Faq.id', '{n}.Faq');
}
}
and in the index view I made a foreach that looks like this:
echo $form->create('Faq', array('action'=>'edit'));
foreach($this->viewVars['faqs'] as $key => $value) {
echo 'id:'.$value['Faq']['id'];
echo '<br/>question:'.$value['Faq']['question'];
echo $form->input('Faq.'.$key.'.number');
}
In this case the foreach goes round 8 times because there are 8 rows. If I submit them, I create 8 new rows & can't update existing rows.
-EDIT-
I changed the form echo here:
echo $form->input('Faq.'.$key.'.question',array('value'=>$value['Faq']['question']));
to prepopulate the form. What I can't figure out is how to update the proper row. If I submit the form I get 8 mysql queries like this:
INSERT INTO faqs (question) VALUES ('THE NEW QUESTION I JUST ADDED?') when I don't want an insert but an update.
Put each faq id inside your form?
echo $form->create('Faq', array('action'=>'edit'));
foreach($this->viewVars['faqs'] as $key => $value) {
echo 'id:'.$value['Faq']['id'];
echo '<br/>question:'.$value['Faq']['question'];
echo $form->hidden('Faq.'.$key.'.id', array('value' => $value['Faq']['id']));
echo $form->input('Faq.'.$key.'.number');
}
if you are using jquery: http://jqueryui.com/demos/sortable/ All the ordering is done on client side, you put the order value into hidden input and use javascript to change them according to user interaction. There's nothing to change on the server side script.
Edit:
echo $form->create('Faq', array('action'=>'edit'));
foreach($this->data['Faq'] as $key => $value) {
echo 'id:'.$value['Faq']['id'];
echo '<br/>question:'.$value['Faq']['question'];
echo $form->input('Faq.'.$key.'.number');
echo $form->input('Faq.'.$key.'.id');
}
echo $form->end('Save');
and the controller:
function edit() {
if(!empty($this->data)) {
$this->Faq->saveAll($this->data['Faq']);
}
$this->data['Faq'] = Set::combine($this->Faq->find('all'), '{n}.Faq.id', '{n}.Faq');
}
unless you redirect them somewhere else after saving.
If you're wanting to update a specific row with Cake it is as simple as setting the appropriate row ID in your saveAll() query.
function edit() {
if (!empty($this->data)) {
$this->Faq->saveAll($this->data['Faq'], array('conditions' => array('Faq.id' => $yourId)));
}
...
}
This is telling Cake's ORM to save the information into the row only where Faq.id is equal to $yourId. If $yourId matches an existing ID in your table then that row should be updated.
Edit
You can put the id field into a hidden form element using CakePHP's FormHelper.
$this->Form->hidden('id', array('value' => $value['Faq']['id']));

How to save multiple individual records for a single model

I have a model(friends), where user can export his friend's info from facebook. I want save friends info(id and name) into the mysql database.
I am having trouble creating a form for the same using form helper as i don't know the exact number of friends for each user.
Is there a easier way to save user's friends into the database? (save multiple records for the same model)
Basically you should know how much is the number of friends for the current user, right?
If so, do a loop with following in your view:
echo $this->Form->create('User');
for($i=0;$i<$number_of_current_user_friends;$i++){
echo $this->Form->input('Friend.'.$i.'user_id', array('value'=>$current_user_id));
echo $this->Form->input('Friend.'.$i.'friend_name', array('value'=>$friends[$i]['name']));
echo $this->Form->input('Friend.'.$i.'fb_id', array('value'=>$friends[$i]['fb_id']));
}
echo $this->Form->end('Submit');
then in the controller save it with:
$this->Friend->saveAll($this->data);

Resources