CakePHP remove empty relations - cakephp

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.

Related

Cakephp : Sort by a displayed value

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.

Settings page and multi edit rows

I would like to make a configuration page like this for my CMS
http://img4.hostingpics.net/pics/72087272ok.png
I want this page (admin/settings/index) gets me the various settings (ID 1 to 21) came to my table and in case of change, I can, in this form, do an update
After 3 days of not especially fruitful research I found something. I put in my SettingsController:
admin_index public function () {
if (!empty($this->data)) {
$this->Setting->saveAll($this->request->data['Setting']);
} else {
$this->request->data['Setting'] = Set::combine($this->Setting->find('all'),
'{n}. Setting.id', '{n}. Setting');
}
}
and my view:
<?php
echo $this->Form->create('Setting', array ('class' => 'form-horizontal'));
foreach($this->request->data['Setting'] as $key => $value) {
echo $this->Form->input('Setting.' . $key . '.pair');
echo $this->Form->input('Setting.' . $key . '.id');
}
echo $this->Form->end(array('class' => 'btn btn-primary', 'label' => 'Save',
'value' => 'Update!', 'div' => array ('class' => 'form-actions')));
?>
he is recovering well all my information, I can even update. The trouble is that I do not really know how I can do to get the same result as my first screenshot. He puts everything in the textarea while in some cases I want the checkbox and / or drop-down.
please help me or explain to me how to make a page that retrieves configuration information from my table and allows me to edit without use an address like admin/settings/edit/ID
My table settings is something like this here
http://img4.hostingpics.net/pics/724403settings.png
If you are asking about how to format the output to produce a "settings" page, you will need to do it manually or add some kind of metadata to your table schema, such as "field_type".
Now Cake will automatically generate a checkbox for a boolean or tiny int, for example, but as you have varchars, ints, texts and so on, this won't work for you (pair is presumably varchar or text to allow for the different possible values.
You cannot really automagically generate the outputs you want without telling Cake.
One option would be to add a field_type to the table, so:
key value field
site_name My Site input
site_online 1 checkbox
meta_desc [some text] textarea
and something like
foreach($settings as $setting) {
echo $this->Form->{$setting['field']}($setting['key'],
array('value' => $setting['value']));
}
might do what you are after.
Or if($key=='site_name') // output a textbox
but this is not exactly ideal.

blackhole cakephp 2 associated entities

My Goal:
Reuse of a contact form to be related to several different entities I call "Parents" ie Group has contact information, Member has contact info etc....
The way I tried doing it was:
1. Creating a view file for contact, named "form.ctp" which doesn`t create a new form, nor submits, just echo's the contact's fields.
2. Calling this file using requestAction
My Problem:
The form's _Token get crumbled.
Parent add.ctp example
<?php echo $this->Form->create('Group');?>
<fieldset>
echo $this->Form->input($field_prefix.'contact_id',array('type'=>'hidden'));
<?php echo $this->requestAction(array('controller' => 'contacts', 'action' => 'form'), array('named' => array('index'=>'0','parent'=>'Group',
'fields'=>array(
'email'=>array('value'=>'xx#yy.com','hidden'=>1)
))));
inside the form.ctp I have:
//Associated Model
echo $this->Form->input('Contact.0.city',array('type'=>'hidden'));
echo $this->Form->input('Contact.0.postcode');
echo $this->Form->input('Contact.0.phone');
echo $this->Form->input('Contact.0.cellphone');
echo $this->Form->input('Contact.0.email',array('value'=>""));
echo $this->Form->input('Contact.0.id',array('type'=>'hidden'));
?>
Looking at the HTML source code that is generated, I see that whether I use the request action or just copy the contect of the form.ctp into the "Parent's" add file, I get the same HTML result.
HOWEVER!!! when I use the form.ctp Action Request, I get the blackhole, the tokens are being messed up!!!
Any Ideas?
Thanks in advance
Orly
If your problem is solely reusing a form, you can use the form as a Element, and then you could call it multiple times, substituting in the exact values you need.
As for SecurityComponent, I would recommend (at least as a temporary fix) disabling SecurityComponent for that specific action by using $this->Security->unlockedActions(); in your controller's beforeFilter()

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']));

Cakephp: Designpattern for creation of models in hasMany relationship

I have two Models: Car and Passenger.
Car hasMany Passenger
Passenger belongsTo Car
I managed to create add functionality for each model and managed to resolve the hasMany relationship between them.
Now I'm trying to create a addCar function and view that allows the user to create a new car and automatically generate Passengers.
I thought of something like this
The view asks the user enter the car information
The view has some field that allows to temporarily add new passengers and remove remove them
When the user saves the new car, the entities for the passengers are created, the entity for the car is created and the passengers are linked to the car.
If the user decides to cancel everything, the DB remains unchanged.
Now my question is: What is the best way to do this? Is there a pattern / tutorial to follow for such a entity and associated subentity creation?
To clarify: The passengers associated with each car do not exist prior to the existence of the car.
Use the following code in the view views/passengers/add_cars.ctp:
<?php
echo $this->Form->create('Car');
echo $this->Form->input('name');
echo $this->Form->input('model');
echo $this->Form->input('Passenger.0.name');
echo $this->Form->input('Passenger.0.age');
echo $this->Form->input('Passenger.1.name');
echo $this->Form->input('Passenger.1.age');
echo $this->Form->end();
?>
This basically starts off with the necessary fields to input the car information. Then, you can start a loop with a general format of Passenger.{$i}.name to add passengers dynamically when a new car is added. You can use jQuery to create "add" and "remove" buttons that will add or remove rows of Passenger form entries.
In your passengers_controller.php (assuming this is the controller you want add_cars), use the saveAll function:
function add_cars() {
if (!empty($this->data)) {
if ($this->Passenger->Car->saveAll($this->data)) {
$this->Session->setFlash('Success');
$this->redirect('/');
} else {
$this->Session->setFlash('Error');
}
}
}
Hope that helps.

Resources