HasMany Through multiple entries - new - cakephp

I am playing around with the CourseMembership HasMany through example in the CakePHP cookbook but I cant figure out how to add a new Course and multiple entries into CourseMembership (i.e. student_id and grade) all at the same time.
Course hasMany Coursemmembership
Student hasMany Coursemeembership
Coursemembership belongsTo Student, Course
//CoursemmembershipsController
public function add() {
if ($this->request->is('post')) {
$this->Coursemembership->create();
if ($this->Coursemembership->saveAll($this->request->data,array('deep' => true))) {
$this->Session->setFlash(__('The coursemembership has been saved.'));
//return $this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The coursemembership could not be saved. Please, try again.'));
}
debug($this->request->data);
}
$courses = $this->Coursemembership->Course->find('list');
$students = $this->Coursemembership->Student->find('list');
$this->set(compact('courses', 'students'));
}
__
//Coursemembership/view/add
$this->Form->create('Coursemembership');
echo $this->Form->input('Course.name');
echo $this->Form->input('0.Coursemembership.student_id');
echo $this->Form->input('0.Coursemembership.grade');
echo $this->Form->input('1.Coursemembership.student_id');
echo $this->Form->input('1.Coursemembership.grade');
?>
The data array successfully saves, inserts a new Course fine, but inserts only 1 Coursemembership entry with no student_id or grade.
Data array looks like:
array(
'Course' => array(
'name' => 'Math 101'
),
(int) 0 => array(
'Coursemembership' => array(
'student_id' => '1',
'grade' => '5'
)
),
(int) 1 => array(
'Coursemembership' => array(
'student_id' => '2',
'grade' => '2'
)
)
)

remove Coursemembership from Form input --- Use this
echo $this->Form->create('Coursemembership');
echo $this->Form->input('Course.name');
echo $this->Form->input('0.student_id');
echo $this->Form->input('0.grade');
echo $this->Form->input('1.student_id');
echo $this->Form->input('1.grade');
echo $this->Form->end('save');

Got it! I used the Course controller as recommended, with the following Course/add view and it now works. Thanks
echo $this->Form->input('Course.name');
echo $this->Form->input('Coursemembership.0.student_id');
echo $this->Form->input('Coursemembership.0.grade');
echo $this->Form->input('Coursemembership.1.student_id');
echo $this->Form->input('Coursemembership.1.grade');

Related

Milesj uploader plugin creates new record instead of editing existing record

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

Cakephp HABTM saving -.-

I'm googling high and low on this. I'm not sure where i went wrong cause I don't get any errors.
i have 3 tables:
MOVIES - id, title, genre, etc
GENRES - id, genre
GENRES_MOVIES - movie_id, genre_id
Movie model:
public $hasAndBelongsToMany = array(
'Genre' => array(
'className' => 'Genre',
'joinTable' => 'genres_movies',
'foreignKey' => 'movie_id',
'associationForeignKey' => 'genre_id'
)
);
View:
echo $this->Form->create('Movie', array('controller' => 'movies', 'action' => 'add', 'type' => 'file'));
echo $this->Form->input('title');
echo $this->Form->input('description', array('type' => 'textarea');
echo $this->Form->input('imdb_url');
echo $this->Form->year('release_year', 1900, date('Y'));
echo $this->Form->input('length', array('type' => 'number'));
echo $this->Form->input('genre', array('type'=>'select', 'multiple'=>'checkbox', 'options'=> $genres));
echo $this->Form->input('image', array('type' => 'file'));
echo $this->Form->button('Submit');
MoviesController:
public function add()
{
/* for populating checkbox */
$this->set('genres', $this->Movie->Genre->find('list', array('fields' => array('Genre.id', 'Genre.genre'))));
if($this->request->is('post'))
{
$data_movie = array(
'title' => $this->request->data['Movie']['title'],
'description' => $this->request->data['Movie']['description'],
'imdb_url' => $this->request->data['Movie']['imdb_url'],
'release_year' => (int)$this->request->data['Movie']['release_year']['year'],
'length' => (int)$this->request->data['Movie']['length'],
'user_id' => (int)$this->Auth->user('id')
);
$data_genre = array('Genre' => array());
foreach($this->request->data['Movie']['genre'] as $genre)
array_push($data_genre['Genre'], (int)$genre);
$data = array('Movie' => $data_movie, 'Genre' => $data_genre);
$this->Movie->create();
if($this->Movie->save($data)
{
echo 'success';
}
}
}
So, why did I bother setting up data manually for saving in the movieController, it is because the tutorials are telling me data should be organised like it is now (before that it looked a little different.. so i tried and this is what i have now (it looks ok to me)
http://s10.postimg.org/ikewszo95/Untitled_1.jpg
you can see the form here http://marko-stimac.iz.hr/temp/movies/movies/add (although submit wont work, i guess it is because of the Auth component not letting non-registered users)
hm any help would be greeatly appreciated :)
EDIT - updated controller
public function add()
{
$this->set('genres', $this->Movie->Genre->find('list', array('fields' => array('Genre.id', 'Genre.genre'))));
if($this->request->is('post'))
{
($this->Movie->saveAssociated($this->request->data))
{
$this->redirect('/');
$this->Session->setFlash('Success.');
}
}
}
Don't modify the data, that is, get rid of these lines
$data_genre = array('Genre' => array());
foreach($this->request->data['Movie']['genre'] as $genre)
array_push($data_genre['Genre'], (int)$genre);
$data = array('Movie' => $data_movie, 'Genre' => $data_genre);
$this->Movie->create();
And save your data using
if ($this->Movie->saveAssociated($this->request->data) {
...
EDIT
Modify your form, change this
echo $this->Form->input('genre', array('type'=>'select', 'multiple'=>'checkbox', 'options'=> $genres));
to this
echo $this->Form->input('Genre', array('type'=>'select', 'multiple'=>'checkbox', 'options'=> $genres));

Cakephp: combine input values to create hidden name input

I've searched high and low for a solution but can't seem to get this figured out. What I'm trying to do is upon adding a product, I want the name field to be populated from the inputs in the form. So the name would include the values the user selects for type_id,category_id and subcategory_id. Does anyone know of a way to accomplish this?
Add product View page
<fieldset>
<legend><?php echo __('Add Product'); ?></legend>
<?php
echo $this->Form->input('type_id');
echo $this->Form->input('category_id', array('label' => 'Vendor'));
echo $this->Form->input('subcategory_id', array('label' => 'Model'));
echo $this->Form->input('location', array('label' => 'Location'));
echo $this->Form->input('sku', array('label' => 'Asset Tag'));
echo $this->Form->input('mac');
echo $this->Form->input('description', array('label' => 'Notes'));
echo $this->Form->input('name', array( 'value' => ['type_id']['category_id'] , 'type' => 'hidden'));
//echo $this->Form->input('cost');
// echo $this->Form->input('Tag');
?>
</fieldset>
Product controller add function
public function add() {
if ($this->request->is('post')) {
$this->Product->create();
if ($this->Product->save($this->request->data)) {
$this->Session->setFlash(__('The product has been saved'));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The product could not be saved. Please, try again.'));
}
}
$subcategories = $this->Product->Subcategory->find('list',array('order'=>'Subcategory.name asc'));
$categories = $this->Product->Category->find('list',array('order'=>'Category.name asc'));
$types = $this->Product->Type->find('list',array('order'=>'Type.name asc'));
$this->set(compact('subcategories', 'categories', 'types'));
}
In order to do it the way you are trying to do it, you would have to use client-side javascript to update the input value "on-the-fly", but that's not very safe and can easily be messed with. It would make much more sense to drop the name input altogether and just handle this in the beforeSave method of your Product model (or alternatively by defining the name value in your Controller just before saving).
public function beforeSave($options = array()) {
// Generate the name based on type and category
$this->data['Product']['name'] = $this->data['Product']['type_id'] .
$this->data['Product']['category_id'];
return true;
}
Update based on your comment.
In order to get the names, just find those names (assuming your models are associated) and define those:
public function beforeSave($options = array()) {
// Get the type name
$type = $this->Type->field('name', array(
// Set the condition for the field
'Type.id' => $this->data['Product']['type_id']
));
// Get the category name
$category = $this->Category->field('name', array(
// Set the condition for the field
'Category.id' => $this->data['Product']['category_id']
));
// Generate the name based on type and category
$this->data['Product']['name'] = $type . $category;
return true;
}

cakephp session data and forms

Hi all I'm trying to create a form where a user can create a new user which will have the same account_id as the person creating the user.
currently my page is displaying the correct account_id in the form but when we submit the form to the database it saves as the wrong thing.
here is my function
function add_Employee(){
$accounts=$this->User->find('list', array(
'fields'=>array('account_id'),
'conditions' => array(
'User.id' => $this->Auth->user('id'))));
if($this->request->is('post')){
$this->User->create();
if ($this->User->save($this->request->data))
{
$this->Session->setFlash('The user has been saved');
$this->redirect( array('controller'=>'Users','action' => 'index_admin'));
}
else { $this->Session->setFlash('The user could not be saved. Please, try again.'); }
}
$this->set('accounts',$accounts);
}
and the view
<h2>Add Employee</h2>
<p>Add a new Employee here, please enter their details below.</p>
<?php
echo $this->Form->create('User', array('action'=>'add_Employee'));
echo $this->Form->input('username',array('label'=>'Username: '));
echo $this->Form->input('password',array('label'=>'Password: '), array('type'=>'password'));
echo $this->Form->input('password_confirmation',array('label'=>'Confirm: '), array('type'=>'password'));
echo $this->Form->input('email',array('label'=>'Email: '));
echo $this->Form->input('title',array('label'=>'Title: '));
echo $this->Form->input('firstname',array('label'=>'First Name: '));
echo $this->Form->input('surname',array('label'=>'Surname: '));
echo $this->Form->input('active', array('default'=>true, 'type'=>'hidden'));
echo $this->Form->input('account_id', array('value'=>$accounts['User']['account_id']));
echo $this->Form->input('access_level', array(
'label' => 'Access Level:',
'options' => array('1'=>'Employee','2'=>'Adminstrator')));
echo $this->Form->end('Submit');
?>
you have to put account id as value in form :
In controller:
$accounts=$this->User->find('first', array(
'conditions' => array(
'id' => $this->Auth->user('id'))));
$this->set('account',$accounts);
In view :
echo $this->Form->input('account_id', array('label'=>'Account','value'=>$account['User']['account_id']));

CakePHP - Multiple row edits

How can I do edits to a table on multiple rows?
I followed the tutorial here http://matsimitsu.com/blog/2008/01/06/saveall-with-cakephp.html but it doesn't seem to work.
Here is what I'm doing, but it's not working.
Thanks,
Tee
function editAll() {
$this->data = $this->Settings->find('all', array('conditions' => $conditions));
}
Then in the view, this is what I have
foreach ($this->data as $setting):
echo $form->input('Setting.' . $setting['Setting']["id"] . '.value', array('value' => $setting['Setting']["value"]));
endforeach;
Then in the add function I have
function add() {
if (!empty($this->data)) {
$this->Setting->create();
if ($this->Setting->saveAll($this->data)) {
$this->Session->setFlash(__('The Setting has been saved', true));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The Setting could not be saved. Please, try again.', true));
}
}
}
You need to include the id field, so the data in your controller will look like this:
'Setting' => array(
0 => array(
'id' => 42,
'value' => 'foo'
),
1 => array(…)
)
So in the view, do this:
foreach ($this->data as $i => $setting) {
echo $this->Form->hidden("Setting.$i.id", array('value' => $setting['Setting']['id']));
echo $this->Form->input("Setting.$i.value", array('value' => $setting['Setting']['value']));
}

Resources