Structuring controllers to submit a form in Codeigniter 3 - php

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'));
}

Related

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();

CodeIgniter form validation not working properly

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.

kohana form validation

There is a 'main.php' view that contains a form with email and name fields and a submit button. Eveyrthing works fine with action_index (the code is below), but I'm curious how to modify the code below so it validates if the email was entered correctly. It should not put values in the database if the email field is not valid. I hope it is possible to made using ->rule. Is it? If yes, then how where to add the validation? (I had no luck trying it in different ways).
public function action_index()
{
if ( !empty($_POST) ) {
$model = ORM::factory('tbl1'); // create
$model->values($_POST); // load values to model
if ($model->check()) {
$model->save(); // save the model
} else {
//show errors
}
}
$this->response->body(View::factory('main'));
}
Thank you.
Use rules function in your ORM model:
public function rules()
{
return array(
'email' => array(
array('email', array(':value')),
),
);
}

How to submit a post-method form to same get-url in different function in CodeIgniter?

I found CodeIgniter form validation to show error message with load->view method, and will lost field error message if use "redirect".
Currently I use one function to show form page, and another function to deal form post.
class Users extends CI_Controller {
function __construct() {
parent::__construct();
}
public function sign_up()
{
$this->load->view('users/sign_up');
}
public function do_sign_up(){
$this->form_validation->set_rules('user_login', 'User Name', 'trim|required|is_unique[users.login]');
$this->form_validation->set_rules('user_email', 'Email', 'trim|required|valid_email|is_unique[users.email]');
if ($this->form_validation->run() == FALSE) {
$this->load->view('users/sign_up');
}else {
// save post user data to users table
redirect_to("users/sign_in");
}
When form validation failed, url in browser will changed to "/users/do_sign_up", I want to keep same url in sign_up page.
Use redirect("users/sign_up") method in form validation failed will keep same url, but validation error message will lost.
in Rails, I cant use routes to config like this:
get "users/sign_up" => "users#signup"
post "users/sign_up" => "users#do_signup"
imho it's not necessary to check the request method because if the user 'GET' to the page you want to show the sign up view... if they user 'POST' to the page and fails validation you ALSO want to show the sign up view. You only won't want to show the sign up view when the user 'POST' to the page and passes validation.
imho here's the most elegant way to do it in CodeIgniter:
public function sign_up()
{
// Setup form validation
$this->form_validation->set_rules(array(
//...do stuff...
));
// Run form validation
if ($this->form_validation->run())
{
//...do stuff...
redirect('');
}
// Load view
$this->load->view('sign_up');
}
Btw this is what im doing inside my config/routes.php to make my CI become RoR-like. Remember that your routes.php is just a normal php file so u can put a switch to generate different routes depending on the request method.
switch ($_SERVER['REQUEST_METHOD'])
{
case 'GET':
$route['users/sign_up'] = "users/signup";
break;
case 'POST':
$route['users/sign_up'] = "users/do_signup";
break;
}
Here is my approach in CodeIgniter 4. I think you only need one method to complete the task.
In your app/Config/Routes.php
/*
* --------------------------------------------------------------------
* Route For Sign up page
* --------------------------------------------------------------------
*/
$routes->match(['get','post'], 'signup', 'Users::Signup');
In your app/Views/signup.php
<?php print form_open('/signup', ['method' => 'POST']);?>
<!--All other inputs go here, for example-->
<input type="text" name="firstname">
<?php print form_close();?>
In your app/Controllers/Users.php
namespace App\Controllers
use App\Controllers\BaseController;
class Users extends BaseController
{
public function Signup(){
helper(['form', 'url']);
//run validations here
if ($this->request->getMethod() === 'post' && $this->validate([
'firstname' => [
'label' => 'Firstname',
'rules' => 'required|alpha_space',
'errors' => [
'required' =>'Please enter your <strong>Firstname</strong> e.g.John',
'alpha_space' => 'Only alphabetic characters or spaces for <strong>Firstname</strong> field'
]
],
])){
//do other stuff here such as save data to database
$first_name=$this->request->getPost('firstname');
//if all go well here you can redirect to a favorite page
//e.g /success page
return redirect()->to('/success');
}
//if is get or post
print view('signup');
}
}
<button type="submit"class="md-btn btn-sm md-fab m-b-sm indigo" id="filterbtn" formaction="<?php echo base_url(); ?>front/get_filter/<?php echo$device_id;?>"><i class="fa fa-bar-chart"></i></button>
<button type="submit"class="md-btn btn-sm md-fab m-b-sm indigo" id="filterbtn" formaction="<?php echo base_url(); ?>front/get_data/<?php echo$device_id;?>"><i class="fa fa-th-list"></i></button>

Symfony submit to same url

I have a form with some text fields and I have a preview button that needs to submit the form to the same controller. And then in the controller, I need to extract the values and populate a form with these values for the template to see. What is the best way to achieve this? I'm a newbe so please be clear.
Sample controller:
public function myControllerName(sfWebRequest $request)
{
$this->form = new myFormClass();
}
Use <?php echo $form->renderFormTag( url_for('#yourRoutingName'), array('method' => 'POST') ); ?> in your template and change #yourRoutingName to the one pointing to your controller.
Now change your controller to be something like this:
public function myControllerName(sfWebRequest $request)
{
$this->form = new myFormClass();
if ($request->isMethod(sfRequest::POST)
{
$this->form->bind( $request->getParameter( $this->form->getName() ) );
// Check if the form is valid.
if ($this->form->isValid())
{
$this->form->save();
// More logic here.
}
}
}
The $this->form->bind( $request->getParameter( $this->form->getName() ) ); part binds posted data to your form where $this->form->isValid() returns a boolean whether the form is valid or not.
Have you tried this ?
$this->redirect($request->getReferer()); //action
if not, then please try and check if its work for you.
Thanks.

Categories