I have a weird bug.
Form validation is doing both TRUE and FALSE actions.
For TRUE, the database model (scrape_url_model) runs so the database is updated, but then the views are run as though form validation is FALSE.
The FALSE view (scrape_url/index) is shown instead of the view associated with a successful validation (scrape_url/form_success).
I'm getting the validation error message The URL is already in the database from the callback function.
public function index(){
$this->load->helper('form');
$this->load->library('form_validation');
$this->form_validation->set_error_delimiters('', '');
$data['pageTitle'] = 'URL Scraping Tool';
$this->form_validation->set_rules('event_url', 'URL', 'trim|required|callback_url_check');
if ($this->form_validation->run() == FALSE){
$this->load->view('templates/header', $data);
$this->load->view('scrape_url/index', $data);
$this->load->view('templates/footer');
}
else {
$this->load->library('Db_queries');
$this->load->library('session');
$this->load->helper('url');
list($session_data['alert'],
$session_data['alert_type'],
$session_data['countUncategorizedDecks'],
$session_data['event_id'],
$session_data['eventDate']) = $this->scrape_url_model->insert_decks_and_cards();
if ($this->input->post('last_url') == 'yes'){
$this->scrape_url_model->insert_md_percentage($session_data['eventDate']);
}
$this->session->set_userdata($session_data);
$this->load->view('templates/header', $data);
$this->load->view('scrape_url/form_success', $data);
$this->load->view('templates/footer_ajax');
}
}
public function url_check($event_url) {
$url_regex = "/^(http|https|ftp):\/\/([A-Z0-9][A-Z0-9_-]*(?:\.[A-Z0-9][A-Z0-9_-]*)+):?(\d+)?\/?/i";
if (preg_match($url_regex, $event_url) == FALSE) {
// check to see if input is a URL
$this->form_validation->set_message('url_check', 'Please enter a URL including "http://".');
return FALSE;
}
$this->load->database();
$sql = 'SELECT url FROM event';
$s = $this->db->conn_id->query($sql);
$used_urls = $s->fetchAll(PDO::FETCH_COLUMN, 0);
if (in_array($event_url, $used_urls)){
$this->form_validation->set_message('url_check', 'The URL is already in the database.');
return FALSE;
}
return TRUE;
}
Try using statement:
$this->form_validation->run() == true
and then code your conditions accordingly. It will work and will also easy to understand.
Related
I'm getting error when login to my project and then goto the base url. The below is the error which i get
My Login page [ see the url ]
After logging in , if i remove the highlighted segments[pls see below image] after which i get the above error
I know these error are due to headers so can somebody help me in saying what error am i making in header. An also say how to make good use of session so that the form is to resubmitted when i refresh after logging in. Below are the header codes.
login header
<?php if(isset($this->session->userdata['logged'])){
header("location: http://localhost/capacity_planner/login/login_check");
}
?>
admin dashboard[after logging in header]
<?php if(isset($this->session->userdata['logged'])){
$email = ($this->session->userdata['logged']['email']);
}else{
header("location: http://localhost/capacity_planner/login");
}
?>
controller side
public function login_check(){
$data['base_url'] = base_url();
$this->form_validation->set_rules('email', 'Email', 'trim|required|xss_clean');
$this->form_validation->set_rules('password', 'Password', 'trim|required|xss_clean|callback_check_database');
if ($this->form_validation->run($this) == false) {
$this->index();
} else {
if(isset($this->session->userdata['logged'])) {
$data['login_bg'] = $this->input->post('login_bg');
$this->load->view("admin_db", $data);
}
}
function check_database($password){
$email= $this->input->post('email');
$user = $this->user->loginCheck($email, $password);
if($user[1] == 1){
$result = $this->user->user_details($email);
if($result != false) {
$session_data = array(
'id' => $result[0]->id,
'email' => $result[0]->cp_email,
);
$this->session->set_userdata('logged', $session_data);
return true;
}
} else{
$this->form_validation->set_message('check_database', $user[0]);
return false;
}
}
ERR_TOO_MANY_REDIRECTS is caused when strucked up in a conditional loop
I assume you want to redirect to admin dashboard if you go to index after logged in..
Try adding these lines in your public function index()
public function index(){
if(isset($this->session->userdata['logged'])) {
//admin_db display function eg.redirect('admindashboard');
}
else{
//load your index view
this->load->view('your_index_view');
}
}
or you can check reverse way in admin dashboard function like this
public function dashboard(){
if($this->session->userdata('logged') == ''){
redirect('index');
}
else{
$this->load->view('dashboard view');
}
}
This is my assumption.Kindly check it.
Here Is My COde I m checking username is already exist or not in datbase
when i validate and submit the form duplicate entry entered in database i want that if already exist it show validation error
My Controller
public function index()
{
if($this->input->post('submit')) {
$this->form_validation->set_rules('name', 'User Name', 'callback_checkuser');
$this->form_validation->set_rules('role', 'Role', 'trim|required');
$this->form_validation->set_rules('pass', 'Password', 'trim|required');
if($this->form_validation->run()==TRUE)
{
$user['u_name'] = $this->input->post('name');
$user['role'] = $this->input->post('role');
$user['password']= md5($this->input->post('pass'));
$u_id = $this->custom_model->add_user($user);
if($u_id){
$data['msg'] = 'Successfully Created!!!!';
}
}
}
$this->load->template('add_user', $data);
}
function checkuser($name) {
if($this->custom_model->check_name($name) == false) {
false;
}else {
$this->form_validation->set_message('checkuser', 'This user already exist');
return true;
}
}
Here is My Model
public function check_name($name) {
$sql = "SELECT * FROM users WHERE u_name='".$name."' ";
$query = $this->db->query($sql);
$res = $query->row_array();
if (is_array($res) && count($res) > 0){
return $res;
}
return false;
}
There is a return statement missing in the function checkuser, but more importantly, you should invert the value you return. According to the example in the docs, when you set a validation message because of a validation error, you should return false, and return true when the validation passes.
So add a return, and change the boolean values. BTW, you don't really need an else clause and the word "exist" needs an additional "s":
function checkuser($name) {
if ($this->custom_model->check_name($name) == false) {
return true; // the user does not yet exist, so all is OK
}
$this->form_validation->set_message('checkuser', 'This user already exists');
return false; // this is a duplicate user name: not OK
}
Use this:
$this->form_validation->set_rules('name', 'User Name', 'trim|required|is_unique[users.u_name]');// trim and required added too
Docs.
I am pretty knew to code igniter / OOP but I am giving it a shot and a little stumped at this point.
I have 2 functions. One is the search which loads data from a model. The other is the save function.
My issue is, when running save() I am getting errors because its trying ti display the validation errors but we no longer have the data from the database that we got from the search() function.
I feel that it would be redundant to include all the details form the search back into this save function which is why I think I am doing something wrong.
public function search()
{
// Define some vars
$data['title'] = 'Submit Attrition';
$data['js_file'] = 'submit.js';
// Load our helper
$this->load->helper('form');
// Get the user and pass it to the model
$empQID = $this->input->post('empQID');
$data['userDetails'] = $this->submit_model->get_details($empQID);
$data['languages'] = $this->submit_model->get_languages();
$data['types'] = $this->submit_model->get_types();
$data['ratings'] = $this->submit_model->get_ratings();
$data['processes'] = $this->submit_model->get_processes();
// Send the data to the views
$this->load->view('templates/header', $data);
$this->load->view('submit/search', $data);
$this->load->view('templates/footer', $data);
}
/**
* Validate & save attrition submission
*
* #author Carl
* #return void
*/
public function save()
{
$data['title'] = 'Submit Attrition';
$this->load->library('form_validation');
$this->form_validation->set_rules('language', 'Supporting Language', 'required');
// Validation failed, show form w/ validation errors
if ($this->form_validation->run() === FALSE)
{
$this->load->view('templates/header', $data);
$this->load->view('submit/search', $data);
$this->load->view('templates/footer', $data);
}
else
{
// Success : Send data to model
$this->submit_model->save_attrition();
$this->load->view('templates/header', $data);
$this->load->view('submit/success', $data);
$this->load->view('templates/footer', $data);
}
}
I'm not sure I entirely understand your question, but I think I understand what you're trying to do. In CodeIgniter, you do something like this:
class MyController
{
// this controller action will load whether the form is submitted or not
// $user_id is set by the router
public function save($username)
{
// if the users not in the database, throw a 404 error
$user = $this->db->get_where('users', ['username' => $username]);
if(!$user) {
return show_404();
}
// if it's not a post request, then the form hasn't been submitted
// so don't bother validating it
if($router->fetch_method() === 'POST' && $form_validation->run() === TRUE)
{
$user['name'] = $this->input->post('name');
$this->db->update('users', $user);
$this->load->view('success_page');
// return so we don't render the form again
return;
}
// this will happen in all cases, __except__ when the form was submitted
// with valid data
$this->load->view('form');
}
}
I've skipped on details for brevity (like loading the relevant libraries), and because I can't remember all the CI syntax.
Firstly Im new to CodeIgniter and MVC.
I am Creating a CMS and coudln't decide which route to take with do I have two applications (front end/CMS) or just create the admin as a controller. I opted for one application and creating the admin via a Controller.
Doing it this way I have ran into a problem with form validation where if it doesn't validate I cant load the form I have to redirect which then means it wont repopulate the unvalidated fields. I use a variable in the 3rd URI segment to determine whether to display a form for inserting a new record, a populated form for editing a record, or a tabled list of all records.
The form posts to /admin/videos/save
function videos()
{
if (!$this->tank_auth->is_logged_in()) {
redirect('/auth/login/');
} else {
$this->load->model('videos_model');
$data['section'] = "Videos";
$data['area'] = "Videos";
$data['mode'] = $this->uri->segment(3, 'create');
$data['user_id'] = $this->tank_auth->get_user_id();
$data['username'] = $this->tank_auth->get_username();
if ($data['mode'] == 'edit') {
$data['ID'] = $this->uri->segment(4);
$data['videos'] = $this->videos_model->get_videos($data['ID']);
} elseif ($data['mode'] == 'list') {
if ($this->uri->segment(4)) {
$data['filter'] = $this->uri->segment(4);
$data['videos'] = $this->videos_model->get_filtered_videos($data['filter']);
} else {
$data['videos'] = $this->videos_model->get_filtered_videos();
}
} elseif ($data['mode'] == 'save') {
$this->load->helper('form');
$this->load->library('form_validation');
$this->form_validation->set_rules('videoTitle', 'Title', 'required');
$this->form_validation->set_rules('Code', 'Youtube Code', 'required');
if ($this->form_validation->run() === FALSE) {
redirect('/admin/videos');
} else {
$this->videos_model->set_videos();
redirect('/admin/videos/list');
}
}
if ($data['mode'] != "create" && empty($data['videos'])) {
show_404();
}
$this->load->view('admin/templates/head', $data);
$this->load->view('admin/templates/body_navbar', $data);
$this->load->view('admin/videos', $data);
$this->load->view('admin/templates/footer', $data);
}
}
Am I setting about this the wrong way, Should I use two application folders or have 3 controllers for editing/inserting/viewing all. Or is there a solution to my current setup?
I personally haven't used CodeIgniter's form helper nor validation lib, so excuse my ignorance, but is there any particular reason you're not doing this as AJAX post instead?
Am I setting about this the wrong way, Should I use two application
folders or have 3 controllers for editing/inserting/viewing all. Or is
there a solution to my current setup?
Why 3 controllers? You can have a single controller with multiple functions. Honestly, I'd recommend just doing a simple AJAX post on your form and returning some JSON data whether validation passed or not -- no need for redirects.
Something like:
// AJAX
function validateForm() {
$.post('route/to/controller', {"apple": appleValue, "peach": peachValue}, function(data) {
json = $.parseJSON(data);
if (json.success)
alert('Great!');
else
alert('Nope!');
});
//Controller
function validateForm()
{
$data['success'] = ...validation checks...
echo json_encode($data);
}
I have continued to use my one application folder and the entire admin as a controller.
I have solved my form validation and repopulating issue by continuing to redirect back to the form but storing the form fields and errors in a session.
I destroy the error data in the session once viewed but leave the other info intact which allows the user to navigate away and come back and the info will remain. Once the form is validated correctly and information stored in the database it destroys the session data.
function videos()
{
if (!$this->tank_auth->is_logged_in()) {
redirect('/auth/login/');
} else {
$this->load->model('videos_model');
$data['section'] = "Videos";
$data['area'] = "Videos";
$data['mode'] = $this->uri->segment(3, 'create');
$data['user_id'] = $this->tank_auth->get_user_id();
$data['username'] = $this->tank_auth->get_username();
if ($this->session->userdata('videoTitle'))
$data['videoTitle'] = $this->session->userdata('videoTitle');
if ($this->session->userdata('Code'))
$data['Code'] = $this->session->userdata('Code');
if ($this->session->userdata('videoTitle'))
$data['description'] = $this->session->userdata('description');
if ($this->session->userdata('errors')){
$data['errors'] = $this->session->userdata('errors');
$this->session->unset_userdata('errors');
}
if ($data['mode'] == 'edit') {
$data['ID'] = $this->uri->segment(4);
$video_data = $this->videos_model->get_videos($data['ID']);
$data['videoTitle'] = $video_data['videoTitle'];
$data['Code'] = $video_data['blipCode'];
$data['description'] = $video_data['description'];
} elseif ($data['mode'] == 'list') {
if ($this->uri->segment(4)) {
$data['filter'] = $this->uri->segment(4);
$data['videos'] = $this->videos_model->get_filtered_videos($data['filter']);
} else {
$data['videos'] = $this->videos_model->get_filtered_videos();
}
} elseif ($data['mode'] == 'save') {
$this->load->helper('form');
$this->load->library('form_validation');
$this->form_validation->set_rules('videoTitle', 'Title', 'required');
$this->form_validation->set_rules('Code', 'Youtube Code', 'required');
if ($this->form_validation->run() === FALSE) {
$formdata = array(
'videoTitle' => $this->input->post('videoTitle'),
'Code' => $this->input->post('Code'),
'description' => $this->input->post('description'),
'errors' => validation_errors()
);
$this->session->set_userdata($formdata);
redirect('/admin/videos');
} else {
$this->videos_model->set_videos();
$this->session->unset_userdata('videoTitle');
$this->session->unset_userdata('Code');
$this->session->unset_userdata('description');
redirect('/admin/videos/list');
}
}
$this->load->view('admin/templates/head', $data);
$this->load->view('admin/templates/body_navbar', $data);
$this->load->view('admin/videos', $data);
$this->load->view('admin/templates/footer', $data);
}
}
I have a form on my website header where i allow the user to log in with his username/password... then i POST to /signin page and check if the username exists to allow the user to log in.. if there is a problem upon login i output these errors...
i tried using the following code to show a custom error but with no luck
if ($this->form_validation->run() == false){
$this->load->view("login/index", $data);
}else{
$return = $this->_submitLogin();
if ($return == true){
//success
}else{
$this->form_validation->set_message('new_error', 'error goes here');
//error
}
$this->load->view("login/index", $data);
}
how does set_message work and if this is the wrong method, which one allow me to show a custom error in this case?
EDIT :
validation rules:
private $validation_rules = array(
array(
'field' => 'username',
'label' => 'Username',
'rules' => 'trim|required|callback__check_valid_username|min_length[6]|max_length[20]|xss_clean'
),
array(
'field' => 'password',
'label' => 'Password',
'rules' => 'trim|required|min_length[6]|max_length[32]'
),
);
The set_message method allows you to set your own error messages on the fly. But one thing you should notice is that the key name has to match the function name that it corresponds to.
If you need to modify your custom rule, which is _check_valid_username, you can do so by perform set_message within this function:
function _check_valid_username($str)
{
// Your validation code
// ...
// Put this in condition where you want to return FALSE
$this->form_validation->set_message('_check_valid_username', 'Error Message');
//
}
If you want to change the default error message for a specific rule, you can do so by invoking set_message with the first parameter as the rule name and the second parameter as your custom error. E.g., if you want to change the required error :
$this->form_validation->set_message('required', 'Oops this %s is required');
If by any chance you need to change the language instead of the error statement itself, create your own form_validation_lang.php and put it into the proper language folder inside your system language directory.
As you can see here, you can display the custom error in your view in the following way:
<?php echo form_error('new_error'); ?>
PS: If this isn't your problem, post your corresponding view code and any other error message that you're getting.
The problem is that your form is already validated in your IF part! You can fix the problem by this way:
if ($this->form_validation->run() == false){
$this->load->view("login/index", $data);
}else{
$return = $this->_submitLogin();
if ($return == true){
//success
}else{
$data['error'] = 'Your error message here';
//error
}
$this->load->view("login/index", $data);
}
In the view:
echo $error;
The CI way to check user credentials is to use callbacks:
$this->form_validation->set_rules('username', 'Username', 'callback_username_check');
...
public function username_check($str) {
// your code here
}
I recommend you to read CI documentation: http://codeigniter.com/user_guide/libraries/form_validation.html
The way I did this was to add another validation rule and run the validation again. That way, I could keep the validation error display in the view consistent.
The following code is an edited excerpt from my working code.
public function login() {
$this->form_validation->set_rules('email', 'Email', 'required');
$this->form_validation->set_rules('password', 'Password', 'required');
$data['content'] = 'login';
if($this->form_validation->run()) {
$sql = "select * from users where email = ? and password = ?";
$query = $this->db->query($sql, array($this->input->post('email'), $this->input->post('password')));
if($query->num_rows()==0) {
// user not found
$this->form_validation->set_rules('account', 'Account', 'callback__noaccount');
$this->form_validation->run();
$this->load->view('template', $data);
} else {
$this->session->set_userdata('userid', $query->id);
redirect('/home');
}
} else {
$this->load->view('template', $data);
}
}
public function _noaccount() {
$this->form_validation->set_message('_noaccount', 'Account must exist');
return FALSE;
}
Require Codeigniter 3.0
Using callback_ method;
class My_controller extends CI_Controller {
function __construct() {
parent::__construct();
$this->form_validation->set_message('date_control', '%s Date Special Error');
}
public function date_control($val, $field) { // for special validate
if (preg_match("/^[0-9]{2}.[0-9]{2}.[0-9]{4}$/", $val)) {
return true;
} else {
return false;
}
}
public function my_controller_test() {
if ($this->input->post()) {
$this->form_validation->set_rules('date_field', 'Date Field', 'trim|callback_date_control[date_field]|xss_clean');
if ($this->form_validation->run() == FALSE) {
$data['errors']=validation_errors();
$this->load->view('my_view',$data);
}
}
}
}
Result:
if date = '14.07.2017' no error
if date = '14-7-2017' Date Field Date Special Error