i want to create an simple application that will allow graduating students to register for graduation attendance. From the application form the student enter the details that's saved to the students table waiting for approval. The admin then approves the request and the record is inserted in the approved table and deleted from the students table. How can i write the approve action and how can i move the record to the approved table in cakephp 2.6.3.
thanks in advance
I would use one and same table to save this data. Use the table students. Add a approved column to the table where 0 = not approved, 1 = approved. When students are entering their data and saves it to students table, make sure approved = 0. Then admin can go change this value to 1 if student is approved.
// StudentsController.php
public function approve($id = null) {
if (!$this->Student->exists($id)) {
throw new NotFoundException(__('Invalid'));
}
if ($this->request->is(array('post', 'put'))) {
if ($this->Student->save($this->request->data)) {
$this->Session->setFlash(__('The student has been saved.'), 'default', array('class' => 'notice success'));
return $this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The student could not be saved. Please, try again.'), 'default', array('class' => 'notice error'));
}
} else {
$options = array('conditions' => array('Student.' . $this->Student->primaryKey => $id));
$this->request->data = $this->Student->find('first', $options);
}
}
app/View/Students/approve.ctp:
<h1><?php echo __('Approve student');?></h1>
<?php echo $this->Form->create('Student'); ?>
<?php
echo $this->Form->input('id');
echo $this->Form->input('approved', array('label' => __('Approve'), 'options' => array(
'0' => __('Not approved'),
'1' => __('Approved'),
)));
?>
<?php echo $this->Form->end(array('label' => __('Save'), 'class' => 'button')); ?>
Sorry for not answering your exact question, but I really think it is unnecessary to use two tables to identify who are not approved vs approved students.
Related
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;
}
I'm pretty new to cakePHP and I've been stuck on this problem for a few days now. My Products index view displays a list of products we have in inventory and includes a "Checkout" action with every product that points to the Checkout/add view. The problem is the product_id from the product that needs to be checked out does not get passed to the add checkout page and I can't figure out how to make this happen. If anyone has any suggestions I could really use some help.
Here is my CheckoutController add action:
public function add() {
if ($this->request->is('post')) {
$this->Checkout->create();
if ($this->Checkout->save($this->request->data)) {
$this->Session->setFlash(__('The checkout has been saved'));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The checkout could not be saved. Please, try again.'));
}
}
$products = $this->Checkout->Product->find('list');
$users = $this->Checkout->User->find('list');
$this->set(compact('products', 'users'));
}
Checkout Add View
<?php echo $this->Form->create('Checkout');?>
<fieldset>
<legend><?php echo __('Add Checkout'); ?></legend>
<?php
echo $this->Form->input('product_id');
echo $this->Form->input('start_time');
echo $this->Form->input('end_time');
echo $this->Form->input('user_id');
echo $this->Form->input('description');
?>
</fieldset>
Link from the Products index page
<?php echo $this->Html->link(__('Checkout'), array('controller' => 'Checkouts','action' => 'add', $product['Product']['id'])); ?>
Cake will pass the product_id as the first argument of your action; Default Cake 'Routes' will match this url;
/mycontroller/myaction/param1/param2/param3
To this action:
MycontrollerController::myaction(param1, param2, param3)
You can pass this value to the form by adding an argument to the add() action and adding it to the 'request' if the form is not posted. Like this;
public function add($productId = null) {
if ($this->request->is('post')) {
$this->Checkout->create();
if ($this->Checkout->save($this->request->data)) {
$this->Session->setFlash(__('The checkout has been saved'));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The checkout could not be saved. Please, try again.'));
}
} else {
$this->request->data['Checkout']['product_id'] = $productId;
}
$products = $this->Checkout->Product->find('list');
$users = $this->Checkout->User->find('list');
$this->set(compact('products', 'users'));
}
This will automatically propagate the 'value' of the product_id drop down
from your links on the products index page it seems that
public function add()
should read
public function add($product_id)
furthermore you should set the $product_id into the view, and also
fill it into the inputbox echo $this->Form->input('product_id', array('value'=>$product_id));
I have two models Business and User. They are related by a HABTM relationship.
Everything is working with the baked controllers, models and views.
Now I'm trying to combine the two models in one form so the user can enter a business name with is user info.
Here's the form :
Form->create('User'); ?>
Form->input('Business.name', array('label' => __('Business name')));
echo $this->Form->input('User.email');
echo $this->Form->input('User.firstname');
echo $this->Form->input('User.lastname');
echo $this->Form->input('User.password');
echo $this->Form->input('User.phone_cell', array('type' => 'text'));
echo $this->Form->input('User.phone_home', array('type' => 'text'));
echo $this->Form->input('User.phone_work', array('type' => 'text'));
?>
Form->end(__('Submit')); ?>
The only way I was able to make it work was to save the User first and then get the user id and save the business after by adding the user array with the new id.
if ($this->User->save($this->request->data)) {
$this->request->data['User'] = array('User' => array(0 => $this->User->id));
if ($this->User->Business->save($this->request->data)) {
// User saved
} else {
// User not saved
}
} else {
$this->Session->setFlash(__('The user could not be saved. Please, try again.'));
}
I tried the saveAll method without success. Is is possible to optimize this the CakePHP way for a single save ?
Thanks
I was able to get it to work myself with a couple models named User and Group. Here's some snips from my code to show how I did it:
UsersController.php
public function edit($id = null)
{
$this->User->id = $id;
if ($this->request->is('get')) {
//On page load load the user data
$this->request->data = $this->User->read();
} else {
//Saving
if ($this->User->save($this->data)) {
//....snipped...
} else {
$this->Session->setFlash('Unable to update the user.');
}
}
//Build $groups array for form
// Only admins can assign admin rights
if ($this->isMember('Admin')) {
$this->set('groups',$this->User->Group->find('list'));
} else {
$this->set('groups',$this->User->Group->find('list',array(
'conditions' => array(
'Group.name !=' => 'Admin'
)
)));
}
//...more snipping...
}
edit.ctp (View)
echo $this->Form->create('User', array('action' => 'edit'));
echo $this->Form->input('User.username');
echo $this->Form->input('Group',array(
'type' => 'select',
'multiple' => true,
'label' => "Group (Select multiple entries with CTRL)",
'size' => count($groups)
)
);
//More snipping
With that example to work from, how are you validating that the Business.name entered is valid and can be matched to the HABTM relation? Mine forces a selection list in this case. My Model is extremely simple so I didn't include that.
What are your outputs to debug($this->data); vs. debug($this->request->data)?
I've been trying to figure this problem out all morning. Tried some things from other questions, but it either didn't really apply to my situation or didn't work. I have two tables:
users = (id,name,username,password,roles,last_edit,language)
french_translations = (id, french_clinical_recommendations, french_tradenames, include_drug, french_category, drug_id, user_id)
User hasMany french_translations and french_translations belongsTo User.
When a user adds or edits a french_translation I want it to save the user id in the french_translations table, the field user_id, for that record, and then put the generic name for a drug in the last_edit field in the users table. Right now it creates a new record in each table. In the users table, everything is blank except for the id and last_edit field(Which puts the correct drug name in the field). And the french_translations table has a record with blanks, with the user_id being the same as the blank one created in the users table.
Controller:
function add($id = null) {
$userid = $session->read('Auth.User.id');
$drug = $this->FrenchTranslation->Drug->read(
array(
'Drug.id','Drug.generic','Drug.ahl','Drug.aap','Drug.rid','Drug.oral','Drug.mw','Drug.clinical_recommendations',
'Drug.category','Drug.lrc'
),
$id
);
$this->set('user',$userid);
$this->set('drug',$drug);
if (!empty($this->data)) {
$french_translation['FrenchTranslation']['id'] = $this->Session->read('id');
$this->FrenchTranslation->create();
if ($this->FrenchTranslation->save($this->data)) {
$this->Session->setFlash(__('The french translation has been saved', true));
$this->redirect(array('controller'=>'drugs','action' => 'index'));
} else {
$this->Session->setFlash(__('The french translation could not be saved. Please, try again.', true));
}
}
$drugs = $this->FrenchTranslation->Drug->find('list');
$this->set(compact('drugs'));
}
function edit($id = null) {
//$this->FrenchTranslation->id = $id;
$userid = $this->Auth->user('id');
$username = $this->Auth->user('name');
//$this->FrenchTranslation->user_id = $id;
$drug = $this->FrenchTranslation->Drug->read(
array(
'Drug.id','Drug.generic','Drug.ahl','Drug.aap','Drug.rid','Drug.oral','Drug.mw','Drug.clinical_recommendations',
'Drug.category','Drug.lrc'
),
$id
);
$this->set('drug',$drug);
$this->set('user',$userid);
$this->set('username',$username);
if (!$id && empty($this->data)) {
$this->Session->setFlash(__('Invalid french translation', true));
$this->redirect(array('action' => 'index'));
}
if (!empty($this->data)) {
if ($this->FrenchTranslation->saveAll($this->data)) {
$this->Session->setFlash(__('The french translation has been saved', true));
$this->redirect(array('controller'=>'drugs','action' => 'index'));
} else {
$this->Session->setFlash(__('The french translation could not be saved. Please, try again.', true));
}
}
if (empty($this->data)) {
$this->data = $this->FrenchTranslation->read(null, $id);
}
$drugs = $this->FrenchTranslation->Drug->find('list');
$this->set(compact('drugs'));
}
function delete($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid id for french translation', true));
$this->redirect(array('action'=>'index'));
}
if ($this->FrenchTranslation->delete($id)) {
$this->Session->setFlash(__('French translation deleted', true));
$this->redirect(array('action'=>'index'));
}
$this->Session->setFlash(__('French translation was not deleted', true));
$this->redirect(array('action' => 'index'));
}
Edit View:
<?php echo $this->Form->input('User.last_edit',array('type'=>'hidden','value'=>$drug['Drug']['generic'])); ?>
<?php echo $this->Form->input('user_id', array('type'=>'hidden','value'=>$user)); ?>
This is a bit of a late answer, but you should never use the view to set secure variables like user_id. Instead, you can set these variables in your controller:
$this->request->data['User']['last_edit'] = $this->request->data['Drug']['generic'];
I figured it out, however, I feel like there's a better and more secure, way of doing it. I am using the security component, and a person has to login to see any of the site, so it's probably safe enough.
I simply added a user.id input for the user id, at that point it could find the appropriate user to store the last_edit into. In the controller I have a variable called $userid which gets the current user id using $userid = $this->Auth->user('id'); and is passed to the view using $ths->set('user',$userid); I used that same user id value in the input for the drugs user_id field.
View:
<?php echo $this->Form->input('User.id',array('type'=>'hidden','value'=>$user));//The user ID last edit will be stored in ?>
<?php echo $this->Form->input('User.last_edit',array('type'=>'hidden','value'=>$drug['Drug']['generic']));//The drug edited last by the specified user ?>
How can I add an item and insert it into 2 tables?
So I have a 'Type' table and 'SpecificType' table.
Type has fields 'id' and some other common fields.
SpecificType has fields 'id', 'type_id' and some other uncommon fields.
When I go to /specific_types/add and I submit, ideally I want to first add that to 'Type' then add it to 'SpecificType'.
This is what I have now.
In SpecificType Model
var $belongsTo = array(
'Type' => array(
'className' => 'Type',
'foreignKey' => 'type_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
In SpecificType Controller
var $uses = ('Type', 'SpecificType');
function add() {
if (!empty($this->data)) {
$this->Type->create();
if ($this->Type->save($this->data)) {
$this->SpecificType->create();
if ($this->SpecificType->save($this->data)) {
$this->Session->setFlash(__('The SpecificType has been saved', true));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The SpecificType could not be saved. Please, try again.', true));
}
} else {
$this->Session->setFlash(__('The Type could not be saved. Please, try again.', true));
}
}
}
In SpecificType add.ctp
echo $form->input('Type.data1');
echo $form->input('title');
So right now, it saves Type.data1 but title isn't getting saved.
What am I missing?
Thanks,
Tee
Additional Info:
The 2nd model isn't saving only when I turn on MeioUpload.
Make sure your view is setup to create a form for SpecificType:
<?php echo $this->Form->create('SpecificType', array('action' => 'add')); ?>
<?php echo $this->Form->input('data1'); ?>
<?php echo $this->Form->input('title'); ?>
<?php echo $this->Form->end(); ?>
This will put all of your form data into: $this->data['SpecificType']
Right before your code:
$this->Type->create();
You need to do this:
$this->data['Type'] = $this->date['SpecificType'];
Then process the save. As long as the view is setup correctly for the SpecificType controller, all of the data from the form will be stored in $this->data['SpecificType']. If you pr($this->data) and there is data you need to save outside of $this->data['SpecificType'], review and fix the view.
Side note: Your design sounds awfully sketchy. You should never need to save the data in two locations. I would recommend revisiting the design of your app. There is something fundamentally wrong with it if you need to save the same data into two tables.
Just copy the data over to a SpecificType index in the data array and use saveAll(). The models are related so Cake will automatically link them via the type_id. We're working off the Type alias, so make sure you also have var $hasMany = array('SpecificType'); in your Type model.
function add() {
if (!empty($this->data)) {
$this->Type->create();
$this->data['SpecificType'] = $this->data;
if ($this->Type->saveAll($this->data)) {
$this->Session->setFlash(__('The SpecificType has been saved', true));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The SpecificType could not be saved. Please, try again.', true));
}
} else {
$this->Session->setFlash(__('The Type could not be saved. Please, try again.', true));
}
}
The code seems to be fine, use saveAll instead of save