CakePHP 2.x: I am struggling with validating an image upload field in a form for adding users. The upload field is not manditory. But it validates the field always as false while the image is uploaded. It seems the whole validation is working partially. Any help would be appreciated
User.php model :
public $validate = array(
'picture' => array(
'required' => false,
'allowEmpty' => true,
'custom' => array(
'rule' => array('imageExist'),
'message' => 'There is already a picture with that name on the server'
)
));
// function to check if file already exists
public function imageExist($check) {
$picturename = $check['picture'];
$path = WWW_ROOT . 'userimages/';
$file = $path . $picturename;
if (file_exists($file)) {
return false;
} else {
return true;
}
}
add.ctp:
<?php
echo $this->Form->create('User', array('class' => 'form-horizontal', 'role' => 'form', 'div' => false, 'type' => 'file'));
echo $this->Form->input('username', array('label' => "Username"));
echo $this->Form->input('picture', array('label' => "Avatar", 'type' => 'file'));
echo $this->Form>formDefaultActions();
echo $this->Form->end();
?>
UserController.php:
public function add() {
if ($this->request->is('post')) {
$this->User->create();
// set picture and path
$filedir = WWW_ROOT . 'userimages/';
$file = $filedir . $this->request->data['User']['picture']['name'];
// upload avatar picture
move_uploaded_file(
$this->request->data['User']['picture']['tmp_name'],
$file
);
$this->request->data['User']['picture'] = $this->request->data['User']['picture']['name'];
if ($this->User->save($this->request->data)) {
$this->Session->setFlash(__('The user has been added'), 'success' );
$this->redirect(array(
'action' => 'index'
));
} else {
$this->Session->setFlash(__('The user could not be created. Please, try again'), 'error' );
}
}
}
You need to check your validation before uploading or will be always false. If you upload your file, when cakephp validates your file already exists in folder.
You can just move your logic to something like:
$this->request->data['User']['picture'] = $this->request->data['User']['picture']['name'];
if ($this->User->save($this->request->data)) {
move_uploaded_file(
$this->request->data['User']['picture']['tmp_name'],
$file
);
}
Or check, before saving:
if ($this->User->validates()) {
if ($this->User->save($this->request->data)) {
move_uploaded_file(
$this->request->data['User']['picture']['tmp_name'],
$file
);
}
}
comment this
$this->request->data['User']['picture'] = $this->request->data['User']['picture']['name'];
and also take off the 2 statements into model, required and allowEmpty.also replace in your controller:
if ($this->User->save($this->request->data))
with
if ($this->User->save($this->request->data['User']))
and the pic name should be saved into the db
I got trouble inputing the radio button value to database, when i choose "submit" it won't add into database. This is the form view:
<?php
$form = array(
'no pengujian' => array(
'name' => 'NO_PENGUJIAN',
'size' => '30',
'class' => 'form_field',
'value' => set_value('NO_PENGUJIAN', isset($form_value['NO_PENGUJIAN']))),
'id kendaraan' => array(
'name' => 'ID_KENDARAAN',
'size' => '30',
'class' => 'form_field',
'value' => set_value('ID_KENDARAAN', isset($form_value['ID_KENDARAAN']))),
'no kendaraan' => array(
'name' => 'NO_KENDARAAN',
'size' => '30',
'class' => 'form_field',
'value' => set_value('NO_KENDARAAN', isset($form_value['NO_KENDARAAN']))),
'lampu' => array(
'name' => 'LAMPU',
'size' => '30',
'class' => 'radio',
'value' => set_value('LAMPU', isset($_POST['LAMPU']))),
'submit' => array(
'name' => 'submit',
'id' => 'submit',
'value' => 'Simpan'
)
);
?>
<h2><?php echo $breadcrumb ?></h2>
<!-- pesan start -->
<?php if (! empty($pesan)) : ?>
<div class="pesan">
<?php echo $pesan; ?>
</div>
<?php endif ?>
<!-- pesan end -->
<!-- form start -->
<?php echo form_open($form_action); ?>
<p>
<?php echo form_label('No Pengujian', 'NO_PENGUJIAN'); ?>
<?php echo form_input($form['no pengujian']); ?>
</p>
<?php echo form_error('NO_PENGUJIAN', '<p class = "field_error">', '</p>');?>
<p>
<?php echo form_label('Id Kendaraan', 'ID_KENDARAAN'); ?>
<?php echo form_input($form['id kendaraan']); ?>
</p>
<?php echo form_error('ID_KENDARAAN', '<p class="field_error">', '</p>'); ?>
<p>
<?php echo form_label('No Kendaraan', 'NO_KENDARAAN'); ?>
<?php echo form_input($form['no kendaraan']); ?>
</p>
<?php echo form_error('NO_KENDARAAN', '<p class="field_error">', '</p>'); ?>
<p>
<?php echo form_label('Lampu', 'LAMPU'); ?>
<input type ="radio" name = "lulus" value="Lulus"/> Lulus
<input type ="radio" name = "lulus" value= "Gagal"/> Gagal
</p>
<p>
<?php echo form_submit($form['submit']); ?>
<?php echo anchor('pengujian', 'Batal', array('class' => 'cancel')) ?>
</p>
<?php echo form_close(); ?>
This is the controller (tambah is "insert" function to database)
<?php if (!defined('BASEPATH')) exit ('No direct script access allowed');
class Pengujian extends MY_Controller
{
public $data = array(
'modul' => 'pengujian',
'breadcrumb' => 'Pengujian',
'pesan' => '',
'pagination' => '',
'tabel_data' => '',
'main_view' => 'view_pengujian/pengujian_view',
'form_action' => '',
'form_value' => '',
'option_uji' => '',
);
public function __construct()
{
parent::__construct();
$this->load->model('Pengujian_model', 'pengujian', TRUE);
$this->load->helper('form');
//$this->load->model('Penguji_model', 'penguji', TRUE);
}
public function index($offset = 0)
{
$this->session->unset_userdata('no_pengujian_sekarang', '');
$pengujian = $this->pengujian->cari_semua($offset);
if ($pengujian)
{
$tabel = $this->pengujian->buat_tabel($pengujian);
$this->data['tabel_data'] = $tabel;
$this->data['pagination'] = $this->pengujian->paging(site_url('pengujian/halaman'));
}
else
{
$this->data['pesan'] = 'Tidak ada data pengujian';
}
$this->load->view('template', $this->data);
}
public function tambah()
{
$this->data['breadcrumb'] = 'Pengujian > Tambah';
$this->data['main_view'] = 'view_pengujian/pengujian_form';
$this->data['form_action'] = 'pengujian/tambah';
//$penguji = $this->penguji->cari_semua();
//if($penguji)
//{
// foreach($penguji as $row)
// {
// $this->data['option_pengujian'][$row->id_penguji] = $row->penguji;
//}
//}
//else
//{
$this->data['option_pengujian']['00'] = '-';
// $this->data['pesan'] = 'Data penguji tidak tersedia. Silahkan isi dahulu data penguji.';
// if submit
if($this->input->post('submit'))
{
if($this->pengujian->validasi_tambah())
{
if($this->pengujian->tambah())
{
$this->session->set_flashdata('pesan', ' Proses tambah data berhasil');
redirect('pengujian');
}
else
{
$this->data['pesan'] = 'Proses tambah data gagal';
$this->load->view('template', $this->data);
}
}
else
{
$this->load->view('template', $this->data);
}
}
else
{
$this->load->view('template', $this->data);
}
}
This is the model:
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
class Pengujian_model extends CI_Model
{
public $db_tabel ='pengujian';
public $per_halaman = 100;
public $offset = 0;
public function cari_semua($offset = 0)
{
if (is_null($offset) || empty($offset))
{
$this->offset = 0;
}
else
{
$this->offset = ($offset * $this->per_halaman) - $this->per_halaman;
}
return $this->db->select('NO_PENGUJIAN, ID_KENDARAAN, NO_KENDARAAN, LAMPU, EMISI, REM, WAKTU_UJI')
->from($this->db_tabel)
->limit($this->per_halaman, $this->offset)
->order_by('NO_PENGUJIAN', 'ASC')
->get()
->result();
}
public function buat_tabel($data)
{
$this->load->library('table');
$tmpl = array('row_alt_start' => '<tr class="zebra">');
$this->table->set_template($tmpl);
$this->table->set_heading('No', 'No Pengujian', 'Id Kendaraan', 'No Kendaraan', 'Lampu','Emisi','Rem', 'Waktu Uji', 'Aksi');
$no = 0 + $this->offset;
foreach ($data as $row)
{
$this->table->add_row(
++$no,
$row->NO_PENGUJIAN,
$row->ID_KENDARAAN,
$row->NO_KENDARAAN,
$row->LAMPU,
$row->EMISI,
$row->REM,
$row->WAKTU_UJI,
anchor('pengujian/edit/'.$row->NO_PENGUJIAN,'Edit',array('class' => 'edit')).' '.
anchor('pengujian/hapus/'.$row->NO_PENGUJIAN,'Hapus',array('class' => 'delete','onclick'=>"return confirm('Anda yakin menghapus data ini?')")));
}
$tabel = $this->table->generate();
return $tabel;
}
public function paging($base_url)
{
$this->load->library('pagination');
$config = array(
'base_url' => $base_url,
'total_rows' => $this->hitung_semua(),
'per_page' => $this->per_halaman,
'num_links' => 4,
'use_page_number' => TRUE,
'first link' => '|< First',
'last link' => 'Last >|',
'next link' => 'Next >',
'prev_link' => '< Prev',
);
$this->pagination->initialize($config);
return $this->pagination->create_links();
}
public function hitung_semua()
{
return $this->db->count_all($this->db_tabel);
}
private function load_form_rules_tambah()
{
$form = array(
array(
'field' => 'NO_PENGUJIAN',
'label' => 'no pengujian',
'rules' => 'required'
),
array(
'field' => 'ID_KENDARAAN',
'label' => 'id kendaraan',
'rules' => 'required'
),
array(
'field' => 'NO_KENDARAAN',
'label' => 'no kendaraan',
'rules' => 'required'
),
array(
'field' => 'LAMPU',
'label' => 'lampu',
'rules' => 'required'
),
);
return $form;
}
public function validasi_tambah()
{
$form = $this->load_form_rules_tambah();
$this->form_validation->set_rules($form);
if($this->form_validation->run())
{
return TRUE;
}
else
{
return FALSE;
}
}
public function tambah()
{
$pengujian = array(
'NO_PENGUJIAN' => $this->input->post('NO_PENGUJIAN'),
'ID_KENDARAAN' => $this->input->post('ID_KENDARAAN'),
'NO_KENDARAAN' => $this->input->post('NO_KENDARAAN'),
'LAMPU' => $this->input->post('lampu[]'),
//'EMISI' => $this->input->post('EMISI'),
//'REM' => $this->input->post('REM')
);
$lulus = $_POST["lulus"];
//$statement = "INSERT INTO pengujian VALUES($lulus)"
$this->db->insert($this->db_tabel, $pengujian);
if($this->db->affected_rows() > 0)
{
return TRUE;
}
else
{
return FALSE;
}
}
I got no trouble in the formfield. The trouble is the radio button "lampu"
The best thing to do, I think, is to check where it's going wrong. I usually do this, in this case, by checking if the value is being passed back to the controller and model. This way you understand better what's going on inside your code. Do something like this:
In the model:
public function tambah()
{
// Check to see if we get a value. If not, do the same in the controller
var_dump($this->input->post('lampu'));
exit;
$pengujian = array(
'NO_PENGUJIAN' => $this->input->post('NO_PENGUJIAN'),
'ID_KENDARAAN' => $this->input->post('ID_KENDARAAN'),
'NO_KENDARAAN' => $this->input->post('NO_KENDARAAN'),
'LAMPU' => $this->input->post('lampu[]'),
//'EMISI' => $this->input->post('EMISI'),
//'REM' => $this->input->post('REM')
);
$lulus = $_POST["lulus"];
//$statement = "INSERT INTO pengujian VALUES($lulus)"
$this->db->insert($this->db_tabel, $pengujian);
if($this->db->affected_rows() > 0)
{
return TRUE;
}
else
{
return FALSE;
}
}
I hope this helps a bit....
Here is my validation rule in User.php
public $validate = array(
'username' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'User name is required'
),
'alphaNumeric'=>array(
'rule' => 'alphaNumeric',
'required' => true,
'message' => 'Alphabets and numbers only'
)
))
and this is my view page code
<?php
echo $this->Form->create('User');
echo $this->Form->input('username', array('label' => 'Username'));
echo $this->Form->input('email', array('label' => 'Email'));
echo $this->Form->input('password', array('label' => 'Password'));
echo $this->Form->submit('Sign Up');
echo $this->Form->end();
?>
Here is my controller code
public function register() {
$this->layout = 'starter';
//debug($this->validationErrors);
if ($this->request->is('post')) {
if ($this->User->validates()) {
$this->User->save($this->request->data);
$this->Session->setFlash(__('Please login your account'));
$this->redirect('/users/login');
} else {
$this->Session->setFlash(__('The user could not be saved. Please, try again.'));
}
}
}
but validation message is not showing. What is wrong in my code?...
Your code is wrong.
if ($this->request->is('post')) {
if ($this->User->validates()) {
$this->User->save($this->request->data);
this is not how it could ever work as the data is not passed prior to validation.
You need to first pass the data, then validate, then optionally save (or save and validate together):
if ($this->request->is('post')) {
if ($this->User->save($this->request->data)) {}
or, careful not to retrigger validation twice:
if ($this->request->is('post')) {
$this->User->set($this->request->data);
if ($this->User->validates()) {
$success = $this->User->save(null, array('validate' => false));
But that is documented.
The latter only makes sense if you really need to do this in two steps.
In your comment you have written you have changed layout page.It may you miss
<?php echo $this->Session->flash(); ?>
this line.Add this line in your view/layouts/yourlayout.ctp file.
Disable HTML5 required in your view page code
<?php
echo $this->Form->create('User');
echo $this->Form->input('username', array('label' => 'Username','required'=>'false'));
echo $this->Form->input('email', array('label' => 'Email','required'=>'false'));
echo $this->Form->input('password', array('label' => 'Password','required'=>'false'));
echo $this->Form->submit('Sign Up');
echo $this->Form->end();
?>
Controller created for UserController.php
public function myappointment() {
$this->loadmodel('event');
if ($this->request->is('post')) {
$this->Event->create();
if ($this->Event->save($this->request->data)) {
$this->Session->setFlash(__('Your appointment has been saved.'));
} else {
$this->Session->setFlash(__('Unable to add your appointment.'));
}
}
}
model name for event
event.php
class Event extends UserMgmtAppModel {
}
appointment form code in view
<?php
$this->Form->create('Event');
echo $this->Form->input("title" ,array('label' => false ));
echo $this->Form->input("from", array('label' =>false, 'type' => 'text', 'class' => 'fl tal vat w300p', 'error' => false , 'id' => 'select_date'));
echo $this->Html->div('datepicker_img w100p fl pl460p pa', $this->Html->image('calendar.png'),array('id' => 'datepicker_img')); ?>
<?php echo $this->Html->div('datepicker fl pl460p pa', ' ' ,array('id' => 'datepicker'));
echo 'End time';
echo $this->Form->input("to", array('label' =>false, 'type' => 'text', 'class' => 'fl tal vat w300p', 'error' => false , 'id' => 'select_date1'));
echo $this->Html->div('datepicker_img1 w100p fl pl460p pa', $this->Html->image('calendar.png'),array('id' => 'datepicker_img1')); ?>
<?php echo $this->Html->div('datepicker1 fl pl460p pa', ' ' ,array('id' => 'datepicker1'));
echo $this->Form->end('Create appointment');
Try this in your model.
App::uses('UserMgmtAppModel', 'Event.Model');
class Event extends UserMgmtAppModel {
}
Your controller action
public function myappointment() {
$this->loadmodel('Event');
if ($this->request->is('post')) {
$this->Event->create();
if ($this->Event->save($this->request->data)) {
$this->Session->setFlash(__('Your appointment has been saved.'));
} else {
$this->Session->setFlash(__('Unable to add your appointment.'));
}
}
}
I'm tying to figure out how to save, for example 4 days of schedule in one view, and have each field validation message show if validation fails.
My approach was at first to use $this->SomeModel->saveAll() but couldn't save so I tried another way using foreach and all data is saved (pass validation) but no validation message is shown. if you guys know better way to do this I'm open for any suggestions.
Model
public $validate = array(
'hour_from'=>array(
'some mgs' => array(
'rule' => 'good_hours',
),
),
);
public function good_hours($data) {
//throw new Exception(($data['hour_from'] >= $this->data['Hour']['hour_to']));
if ($data['hour_from'] >= $this->data['Hour']['hour_to']) {
return false;
}
return true;
}
Controller:
if ($this->request->is('post')) {
$all_good = true;
foreach ($this->request->data['Hour'] as $day){
if ($this->Hour->save($day)){
}else {
$all_good = false;
$this->Session->setFlash('hours not saved');
}
}
//if all saves are correct rediredt to index
if ($all_good) {
$this->Session->setFlash(__('Hours saved'));
return $this->redirect(array('action' => 'index'));
}
}
View
foreach ($days as $count => $day):
$form_model ='Hour.'.$count. '.';
?>
<fieldset>
<legend><?php
$day_array = (array) $day;
$day = $day_array['date'];
echo $day;
?></legend>
<?php
echo $this->Form->input($form_model.'type_holiday_id', array(
'label'=> 'Typ urlopu',
'type' => 'select',
'options' => $type_holidays,
'empty' => true
));
echo $this->Form->input($form_model.'hour_from', array('label' => 'od'));
echo $this->Form->input($form_model.'hour_to', array('label' => 'do'));
echo $this->Form->input($form_model.'date', array('type' => 'hidden', 'value' => $day));
echo $this->Form->input($form_model.'subordinate_id', array('type' => 'hidden', 'value' => $user['User']['id']));
echo $this->Form->input($form_model.'supervisor_id', array('type' => 'hidden', 'value' => $current_user['id']));
?>
</fieldset>
Request->data array
Hour(array)
0(array)
type_holiday_id
hour_from 8
hour_to 15
date 2014-01-20
subordinate_id 193
supervisor_id 557
1(array)
type_holiday_id
hour_from 7
hour_to 14
date 2014-01-21
subordinate_id 193
supervisor_id 557
Ok i found solution, and everything works perfectly now in controller i needed to change save to saveAll, function add in Controller should look like this:
if ($this->request->is('post')) {
if ($this->Hour->saveAll($this->request->data['Hour'], Array('validate' => 'first', 'deep' => true))){ <--- most important is that data['Hour']
$this->Session->setFlash(__('Godziny robocze zapisane'));
return $this->redirect(array('action' => 'index'));
} else{
$this->Session->setFlash('Godziny robocze nie zostaĆy zapisane.');
}
}