I have an Up which has to do a lot with pictures. I have a problem. I know might seems stupid, and even i know that im missing something, but i havent found out yet. So in few words. Let's say I have an Item. |id|name|price|condition|location|picture|
picture is the picture path that i save to DB. So when i create a new Item all the field are required. Till here everything works Fine.Now lets say i open Item x to edit. I edit only the name and the price and other i leave them as they are, and i press save, browse button, of the picture field is still required and i have to open galerry find the pic again in order to save. So my question is this: How can i do a picture upload only if i browse for the picture, but not to forget that on creation must not be empty. To Ilustrate it here is some code:
<?php
App::uses('AppModel', 'Model');
class Item extends AppModel {
public $name = 'Item';
public $primaryKey = 'id';
public $displayField = 'title';
public $validate = array(
'id' => array(
'blank' => array(
'rule' => 'blank',
'on' => 'create',
),
),
'title' => array(
'words' => array(
'rule' => array('custom', '/[0-9A-Za-z\._-]/'),
'message' => 'The Item name can only contain letters, numbers and spaces.',
),
'maxLength' => array(
'rule' => array('maxLength', 100),
'message' => 'The Item name must not be longer than 100 characters.',
),
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => 'The Item name must not be empty.',
),
'isUnique' => array(
'rule' => 'isUnique',
'message' => 'This Item name already exists.',
),
),
'picture' => array(
'uploadError' => array(
'rule'=>'uploadError',
'message' => 'The File Did NOT Upload. Please Try Again!',
),
'fileSize'=>array(
'rule'=>array('fileSize','<=','30MB'),
'message'=>'File Size should be less then 30MB',
),
'processMediaUpload'=>array(
'rule' =>'processMediaUpload',
'message'=>'Uploading File Failed!',
),
),
'item_location_id' => array(
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => 'You Must Choose a Location',
),
'numeric' => array(
'rule' => array('numeric'),
//'message' => 'Your custom message here',
),
),
'address' => array(
'words' => array(
'rule' => array('custom', '/[0-9A-Za-z\._-]/'),
'message' => 'The Item Address can only contain letters, numbers and spaces.',
),
'maxLength' => array(
'rule' => array('maxLength', 150),
'message' => 'Address can not be longer then 150 characters long',
),
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => 'You Should Put an Address',
),
),
);
public $belongsTo = array(
'ItemLocation' => array(
'className' => 'ItemLocation',
'foreignKey' => 'item_location_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
);
public function processMediaUpload($mediacheck = array()) {
$dir = 'img/uploads/item/media/';
if (isset($mediacheck['media_path']['name'])) {
if(is_uploaded_file($mediacheck['media_path']['tmp_name'])) {
if (trim($mediacheck['media_path']['name'])!=""){
// here we delete if the image exist and replace it.
if (file_exists(WWW_ROOT . $dir . $mediacheck['media_path']['name'])) {
unlink(WWW_ROOT . $dir . $mediacheck['media_path']['name']);
return true;
}
}
$allowedExts = array('jpeg', 'png', 'jpg', 'gif');
$extension=strtolower(end(explode(".", $mediacheck['media_path']['name'])));
if (($mediacheck['media_path']['size'] < 55000000)) {
if(in_array($extension, $allowedExts)){
if ($mediacheck['media_path']["error"] > 0) {
$this->invalidate('media_path', $mediacheck['media_path']['error']);
return false;
} else {
if (file_exists( WWW_ROOT . $dir) && is_dir( WWW_ROOT . $dir)) {
if (file_exists( WWW_ROOT . $dir . $mediacheck['media_path']['name'])) {
$this->invalidate('media_path', 'File Allredy Exists!');
return false;
} else {
move_uploaded_file($mediacheck['media_path']['tmp_name'], WWW_ROOT . $dir . mktime() . $mediacheck['media_path']['name']);
$this->data[$this->alias]['media_path'] = mktime() . $mediacheck['media_path']['name'];
return TRUE;
}
} else { // in this case the directory doesent exist so we create it
mkdir($dir, 0777, true);
move_uploaded_file($mediacheck['media_path']['tmp_name'], WWW_ROOT . $dir . mktime() . $mediacheck['media_path']['name']);
$this->data[$this->alias]['media_path'] = mktime() . $mediacheck['media_path']['name'];
return TRUE;
}
}
}else { $this->invalidate('media_path', 'Invalid File Format! '); return false;}
} else { $this->invalidate('media_path', 'File size is To big!'); return false; }
} else { $this->invalidate('media_path', 'You must upload a file before you Submit!'); return false; }
} else { $this->invalidate('media_path', 'You must upload a file before you Submit!'); return false; }
// better safe then sorry!
return false;
}
Add Form:
<div class="items form">
<?php echo $this->Form->create('Item', array('type'=>'file')); ?>
<fieldset>
<legend><?php echo __('Add New Item'); ?></legend>
<?php
echo $this->Form->input('id');
echo $this->Form->input('title');
echo $this->Form->input('item_description');
echo $this->Form->input('location_description');
echo $this->Form->input('media_path', array('label'=>'Media','type'=>'file'));
echo $this->Form->input('item_location_id', array('label'=>'Location'));
echo $this->Form->input('item_characteristic_id', array('label'=>'Characteristics'));
echo $this->Form->input('address', array('id' => 'address'));
echo "<div id=\"map_canvas\" style=\"width:98%; height:400px;\"> </div>";
echo $this->Form->input('longitude', array('id'=>'longitude', 'readonly'=>'readonly'));
echo $this->Form->input('latitude', array('id'=>'latitude', 'readonly'=>'readonly'));
echo $this->Form->input('first_seller_id');
echo $this->Form->input('second_seller_id');
echo $this->Form->input('brochure_path', array('label'=>'Broshure','type'=>'file'));
echo $this->Form->input('seo_title');
echo $this->Form->input('seo_description' , array('label' => 'SEO Description'));
echo $this->Form->input('seo_url' , array('label' => 'SEO Url'));
echo $this->Form->input('seo_keywords' , array('label' => 'SEO Keywords'));
?>
</fieldset>
Edit Form:
<div class="items form">
<?php echo $this->Form->create('Item', array('type'=>'file')); ?>
<fieldset>
<legend><?php echo __('Edit Item'); ?></legend>
<?php
$dir = "/img/uploads/item/media/";
echo $this->Form->input('id');
echo $this->Form->input('title');
echo $this->Form->input('item_description');
echo $this->Form->input('location_description');
echo $this->Form->input('media_path', array('label'=>'Media','type'=>'file'));
echo $this->Form->input('hiddenimage', array('type'=>'hidden','value'=> $this->Form->value('media_path') ));
$Image = $this->Form->value( 'media_path');
if(empty($Image) || $Image==NULL)
{$Image = "/img/uploads/noimg.jpg";}
else {$Image = $dir . $Image; }
echo $this->Html->image($Image,array('align'=>'absbottom','style'=>'max-height:100px'));
echo "<h3> Test: ". $this->Form->value('media_path') . "</h3>";
echo $this->Form->input('item_location_id', array('label'=>'Location'));
echo $this->Form->input('item_characteristic_id', array('label'=>'Characteristics'));
echo $this->Form->input('address', array('id' => 'address'));
echo "<div id=\"map_canvas\" style=\"width:98%; height:400px;\"> </div>";
echo $this->Form->input('longitude', array('id'=>'longitude', 'readonly'=>'readonly'));
echo $this->Form->input('latitude', array('id'=>'latitude', 'readonly'=>'readonly'));
echo $this->Form->input('first_seller_id');
echo $this->Form->input('second_seller_id');
echo $this->Form->input('brochure_path', array('label'=>'Broshure','type'=>'file'));
echo $this->Form->input('seo_title');
echo $this->Form->input('seo_description' , array('label' => 'SEO Description'));
echo $this->Form->input('seo_url' , array('label' => 'SEO Url'));
echo $this->Form->input('seo_keywords' , array('label' => 'SEO Keywords'));
?>
</fieldset>
Look at adding the on parameter to your rules.
'on' => 'create'
Will only trigger the validation on an insert (i.e. a new record).
If a rule has defined ‘on’ => ‘create’, the rule will only be enforced
during the creation of a new record. Likewise, if it is defined as
‘on’ => ‘update’, it will only be enforced during the updating of a
record.
In your edit action could you not just check the field and remove it if it's empty? Is that what you mean? Like:
if (empty($this->request->data['Item']['media_path'])) {
unset($this->request->data['Item']['media_path']);
}
It would probably be more complicated than that, checking to see if it's valid upload I guess, but would something like that work?
Related
I'm using the cakephp uploader plugin by Miles Johnson. I like the plugin and I've got it working to be able to upload photos for a photo model.
The problem I'm running into is that when I try to edit an existing record, instead of replacing the photo associated with the record I'm editing a new record is created. The new record has all the same information with the exception of the new photo that's been uploaded.
Here's how the photo model looks:
'Uploader.Attachment' => array(
'imgPath' => array(
// 'name' => '', // Name of the function to use to format filenames
'baseDir' => '', // See UploaderComponent::$baseDir
'uploadDir' => 'files/uploads/', // See UploaderComponent::$uploadDir
'dbColumn' => 'imgPath', // The database column name to save the path to
'maxNameLength' => 60, // Max file name length
'overwrite' => false, // Overwrite file with same name if it exists
'stopSave' => true, // Stop the model save() if upload fails
'allowEmpty' => true, // Allow an empty file upload to continue
'transforms' => array( // What transformations to do on images: scale, resize, etc
array(
'method' => 'resize',
'width' => 50,
'height' => 50,
'append' => '_thumb',
'dbColumn' => 'imgPathThumb',
)
)
)
)
This is the photo admin edit view form:
<?php echo $this->Html->script('ckeditor/ckeditor');?>
<?php echo $this->Form->create('Photo', array('type' => 'file'));?>
<fieldset>
<legend><?php echo __('Admin Edit Photo'); ?></legend>
<?php
echo $this->Form->input('title');
echo $this->Form->input('caption', array('class'=>'ckeditor'));
echo $this->Form->input('imgPath', array('type' => 'file'));
echo $this->Form->input('alt_tag');
echo $this->Form->input('type', array( 'label' => 'Choose a type of photo', 'options' => array(
'gallery'=>'gallery',
'news'=>'news',
'post'=>'post',
)));
echo $this->Form->input('active', array( 'label' => 'Make active', 'options' => array('yes'=>'yes','no'=>'no' )));
echo $this->Form->input('gallery_id');
?>
</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
This is the controller admin edit code:
public function admin_edit($id = null) {
$this->layout = 'admin';
if (!$this->Photo->exists($id)) {
throw new NotFoundException(__('Invalid photo'));
}
if ($this->request->is(array('post', 'put'))) {
if ($this->Photo->save($this->request->data)) {
$this->Session->setFlash(__('The photo has been saved.'), 'success');
return $this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The photo could not be saved. Please, try again.'), 'error');
}
} else {
$options = array('conditions' => array('Photo.' . $this->Photo->primaryKey => $id));
$this->request->data = $this->Photo->find('first', $options);
}
$galleries = $this->Photo->Gallery->find('list');
$this->set(compact('galleries'));
}
Have I overlooked something obvious?
Cheers, Paul
When You editing record, You must set ID of this record.
Add to form $this->Form->input('id') or set ID in controller before save() action
I am newbie to cake php and I have a problem.
When a user updates his profile iam asking to enter his password.Now I dont know how to check it with the stored password.
<?php echo $form->create('UserProfile', array('url' => array('action' => 'edit_profile', 'controller' => 'users'))); ?>
<?php
echo $form->input('nickname', array('label' => __('Display Name', true), 'class' => 'INPUT required'));
?>
<b>To save these settings, please enter your password</b><br /><br />
<?php
echo $form->input('repeat_password', array('label' => __('Password', true), 'class' => 'INPUT required','type'=>'password'));
echo $form->input('private', array('label' => __('Set Profile Private', true), 'class' => 'INPUT required'));
?>
<!-- <div id="CityList">
<?php
// echo $form->input('city', array('id' => 'citySelect', 'name' => 'data[UserProfile][city]', 'empty' => __('Please select city', true), 'label' => __('City', true), 'class' => 'INPUT required'));
?>
</div> -->
<?php echo $form->submit(__('Submit', true), array('class' => 'save_btn')) ?>`
>
In My model i have applied the following validation on repeat password.
'repeat_password' => array(
array('rule' => 'check_repeatPassword'),
array('rule' => 'notempty', 'message' => __('Required', true), 'require' => true),
array('rule' => 'alphaNumeric', 'allowEmpty' => true, 'message' => __('Password must only contain letters and numbers.', true)),
array('rule' => array('minLength', 6), 'allowEmpty' => true,
'message' => __('Password must be at least 6 characters long.', true)),
array('rule' => array('maxLength', 16), 'allowEmpty' => true,
'message' => __('Password must be at most 16 characters long.', true))
),
function check_repeatPassword($data) {
$repeatPassword = $data['repeat_passowrd'];
$passwordExists = $this->find('count', array('conditions' => array('User.repeat_password' => $repeatPassword)));
if ($passwordExists == 0) {
return false;
}
return true;
}
In My Controller I have made the following edit profile method.
function edit_profile() {
$this->loadModel('UserProfile');
$user = $this->_authenticate_user();
$id = $user['account_num'];
if (!empty($this->data)) {
$this->data['UserProfile']['account_name'] = $id;
unset($this->data['UserProfile']['country']);
unset($this->data['UserProfile']['city']);
if ($this->UserProfile->save($this->data)) {
$userInfo = $this->User->getUserInfo($id);
$this->User->reassign_session($userInfo);
$this->flashMessage(__('Your Profile has been Updated successfully', true), 'Sucmessage');
//$this->redirect(array('action' => 'profile'));
} else {
$this->flashMessage(__('Your Profile has not been updated. Please, try again.', true));
}
}
if (empty($this->data)) {
$this->data = $this->UserProfile->read(null, $id);
}
// $this->loadModel('Country');
// $countries = $this->Country->find('list');
// $this->set('countries', $countries);
$this->loadModel('Nationality');
$nationalities = $this->Nationality->find('list', array('fields' => array('name', 'name')));
$this->set('nationalities', $nationalities);
$this->pageTitle = __('Edit My Profile', true);
}
Kindly help me how to do this.Thankssssss in advance
You are not storing passwords in plain text
I cannot avoid seeing this and being amazed:
$passwordExists = $this->find('count', array(
'conditions' => array(
'User.repeat_password' => $repeatPassword
)
));
Please, please confirm that you aren't storing user passwords in plain text, and if you are stop doing so immediately and execute the following sql:
ALTER TABLE users DROP repeat_password;
Compare a hash with a hash
In the db, you should have the user's existing password stored as a one-way-hash. Assuming that's the case, to verify that the user entered their existing account password - just hash what they provided in the same way the Auth component does, and compare to the db:
function check_repeatPassword($data) {
$userId = $this->data['UserProfile']['account_name']; // from the question
$userInput = current($data);
$hashedUserInput = Security::hash($userInput, null, true);
return $this->find('count', array(
'conditions' => array(
'password' => $hashedUserInput,
'id' => $userId
)
));
}
This will confirm that the password the user entered, is the same as the one already in the db for that user.
I'm trying to set up a commercial proposal system using CakePHP 2.3.
It has 5 tables which are associated (see details below).
This system will have 1 page on which are 5 forms for each table. (see details below).
Form 1: table proposals
Form 2: table clients FK proposal_id
Form 3: table products FK client_id
Form 4: table specifications FK product_id (of the product)
Form 5: table appendices FK product_id (of the product)
WHERE:
proposals hasOne clients.
----------v----------
clients beongsTo proposals AND hasMany products.
----------v----------
products belongsTo clients AND hasMany specifications & appendices.
----------v----------
specifications belongsTo products.
appendices belongsTo products.
The form 4 can have multiple row so it's inside a foreach loop to generate more input. Same for the form 5. Because 1 product can have multiple specifications and appendices.
I admit, it's pretty tricky :)
This is the solution I finally chose, but maybe there is better. For exemple, I could make a multi-step form but it seems quite difficult to put in place. Anyway, i'm open to suggestion.
Meanwhile, I'm sure we can make this work so here are the details. For each table, I have created a model and made the appropriated connections. In each model I have enable the containable behaviour: public $actsAs = array('Containable');.
Now here is the ProposalsController.php:
function admin_edit($id=null){
$this->loadModel('Proposal','Client','Product', 'Specification', 'Appendice');
$this->Proposal->contain('Proposal','Client','Product', 'Specification', 'Appendice');
if ($this->request->is('put') || $this->request->is('Post')) {
$data = $this->request->data;
if (!empty($data)) {
// Use the following to avoid validation errors:
// unset($this->Proposal->Client->validate['proposal_id']);
// $this->Proposal->saveAssociated($data);
// $this->Session->setFlash("Le contenu a bien été édité");
// $this->redirect(array('action' => 'index', $data['Product']['id']));
debug($data);
}
}
elseif($id){
$this->Proposal->id = $id;
$this->request->data = $this->Proposal->read(null,$id);
}
}
This edit action has many errors because I don't know how to set it up correctly in that case. So forgive me but I give you a raw code :). I would like this admin_function to add or edit, but again, in this case I don't know how to handle it.
And the view admin_edit.ctp :
<hr/>
<h1>Proposition</h1>
<hr/>
<?php echo $this->Form->create('Product'); ?>
<?php echo $this->Form->input('Proposal.name', array('label' => "Nom de la proposition")); ?>
<?php echo $this->Form->input('Proposal.created', array('label' => "Date de création")); ?>
<?php echo $this->Form->input('Proposal.due', array('label' => "Date d'échéance")); ?>
<?php echo $this->Form->input('Proposal.content', array('label' => "Termes & conditions")); ?>
<hr/>
<h1>Client</h1>
<hr/>
<?php echo $this->Form->input('Client.name', array('label' => "Nom du client")); ?>
<?php echo $this->Form->input('Client.project', array('label' => "Nom du projet")); ?>
<?php echo $this->Form->input('Client.address', array('label' => "Adresse")); ?>
<?php echo $this->Form->input('Client.phone', array('label' => "Téléphone")); ?>
<?php echo $this->Form->input('Client.email', array('label' => "Email")); ?>
<?php echo $this->Form->hidden('Client.proposal_id'); ?>
<hr/>
<h1>Produit</h1>
<hr/>
<?php echo $this->Form->input('Product.0.name', array('label' => "Nom du produit")); ?>
<?php echo $this->Form->input('Product.0.reference', array('label' => "Référence")); ?>
<?php echo $this->Form->input('Product.0.image', array('label' => "Image")); ?>
<?php echo $this->Form->input('Product.0.pu', array('label' => "Prix Unitaire")); ?>
<?php echo $this->Form->input('Product.0.quantity', array('label' => "Quantité")); ?>
<?php echo $this->Form->input('Product.0.ce', array('label' => "CE")); ?>
<?php echo $this->Form->input('Product.0.nf', array('label' => "NF")); ?>
<?php echo $this->Form->input('Product.0.rohs', array('label' => "RoHS")); ?>
<?php echo $this->Form->hidden('Product.0.client_id'); ?>
<hr/>
<h1>Spécifications :</h1>
<hr/>
<?php
foreach (range(0,1) as $i):
$a=$i+1;
echo '<p>Spécification '.$a.'</p>';
echo $this->Form->input('Specification.'.$i.'.name', array('label' => "Nom de la spécification"));
echo $this->Form->input('Specification.'.$i.'.value', array('label' => "Valeur de la spécification"));
echo $this->Form->hidden('Specification.'.$i.'.product_id');
endforeach;
?>
<hr/>
<h1>Annexes :</h1>
<hr/>
<?php
foreach (range(0,1) as $j):
$b=$j+1;
echo '<p>Annexe '.$b.'</p>';
echo $this->Form->input('Appendice.'.$j.'.name', array('label' => "Image"));
echo $this->Form->input('Appendice.'.$j.'.content', array('label' => "Description de l'annexe"));
echo $this->Form->hidden('Appendice.'.$j.'.product_id');
endforeach;
?>
<?php echo $this->Form->end('valider'); ?>
And finally, here is the array result of the debug($data):
array(
'Proposal' => array(
'name' => 'Proposition 3',
'created' => array(
'month' => '02',
'day' => '19',
'year' => '2013',
'hour' => '08',
'min' => '27',
'meridian' => 'am'
),
'due' => array(
'month' => '02',
'day' => '19',
'year' => '2013',
'hour' => '08',
'min' => '27',
'meridian' => 'am'
),
'content' => 'Termes & conditions'
),
'Client' => array(
'name' => 'Client 3',
'project' => 'Projet Client 3',
'address' => 'Adresse Client 3',
'phone' => 'Téléphone Client 3',
'email' => 'Email#test.com',
'proposal_id' => ''
),
'Product' => array(
(int) 0 => array(
'name' => 'Produit 3',
'reference' => 'Référence Produit 3',
'image' => 'Image Produit 3',
'pu' => '100.77',
'quantity' => '1000',
'ce' => '1',
'nf' => '0',
'rohs' => '0',
'client_id' => ''
)
),
'Specification' => array(
(int) 0 => array(
'name' => 'Specification 1',
'value' => 'Valeur 1',
'product_id' => ''
),
(int) 1 => array(
'name' => 'Specification 2',
'value' => 'Valeur 2',
'product_id' => ''
)
),
'Appendice' => array(
(int) 0 => array(
'name' => 'Image annexe 1',
'content' => 'Description de l'annexe',
'product_id' => ''
),
(int) 1 => array(
'name' => 'Image annexe 2',
'content' => 'Description de l'annexe',
'product_id' => ''
)
)
)
So in this array, everything is there. I just need to take these data and save them all in the corresponding tables. The first problem is to manage with the table's associations. Then the 2 foreach loops that generate multiple row.
I would like to save it all at once but is it even possible?
After trying many ways to get it work, I've gone completely crazy and I just lost myself. I'm really desperate on that one, i mix up everything between the saving method and the request->data that contains everything but cannot get it saved. Anyway, i'm desperately in need for help!
Thank you very much in advance for all the help you can give me, I really appreciate!
[EDIT]
I add my model to the present post for more detail.
Proposal.php:
<?php
class Proposal extends AppModel {
public $actsAs = array('Containable');
public $validate = array(
'name' => array(
'rule' => 'notEmpty',
'message' => "Veuillez préciser un titre"
)
) ;
public $hasOne = array(
'Client' => array(
'className' => 'Client',
'foreignKey' => 'proposal_id',
'dependent' => true
)
);
}
Client.php:
<?php
class Client extends AppModel {
public $actsAs = array('Containable');
public $belongsTo = array(
'Proposal' => array(
'className' => 'Proposal',
'foreignKey' => 'proposal_id'
)
);
public $hasMany = array(
'Product' => array(
'className' => 'Product',
'foreignKey' => 'client_id',
'conditions' => '',
'order' => '',
'limit' => '',
'dependent' => true
)
);
}
Product.php:
<?php
class Product extends AppModel {
public $actsAs = array('Containable');
public $belongsTo = array(
'Client' => array(
'className' => 'Client',
'foreignKey' => 'client_id'
)
);
public $hasMany = array(
'Specification' => array(
'className' => 'Specification',
'foreignKey' => 'product_id',
'conditions' => '',
'order' => '',
'limit' => '',
'dependent' => true
),
'Appendice' => array(
'className' => 'Appendice',
'foreignKey' => 'product_id',
'conditions' => '',
'order' => '',
'limit' => '',
'dependent' => true
)
);
}
Specification.php:
<?php
class Specification extends AppModel {
public $actsAs = array('Containable');
public $belongsTo = array(
'Product' => array(
'className' => 'Product',
'foreignKey' => 'product_id'
)
);
}
Appendice.php:
<?php
class Appendice extends AppModel {
public $actsAs = array('Containable');
public $belongsTo = array(
'ProductAppend' => array(
'className' => 'Product',
'foreignKey' => 'product_id'
)
);
}
What's the output when you save the data?
if (!empty($this->data)) {
$this->Proposal->save($this->data);
}
You should also check the sql-output
echo $this->element('sql_dump');
edit:
Well after your edit, on the first look it seems that your relations are wrong.
Check out the examples in the book: http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html
For example hasOne: the other model contains the foreign key.
As I said earlier, you should try to start with just one relation, getting it to work. Afterwords, it'll be much easier to get the other working. So try to comment-out everything except your Proposal and Client model. Then try saving just those two.
I have a form that has multiple entries to the same table, the problem I'm having is that it only sends the last entry to the database and doesn't send the rest. I have used the debug and it only prints out the last field in the form.
With each iteration of field its meant to input into the fields_invoices table a invoice_id, field_id, entered_value
Here is my form
<?php echo $this->Form->create('FieldsInvoice'); ?>
<?php foreach ($fields as $field): ?>
<?php echo $this->Form->hidden('FieldsInvoice.id'); ?>
<?php echo $this->Form->hidden('FieldsInvoice.field_id', array('default' =>$field['Field']['id'])); ?>
<?php echo $this->Form->input('FieldsInvoice.invoice_id', array('default' =>$invoice_id, 'type'=>'hidden')); ?>
<?php echo $this->Form->Input('FieldsInvoice.entered_value', array('label'=>$field['Field']['name'], 'default' =>$field['Field']['default_value'])); ?>
<?php endforeach ;?>
<?php echo $this->Form->End('Submit');?>
Here is the related controller
public function create($id)
{
$this->set('title_for_layout', 'Create Invoice');
$this->set('stylesheet_used', 'homestyle');
$this->set('image_used', 'eBOXLogoHome.png');
$this->layout='home_layout';
if (!is_numeric($id)) throw new BadMethodCallException('I need an ID');
$this->Invoice->id = $id;
if (!$this->Invoice->exists()) throw new NotFoundException('Invalid ID');
$this->set('invoice_id',$id);
$names = $this->Invoice->find('list',array(
'fields'=>array('template_id'),
'conditions'=>array('id'=>$id)));
$fields = $this->Field->find('all', array(
'conditions'=>array(
'template_id'=>$names)));
$this->set(compact('fields'));
$this->set(compact('invoice_id'));
$this->set('name',$names);
$this->Invoice->create();
if(empty($this->data)){
$this->data= $this->Field->read($id);
}
else{
if($this->request->is('post'))
{
//die(debug($this->data));
$this->Invoice->create();
if($this->FieldsInvoice->save($this->request->data, array('deep'=>true)));
{
$this->Session->setFlash('The field has been updated');
$this->redirect(array('controller'=>'invoices', 'action'=>'index'));
}
//else{
$this->Session->setFlash('Could not be saved');
//}
}
}
}
\app\Controller\InvoicesController.php (line 134)
array(
'FieldsInvoice' => array(
(int) 0 => array(
'id' => '',
'field_id' => '0',
'invoice_id' => '97',
'entered_value' => '1'
),
(int) 1 => array(
'id' => '',
'field_id' => '99',
'invoice_id' => '97',
'entered_value' => '2'
),
(int) 2 => array(
'id' => '',
'field_id' => '999',
'invoice_id' => '97',
'entered_value' => '3'
),
(int) 3 => array(
'id' => '',
'field_id' => '9999',
'invoice_id' => '97',
'entered_value' => '4'
)
)
)
To post multiple fields, use:
foreach ($fields as $idx => $field):
echo $this->Form->hidden('FieldsInvoice.'.$idx.'.id');
echo $this->Form->hidden('FieldsInvoice.'.$idx.'.field_id', ...);
...
and then use $this->FieldsInvoice->saveMany() (instead of ->save()) to save multiple records.
My controller action is:
function add() {
if (!empty($this->data)) {
$this->Customer->create();
if ($this->Customer->save($this->data)) {
$this->Session->setFlash('A new Customer has been added');
$this->redirect(array('action'=>'index'));
}
else {
$this->Session->setFlash('The customer cannot be added this time. Try again later.');
$this->redirect(array('action'=>'index'));
}
}
}
My model is:
class Customer extends AppModel {
var $name = 'Customer';
var $validate = array(
'name' => array(
'length'=> array(
'rule' => array('between', 4,50),
'message' => 'Name must be minimum 4 and maximum 50 characters long.'
),
'checkUnique'=> array(
'rule' => 'isUnique',
'message' => 'This Name is already registered'
)
));
and this is my view:
<div class="customers form">
<?php echo $form->create('Customer',array('action'=>'add'));?>
<fieldset>
<legend><?php __('Add Customer');?></legend>
<?php
echo $form->input('Customer.name');
echo $form->input('Customer.balance',array('type'=>'hidden','default'=>0));
?>
</fieldset>
<?php echo $form->end('Submit');?>
</div>
every time I submit the form it splashes:
The customer cannot be added this time. Try again later.
For the hidden input field use 'value' instead of 'default' in your view:
$form->input('Customer.balance', array('type' => 'hidden', 'value' => 0));