Prevent duplicate entry at insert and update using codeigniter - codeigniter

I am trying to stop duplicate entry in database using codeigniter. It works fine when I insert data but when I update the data it is not working.. If I am change only description not departmentname it give already exist message.
For that I am using bellow code in my controller:
$this->form_validation->set_rules('departmentname', 'Departmentname', 'trim|required|xss_clean|is_unique[department_master.departmentname]');

You have to write your validation code.
Method 1: Validation Callback
Your rule declaration:
$this->form_validation->set_rules('field', 'label', 'callback__is_unique2');
The method, in the same controller that the validation:
public function _is_unique2($input) {
$exclude_id = $this->input->post('id');
if( $this->db->where('departmentname', $input)->where('id !=', $exclude_id)
->limit(1)->get('department_master')->num_rows())
{
$this->form_validation->set_message('_is_unique2', 'name exists');
return FALSE;
}
return TRUE;
}
Callbacks: Your own Validation Functions
Method 2: Extend Form_validation to add a new validation rule
Your rule declaration:
$exlclude_id = $this->input->post('id');
$this->form_validation->set_rules('field', 'label',
'is_unique2[department_master.departmentname.id_field.'.$exclude_id.']');
The extend of Form_validation,
//Libraries/MY_Form_validation.php
class MY_Form_validation extends CI_Form_validation {
public function __construct() {
parent::__construct();
}
public function is_unique2($str, $field)
{
list($table, $field, $exclude_field, $exclude_value)=explode('.', $field);
return (bool) $this->CI->db
->where($field, $str)
->where($exclude_field.' !=', $exclude_value)
->limit(1)
->get($table)->num_rows();
}
}
Extending Native Libraries
*No tested code

You can use callback function in validation rules. For example
$this->form_validation->set_rules('departmentname', 'Departmentname', 'trim|required|xss_clean|is_unique[department_master.departmentname]|**callback_is_unique_department**');
Callback function take first argument in a function is field value itself.
public function is_unique_department($dep_name)
{
// select query which find same department value exists or not if exists then write
$this->form_validation->set_message('is_unique_department', 'This Department Name is already exists.');
return false;
else write return false
}

Related

Export Excel in Laravel

**I have a problem with passing parameters on export file, I want to filter the export according to date selected on page. Hope you help me with this issue. Thanks **
This is my ExportController, I request data from form to my controller to give the export collection a date.
namespace App\Http\Controllers;
use Illuminate\Http\Response;
use Illuminate\Http\Request;
use App\Exports\ExportAttendance;
use Maatwebsite\Excel\Facades\Excel;
class ExportController extends Controller
{
public function export(Request $request)
{
return Excel::download(new ExportAttendance($request->input('min'),$request->input('max')),'Attendance.xlsx');
}
}
This is my ExportAttendance.php, this is responsible for the exportation of collections. On the query function I want to filter the data according on the date requested on the controller. How could I passed a data from controller to my Export.php, I did used constructors but it always return errors.
public function headings():array{
return[
'Name',
'In (AM)',
'Out (AM)',
'In (PM)',
'Out (PM)',
'Meeting',
'Task',
'Note',
'Total Hours',
'Date'
];
}
public function query()
{
$start = "2021-06-14";
$end = "2021-06-14";
return Attendance::select('Name','InAm','OutAM','InPM','OutPM','Meeting','SpecialTask','Undertime','TotalHours','Date')->whereBetween('Date',[$start,$end]);
}
public function collection()
{
return Attendance::all();
}
public function map($attendance):array
{
return[
$attendance->Name,
$attendance->InAM,
$attendance->OutAM,
$attendance->InPM,
$attendance->OutPM,
$attendance->Meeting,
$attendance->SpecialTask,
$attendance->Undertime,
$attendance->TotalHours,
$attendance->Date,
];
}
Instead of passing the $request object to the export class. You can simply use the request helper method.
public function query()
{
return Attendance::select('Name','InAm','OutAM','InPM','OutPM','Meeting','SpecialTask','Undertime','TotalHours','Date')
->whereBetween('Date',[request('start'), request('end')]);
}
Passing parameters is supposed to work too. Pls let me know what errors you see so I can update my answer.
I used Constructor
public function query()
{
$start = "2021-06-14";
$end = "2021-06-14";
return Attendance::select('Name','InAm','OutAM','InPM','OutPM','Meeting','SpecialTask','Undertime','TotalHours','Date')->where('Date','=',$this->year);
}
And this is my controller,
public function export(Request $request)
{
ob_start();
$datestart = $request->input('min');
$datestart = ob_get_contents();
return Excel::download(new ExportAttendance($datestart),'Attendance.xlsx');
ob_end_flush();
}
Another problem arise, when I used ob_end_clean() all my variable values returned nulls.

Extended Form_validation library in codeigniter, cannot check is field is empty

I was trying to extend codeigniter(3.1.11) form_validation library to add validation rules of my own.
Below is the code written in application/libraries/MY_Form_validation.php.
defined('BASEPATH') OR exit('No direct script access allowed');
class MY_Form_validation extends CI_Form_validation
{
protected $CI;
public function __construct($rules = array())
{
parent::__construct($rules);
// Assign the CodeIgniter super-object
$this->CI =& get_instance();
}
public function snExists($sn){
if (empty($sn)) {
$this->CI->form_validation->set_message('snExists', '{field} is required');
return FALSE;
}else{
$query = $this->CI->db->query("SELECT `sn` FROM `employee` WHERE `sn` = '$sn';");
$numrows = $query->num_rows();
if ($numrows > 0) {
return TRUE;
}else{
$this->CI->form_validation->set_message('snExists', '{field} does not exist');
return FALSE;
}
}
}
}
The issue i am facing is that, when i submit the field empty the validation does not return FALSE.
somehow the if(empty($sn)) is not satisfied and the else is executed.
hope someone could help. Thank you.
So it looks like codeigniter does not call any validation methods if a field is submitted empty. It will just returns TRUE by default. So in my case checking whether $sn is empty is pointless.

Codeigniter 3.1.9 MY_Form_validation is not working

Im working on Codeigniter 3.1.9 and completed my form on local machine. i just uploaded my app some moment ago on server and getting error
Unable to access an error message corresponding to your field name
URL.(valid_url_format)
i google alot but unable to fix problem.
Filename: My_Form_validation.php
Location: application\libraries
class MY_Form_validation extends CI_Form_validation{
public function __construct()
{
parent::__construct();
}
function valid_url_format($str){
$pattern = "/^(http|https|ftp):\/\/([A-Z0-9][A-Z0-9_-]*(?:\.[A-Z0-9][A-Z0-9_-]*)+):?(\d+)?\/?/i";
if (!preg_match($pattern, $str)){
$this->set_message('valid_url_format', 'The URL you entered is not correctly formatted.');
return FALSE;
}
return TRUE;
}
function url_exists($url){
$url_data = parse_url($url); // scheme, host, port, path, query
if(!fsockopen($url_data['host'], isset($url_data['port']) ? $url_data['port'] : 80)){
$this->set_message('url_exists', 'The URL you entered is not accessible.');
return FALSE;
}
return TRUE;
}
}
Filename: UrlChecker.php
Location:application\controllers
class UrlChecker extends CI_Controller {
public function __construct() {
parent::__construct();
}
public function _initializing(){
}
public function index()
{
$this->form_validation->set_rules('link', 'URL', 'required|trim|valid_url_format|url_exists');
if ($this->form_validation->run() == FALSE)
{
echo validation_errors('<div class="alert alert-danger" role="alert">', '</div>');
}
else
{
echo 'ok';
}
}
Please check and let me know whats wrong is there hosting version problem or there is something else.
I always use custom validation on the fly and its the first time to try to make a custom library for additional validations, anyways i created and tested it to make sure it works, you got to make sure you follow the naming convention, the file name should be like this: MY_Form_validation.php and save it in your application/libraries then create your class:
class MY_Form_validation extends CI_Form_validation
{
// your rules
}
then you have to create error messages for every method, create a lang file in your application/language/english/form_validation_lang.php and add your custom error messages like this:
$lang['valid_url_format'] = 'The {field} field may only contain valid url.';
$lang['url_exists'] = 'The {field} field already exists';

How to call a controller function as a callback for the validation rules?

Deal All,
I have a controller which is extending the CI_Controller like this;
class MY_Controller extends CI_Controller
{
function check_unique($table, $field, $message_label, $value, $except_id){
$query = "SELECT * FROM $table WHERE $field = $value AND id != $except_id LIMIT 1";
if(count($this->db->query($query)->row_array()) == 0 ){
return TRUE;
}else{
$this->form_validation->set_message($field, "The field '" . $message_label . "' is not available. Please try a different value.");
return FALSE;
}
}
}
In my Client class -> edit function, that is...,
class Client extends MY_Controller
{
function edit($id){
$this->form_validation->set_rules("name", "Name", "required|max_length[50]");
}
}
...I want to check if name is being duplicated while update. Is there a way I can call the "check_unique" function from the controller in the validation rules?
You can use Form validation libraries callback feature to call your custom validation functions.
As your custom validation method is in MY_Controllerand you are inheriting it in your Clientclass it will work fine as following.
function edit($id){
$this->form_validation->set_rules("name", "Name", "required|max_length[50]|callback_check_unique");
}
Remember you need call your function using callback_ prefix.
In the Callback function, you can pass arguments as well. By default, CI will pass string parameter as an argument to your callback function. So you may need to modify your custom function little bit

Creating a custom validation rule in Ardent w/ Laravel that can access the model to do dirty checking

Goal
I have an Ardent model called User in Laravel.
I want to have a custom validation rule called confirm_if_dirty.
This would only run if the User->password attribute is dirty. It would expect there to be a User->password_confirmation field.
Below is an example of how this rule might look.
Validator::extend('confirm_dirty', function($attribute, $value, $parameters) use($model)
{
//If field is not dirty, no need to confirm.
if($model->isDirty("{$attribute}")){
//Confirmation field should be present.
if(!$model->__isset($attribute."_confirmation")){
return false;
}
//Values should match.
$confirmedAttribute = $model->getAttribute($attribute."_confirmation");
if( $confirmedAttribute !== $value){
return false;
}
//Check to see if _confirmation field matches dirty field.
}
return true;
});
Question
How can I make it so that $model in my case is passed in or is the model instance in question?
Here is how I am doing to provide access to the model in a validator function:
class CustomModel extends Ardent {
public function __construct(array $attributes = array())
{
parent::__construct($attributes);
$this->validating(array($this, 'addModelAttribute'));
$this->validated(array($this, 'removeModelAttribute'));
}
public function addModelAttribute()
{
$this->attributes['model'] = $this;
}
public function removeModelAttribute()
{
unset($this->attributes['model']);
}
}
Now, it is possible to have access to the model instance as the model attribute in the validator:
class CustomValidator extends Validator {
protected function validateConfirmDirty($attribute, $value, $parameters)
{
$this->data['model']; // and here is the model instance!
}
}

Resources