CodeIgniter form validation not working properly - php

I have a form set up in a controller that both loads the form and its previously populated contents from a database and processes the form as needed. The problem is $this->form_validation->run() never evaluates to FALSE, even if rules are not met.
Controller:
public function edit_version($node, $lang)
{
// load form validation class
$this->load->library('form_validation');
// set validation rules
$this->form_validation->set_rules("title|Title|required");
// run validation
if ($this->form_validation->run() !== FALSE)
{
// save input to database
die("validation successful");
}
else
{
// either validation was not passed or no data to validate
// load page edition view and display databse contents
// load page model
$this->load->model("page_model");
// get the page from database
$data["page"] = $this->page_model->get_page($node, $lang);
// load views
$this->load->view("admin/header.php", array("title" => "Edit page no.: $node, $lang version - Admin"));
$this->load->view("admin/pages/edit_page.php", $data);
$this->load->view("admin/footer.php");
}
}
Model:
class Page_model extends CI_Model
{
public function get_page($node, $lang)
{
// load the page
return $this->db->get_where("pages", array("node" => $node, "lang" => $lang))->row();
}
public function save_version($page)
{
$this->db->where("node", $page["node"]);
$this->db->where("lang", $page["lang"]);
$this->db->update("pages", $page);
}
public function search($query)
{
return $this->db->get_where("pages", $query)->result();
}
}
View:
<h2>Edit page</h2>
<?php
// load form helper
$this->load->helper("form");
// open a form
echo form_open("admin/page/{$page->node}/edit/{$page->lang}");
// print validation errors
echo validation_errors();
// title and content fields
echo form_label("Title: ", "title");
echo form_input("title", set_value("title", $page->title));
// aesthetic line break
echo "<br>";
echo form_label("Content: ", "content") . "<br>";
echo form_textarea("content", set_value("content", $page->content));
// save button and close form
echo form_submit("submit", "Save page");
echo form_close();
Thanks in advance.

syntax for setting rule is
$this->form_validation->set_rules('field_name', 'Label', 'rule1|rule2|rule3');
by considering rules your set rule line will be
$this->form_validation->set_rules('title','Title', 'required");

I'm not a CodeIgniter seasoned dev but from documentation is the proper syntax not the following?
$this->form_validation->set_rules("title","Title","required");
As per this link:
http://ellislab.com/codeigniter/user-guide/libraries/form_validation.html#validationrules

Use
$this->form_validation->set_rules("title","Title","required");
instead of this
$this->form_validation->set_rules('title','Title','required');
I have tested this. It works like a Charm.

Related

Codeigniter form_open() load View file twice when passing variable from Controller to View

My Controller is something along the line of
public function create_room($id_1, $id_2) {
$data['id_1'] = $id_1;
$data['id_2'] = $id_2;
$data['query'] = $this->model->get_all();
$this->load->view('viewFilePath', $data);
$this->form_validation->set_rules // set the rules
if ($this->form_validation->run() === FALSE) {
$this->load->view('viewFilePath');
$this->session->set_flashdata('error', "errorMessage");
} else { (do the query)
}
My View
<?php echo form_open('theURL'.$id_1.'/'.$id_2.'/URLEnding');?>
The view is loading twice, most likely because I load the view once in both files.
Basically I want to:
Pass $id_1 and $id_2 from the opening URL to Controller function as parameters;
Query in Controller using $id_1 and $id_2;
Pass the query data to View.
Is there a way to achieve this without loading the view twice?
Update: I've tried these:
Removing load->view from create_room() (no $data passing from view to controller)
you can create another function store and move the following code to the new function. because this code will run when you submit the form. and in form open use the store function instead of the create form
$this->form_validation->set_rules // set the rules
if ($this->form_validation->run() === FALSE) {
$this->load->view('viewFilePath');
$this->session->set_flashdata('error', "errorMessage");
} else { (etc)
please change your code because view call two time so if you remove one call and other is move your second call in else part.
$data['id_2'] = $id_2;
$data['query'] = $this->model->get_all();
$this->form_validation->set_rules // set the rules
if ($this->form_validation->run() === FALSE) {
$this->load->view('viewFilePath');
$this->session->set_flashdata('error', "errorMessage");
} else {
$this->load->view('viewFilePath', $data);
(etc)

Structuring controllers to submit a form in Codeigniter 3

I'm learning Codeigniter and I have a controller named Admin controller
class Admin extends CI_Controller{
/* skipped */
//This function is used to generate changepassword form
public function changepassword(){
$this->data['sessiondata'] = $_SESSION['logged_in'];
$this->data['mainview'] = 'components/admin/changepassword';
$this->load->view($this->layout, $this->data);
}
//changepassword form will be submitted to this function ('admin/checkpassword')
public function checkpassword(){
$error = array(
'required' => '%s tidak boleh kosong',
'matches' => '%s tidak sama, dumb ass'
);
/* some validations skipped */
if($this->form_validation->run($this) == FALSE){
$this->data['mainview'] = 'components/admin/changepassword';
$this->load->view($this->layout, $this->data);
} else {
$tobesent = array(
"oldpassword" => $this->input->post('oldpassword'),
"newpassword" => $this->input->post('newpassword'),
"verifynewpasswprd" => $this->input->post('verifynewpassword')
);
$this->admincrud->changepassword($tobesent);
$this->data['result'] = "Password sukses diubah";
$this->data['mainview'] = 'components/admin/changepassword';
$this->load->view($this->layout, $this->data);
}
}
}
the result is, each time I go to base_url('admin/changepassword'), fill the provided form and then submit the form, my url changes from base_url('admin/changepassword') into base_url('admin/checkpassword'), which I know came as the result of submitting the form. Also each time I type base_url('admin/checkpassword') directly on my address bar, it opens the form, which I know came as the result of the if-else condition in checkpassword function. My question is, from the security standpoint, is it okay if I keep using this structure? and how can I prevent users from directly accessing base-url('admin/checkpassword') and instead redirecting them to base_url('admin/changepassword') ?
well if you don't want the URL to be changed after submitting the form.
You can use redirect('admin/changepassword'); and since you need to provide
messages accordingly, you can use $this->session->set_flashdata('msg','Your message'); before redirection and use it in view like this:
<?php if($this->session->flashdata('msg') <> NULL){echo $this->session->flashdata('msg');} ?>
Solution to your problem is $_SERVER['REQUEST_METHOD'] if i understood correctly...
For example :-
if($_SERVER['REQUEST_METHOD'] == 'POST')//form method is post
{
//checkpassword code
}
else
{
redirect(base_url('admin/changepassword'));
}

Yii calling controller function from another controller

In my web application the work flow demands that I should call one controller function from another function
Should I do add extra code or some configuration to proceed ? Right now This is how I implemented .But When I click "save" button nothing is happening values are just getting empty from the form .
My code .I want to create an object of model "BookVegetable" inside "ProducerOfferController" .
My code inside producerOffer controller
public function actionCreate()
{
//$book_vegetable=new BookVegetable;
$model=new BookVegetable;
if(isset($_POST['BookVegetable']))
{
$model->attributes=$_POST['BookVegetable'];
$model->booked_by = Yii::app()->user->id;
$model->save();
if ($model->hasErrors() === false)
{
$this->redirect(Yii::app()->user->returnUrl);
}
}
else
{
Yii::app()->user->setReturnUrl($_GET['returnUrl']);
}
$this->render('book',array('model'=>$model,));
}
My code for from view
<div style='padding-left:50px'>
<?php $form=$this->beginWidget('bootstrap.widgets.TbActiveForm',array('id'=>'non-ajax_form','enableAjaxValidation'=>false,)); ?>
<p class="help-block">Fields with <span class="required">*</span> are required.</p>
<?php echo $form->errorSummary($model); ?>
<?php echo "<br>" ?>
<?php echo CHtml::textField("booked_quantity",$model->booked_quantity); ?>
My scenario
public function actionBookvegetable($id){
$BookVegetable=new BookVegetable;
$model=$this->loadModel($id);
if(isset($_POST['ProducerOffer'],$_POST['BookVegetable']))
{
$model->attributes=$_POST['ProducerOffer'];
$BookVegetable->attributes=$_POST['BookVegetable'];
$BookVegetable->booked_by=Yii::app()->user->id;
$BookVegetable->producer_offer_id=$model->id;
$model->save();
$BookVegetable->save();
if (($model->hasErrors() === false)||($BookVegetable->hasErrors()=== false))
{
$this->redirect(Yii::app()->user->returnUrl);
}
}
else
{
Yii::app()->user->setReturnUrl($_GET['returnUrl']);
}
$this->render('book',array('model'=>$model,'BookVegetable'=>$BookVegetable));
}
<div class="form-actions">
<?php $this->widget('bootstrap.widgets.TbButton', array('buttonType'=>'submit', 'type'=>'primary', 'label'=> 'Save',)); ?>
How should I resolve this ? Is it essential to add anything extra to use one controller action inside another controller
The url before saving and its the same after I press save also
http://localhost/xxx/producerOffer/bookvegetable/20?returnUrl=%xxx%2FproducerOffer%2Fmanage
One way to do this in Yii2
Background
In SiteController action index method get the records of all objects from another model called voyzes.
In SiteController
Include the other model ex. Voyzes
Now in the SiteController action index method, implement the code to access the model/SQL/NoSQL or anything and set it in a array and return it to the view. For ex.
Now in the index view you should have your data from another model.
According to your information provided.. when you go here,
http://xxx.yyy.zzz/xxxx/producerOffer/create
Actually it should show you the form of book and when you click the save button there and go to returnUrl.
$this->redirect(Yii::app()->user->returnUrl);
I suggest you to write the following as,
$model->save();
$BookVegetable->save();
if (($model->hasErrors() === false)||($BookVegetable->hasErrors()=== false))
{
$this->redirect(Yii::app()->user->returnUrl);
}
To
if($model->save() && $BookVegetable->save())
$this->redirect('yourAction'); //if params needed, $this->redirect(array('yourAction', 'id' => $model->id));
When you go here, http://xxx.yyy.zzz/xxxx/producerOffer/bookvegetable
What ever the code you have written under ActionBookvegetable will trigger.
To make sure your values submitted properly please change this code
$model->save();
if ($model->hasErrors() === false)
{
$this->redirect(Yii::app()->user->returnUrl);
}
To
if($model->save())
$this->redirect('yourAction');
else
print_r(getErrors());
This will print any errors thats preventing from saving the model. let me know after you try this.
In my work , I have a lot of logic around the "loadModel" routine in controllers to make sure the user logged in has access to the particular model. I found this to work from another controller when I need to access the model, without moving or re-copying the loadmodel routine:
$caseviewController = Yii::app()->createController('Caseview');
//use this method from caseview controller to securley load case view model
$caseview = $caseviewController[0]->loadModel($caseviewid);

Yii - updating a model and using the model to echo data in the view

I have the following code for updating a Yii model:
public function actionSettings($id) {
if (!isset($_POST['save_hostname']) && isset($_POST['Camera']) && isset($_POST['Camera']['hostname'])) {
$_POST['Camera']['hostname'] = '';
}
$model = $this->loadModel($id);
$model->setScenario('frontend');
$this->performAjaxValidation($model);
if (isset($_POST['Camera'])) {
$model->attributes = $_POST['Camera'];
unset($model->api_password);
if ($model->save()) {
Yii::app()->user->setFlash('success', "Camera settings has been saved!");
} else {
Yii::app()->user->setFlash('error', "Unable to save camera settings!");
}
}
$this->render('settings', array(
'model' => $model,
));
}
This works fine, except in my model I have code like this:
<h1>Settings For: <?php echo CHtml::encode($model->name); ?></h1>
The problem is that, even when the user input fails validation, the h1 tag is having bad input echoed out into it. If the input fails the validation, the h1 attribute should stay the same.
I can 'reset' the $model variable to what is in the database before the view is returned, but this then means I don't get any error feedback / validation failed messages.
Is my only option to have 2 $models ($model and $data perhaps), one used for handling the form and the other for sending data to the page? Or does someone have a more elegant solution?
performAjaxValidation assigns all save attributes to the model so this behavior is normal.
I would reload model if save fails.
$model->refresh();

Yii Framework: Undefined variable model when checking if guest

We have a actionSearchType in our User Controller as follows:
public function actionSearchType()
{
if (Yii::app()->user->isGuest == true)
$this->render('login');
else
$this->render('search_type');
}
Our actionLogin in our User Controller is as follows:
public function actionLogin()
{
$model= new Users();
// if it is ajax validation request
if(isset($_POST['ajax']))
{
echo CActiveForm::validate($model);
Yii::app()->end();
}
$this->redirect(Yii::app()->user->returnUrl);
}
}
// display the login form
$this->render('login',array('model'=>$model));
}
The goal is to ensure that only authenticated users can execute the options on the search type view. When I run this page, I receive an error stating Undefined variable: model.
A snippet of the login view is as follows:
<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'login-form',
'enableClientValidation'=>true,
'clientOptions'=>array(
'validateOnSubmit'=>true,
),
)); ?>
<p class="note">Fields with <span class="required">*</span> are required.</p>
<div class="row">
<?php echo $form->labelEx($model,'username'); ?>
<?php echo $form->textField($model,'username'); ?>
<?php echo $form->error($model,'username'); ?>
</div>
What steps must be taken to remedy the above error and properly check to ensure we have an authenticated user?
update
I changed actionSearchType to render the Login Widget per below:
public function actionSearchType()
{
if (Yii::app()->user->isGuest)
$this->widget('ext.LoginWidget');
else
$this->render('search_type');
}
This indeed resolved the error initially seen. A new problem is that there's no styling of the login widget when it renders. Should I echo my tags with appropriate stylesheet classes, or is there a bit more elegant way of doing that?
public function actionSearchType() {
if (Yii::app()->user->isGuest)
$this->redirect('/user/login');
$this->render('search_type');
}
Notes:
to do something when user is guest, simply use if(Yii::app()->user->isGuest) { statement }
to do something when user is logged in, simply use if(!Yii::app()->user->isGuest) { statement }
in the second code, public function actionLogin(), I think you have 2 more closing curly brackets than needed. Anyway, the login action should look like this:
public function actionLogin() {
$formModel = new Login_Form; // Login_Form.php should be in models folder
if (isset($_POST['Login_Form'])) {
$formModel->attributes = $_POST['Login_Form'];
if ($formModel->validate() && $formModel->login()) {
$this->redirect('/'); // replace / with stuff like Yii::app()->user->returnUrl
}
}
$this->render('login', array(
'formModel'=>$formModel,
));
}
Instead of rendering the view redirect to the user login page / action so you don't have to recreate it.
$this->redirect('login');
Somewhere in search_type you are referencing the variable $model which you do not hand over to the render() function. You need to define that variable otherwise the view will create an Exception.
I don't know which Model/Class your search_type view is expecting but you will need to initialize it before you hand it over to the view like this:
$this->render('search_type',array(
'model' => $model,
));
Here a good read about this topic: Understanding the view rendering flow

Categories