Variable not returning a boolean yii 2 - php

I have been working on this code to return a Boolean value, what happens is that the variable gets overwritten with true or false as it looks for a row in the foreach statements. But when I pass it in my view file no value is taken/appears. Can you help me why this is happening and how do I successfully pass the boolean?
View file
echo TestController::Showprerequisites(29005);
Model
$validator;
foreach($prereq as $values){
if(FinishedSubjects::find()->where(['subjectname' => $values['col']])->exists()){
$validator = true;
} else {
$validator = false;
}
}
return $validator;
Controller
public function Showprerequisites($trno){
$model = new TestModel();
return $model->Showprerequisites($trno);
}
EDIT
View update
$preq = TestController::Showprerequisites(29005);
if($preq = true){
echo 'Pre requites completed/read';
} else if($preq = false) {
echo 'Pre requisites not completed/not read';
}

You have logical error in your code, you are assigning value in if condition and then checking, it always return true.
Instead of this:
if($preq = true){
you can check this way too:
if($preq){ // if $preq is true then this line will work.

Related

how to run two statements in one funcation

I'm trying to delete from two tables using one function.
Controller code:
public function userdelete()
{
$u_id = $this->uri->segment(3);
$lr_id = $this->uri->segment(3);
$returndata = $this->user_model->user_delete($u_id, $lr_id);
if($returndata) {
$this->session->set_flashdata('successmessage', 'user deleted successfully..');
redirect('users');
} else {
$this->session->set_flashdata('warningmessage', 'Something went wrong..Try again');
redirect('users');
}
}
Modle code:
public function user_delete($lr_id, $u_id ) {
return $this->db->delete('login_roles',['lr_id'=>$lr_id]);
return $this->db->delete('login',['u_id'=>$u_id]);
}
I'm able to delete only from the first table but not the other one. this is working :
return $this->db->delete('login_roles',['lr_id'=>$lr_id]); but not return $this->db->delete('login',['u_id'=>$u_id]);.
As said in the comment you have to remove the first return.
You should compute the two results :
public function user_delete($lr_id, $u_id ) {
$delete1Response = $this->db->delete('login_roles',['lr_id'=>$lr_id]);
$delete2Response = $this->db->delete('login',['u_id'=>$u_id]);
return ($delete1Response AND $delete2Response);
}
It will returns true only if both are deleted
You even can go further and :
public function user_delete($lr_id, $u_id ) {
$delete1Response = $this->db->delete('login_roles',['lr_id'=>$lr_id]);
$delete2Response = $this->db->delete('login',['u_id'=>$u_id]);
return (object)array('role' => $delete1Response, 'user' => $delete2Response);
}
Then you can access to data like that :
$response = user_delete(...);
if ($response->role AND $response->user) {
// All fine
} else {
// One or both failed.
// Display error or do something
}
It never reaches the second $this->db->delete since its returns after executing the first one. Try:
public function user_delete($lr_id, $u_id ) {
if($this->db->delete('login_roles',['lr_id'=>$lr_id])){
//success, try the next one
return $this->db->delete('login',['u_id'=>$u_id]);
}
//failed
return false;
}

Can't set error message in Code Igniter 3 when using callback function

I am writing a method that uses POST variables posted by AJAX to add a user to a certain course in the database, but I can't get the callback to work correctly:
public function enroll()
{
$package = array();
$this->load->library('form_validation');
$this->form_validation->set_rules('course', 'Vak', 'required|callback_not_enrolled');
$fields = array("course");
if ($this->form_validation->run($this) === FALSE) {
$errors = array();
$success = array();
foreach ($fields as $field) {
$error = form_error($field);
if ($error !== "") {
$errors[$field] = $error;
} else {
$success[$field] = True;
}
}
$package["field_errors"] = $errors;
$package["field_success"] = $success;
$package["success"] = False;
} else {
$package["database"] = $this->course_model->enroll_user($this->data["user"], $this->input->post("course"));
$package["success"] = True;
}
echo json_encode($package);
}
I wrote the callback not_enrolled to check if the user is not already enrolled to the database. Note that I can't use is_unique because I have to test the combined uniqueness of two fields (so just one or two separate ones don't do the trick) and the id of the user is not included in the form (because it's part of the Code Igniter session).
The callback function:
public function _not_enrolled($course)
{
$exists = ($this->user->is_enrolled($course, $this->data["user_id"]) != False);
if ($exists != False) {
$this->form_validation->set_message("not_enrolled", "Already enrolled");
return False;
} else {
return True;
}
}
And finally the method is_enrolled from the model:
public function is_enrolled($course, $user=False) {
if($user==False){
$user = $this->data["user_id"];
}
$this->db->select()->from("course_participant")->where("user_id", $user)->where("course_id", $course);
$query = $this->db->get();
return($query->num_rows()>0);
}
Through a call to var_dump($this->_not_enrolled($existing_course_id)); I know that both the callback function and the method from the model work, as it correctly returned true.
When I var_dump the $package array or validation_errors() I don't get any validation errors except that it says Unable to access an error message corresponding to your field name Vak(not_enrolled).
I tried removing the initial _ from the function name but that gives me a Server Status 500 error.
I have another setup exactly like this, albeit other database calls, with a callback using the same syntax. This method works perfectly.

Variable to another php file

I have a php file(register.php) with a public function register($data) where errors are validated.Then errors are counted and if no errors are found, validation is passed.
register.php:
class ARegister {
public function register($data) {
$user = $data['userData'];
//validate provided data
$errors = $this->validateUser($data);
if(count($errors) == 0) {
//first validation
}
}
public function validateUser($data, $botProtection = true) {
$id = $data['fieldId'];
$user = $data['userData'];
$errors = array();
$validator = new AValidator();
if( $validator->isEmpty($user['password']) )
$errors[] = array(
"id" => $id['password'],
"msg" => Lang::get('password_required')
);
return $errors;
}
The problem is, that I need to get this confirmation of validated data to my other php file (othervalidation.php) where I've made another validation:
othervalidation.php:
<?php
require 'register.php';
if ( !empty($action) ) {
switch ( $action ) {
case 'process_payment':
try {
$instance = new ARegister();
if($instance->validateUser($data, $errors)) {
throw new Exception('Validation error');
}
} catch (Exception $e) {
$status = false;
$message = $e->getMessage();
}
}
How can I send the result of $errors variable to my other validation (othervalidation.php)?
I looked at your new code design and here's the new problems I found.
First, in your register function, you use the errors variable as an integer while your validate function returns an array. You got two possibilities here.
You can change your register method to check out if your error array is empty like this:
if(empty($errors)) {
//first validation
}
Count is also valid, but I still prefer empty since it's syntactically clearer. Furthermore, the count function returns 1 if the parameter is not an array or a countable object or 0 if the parameter is NULL. As I said, it is a functional solution in your current case but, in some other contexts, it might cause you unexpected results.
Here in your method declaration, I see that you are expecting a boolean (botProtection).
public function validateUser($data, $botProtection = true) {
But you are supplying an errors parameter
if($instance->validateUser($data, $errors)) {
You don't provide me the declaration of the errors variable, but it is probably not matching the bot protection parameter your function is expecting. PHP is using lose typing, it is useful but, once again, you got to be careful for bugs hard to find. For public function, you should always make sure a way or another that the supplied parameter won't lead to code crash.
In your code, the data parameter seems to be an array. You can use parameter hinting to force the use of array like this:
public function register(array $data) {
public function validateUser(array $data, $botProtection = true) {
And even specific class (as if you where using "instance of" in a condition)
public function register(MyDataClass $data) {
public function validateUser(MyDataClass $data, $botProtection = true) {
Also, you're not even using the botProtection parameter in your validateUser method.
On the same function call:
if($instance->validateUser($data, $errors)) {
you are expecting a Boolean (true or false), but the method returns an array. If you want to use the code the way it is currently designed, you must use it like this
if(!empty($instance->validateUser($data, $errors)) {
Here, I'm not so sure it is necessary to use exception. Ain't it be easier to design your code like this?
if(!empty($instance->validateUser($data, $errors)) {
$message = 'Validation error';
}
In your validate function, is the "isEmpty" function also validating if the client provided a password?
If that's the case you could validate it like this:
if(!in_array($user['password']) or empty($user['password']))
With those corrections, your code should be functional.
Here's a sample of how I would had design your code (considering the code sample provided):
class ARegister {
public function register($data) {
$user = $data['userData']; //don't declare it here, all the user validations must be done in validateUser($data, &$errors)
$errors = array();
if($this->validateUser($data, $errors)) {
//first validation
}
}
/**
* Note: If you are not returing more than one error at the time, $errors should be a string instead of an array.
*/
public function validateUser($data, array &$errors) {
$isValid = false;
if (in_array($data['fieldId']) and in_array($data['fieldId']['password']) and in_array($data['userData'])){
if(!in_array($data['userData']['password']) or empty($data['userData']['password'])){
$errors[$data['fieldId']['password']] = Lang::get('password_required');
}
else{
$isValid = true;
}
}
else{
//an invalid data array had been provided
}
return $isValid;
}
For the next part, if the code is executed directly in the view and you are a beginner, create a procedural external controller file (all functions will be public...). If you are a professional, you MUST create a class to encapsulate the treatment.
You must not do treatment directly in the view. The view is a dumb placeholder for data presentation and collecting client's input. The sole action it must do is display the data sent by the controller and send back the client's input to the controller.
The treatment on data is the controller responsibility.
if (!empty($action) ) {
$errors =array();
switch ( $action ) {
case 'process_payment':
$instance = new ARegister();
if($instance->validateUser($data, $errors)) {
//the user is valid, do the treatment
}
else
PageManager::dispayError($errors);
}
unset($instance);
}
}
Here's an example how you can centralize your error display
/**
* Can be more complexe than that, but I'm at my father's home at four hundred kms away from Montreal right now..
*/
public static function dispayError($errors, $size = 4){
if (is_numeric($size)){
if ($size < 0){
$size = 1;
}
elseif($size > 5){
$size = 5;
}
}
else{
$size = 4;
}
if (is_scalar($errors)){
echo '<h' . $size . 'class="ERROR_MESSAGE">' . $errors . '</h' . $size . '><br>';
}
elseif (is_array($errors)){
foreach ($errors as $error){
if (is_scalar($error)){
echo '<h' . $size . 'class="ERROR_MESSAGE">' . $error . '</h' . $size . '><br>';
}
}
}
}
Of course, you can also support many kind of message:
public static function dispayError($errors, $size = 4){
self::displayMessage("ERROR_MESSAGE", $errors, $size=4);
}
private static displayMessage($class, $messages, $size=4)
Well, took me two hours to write that. I hope you have now enough material to build an efficient, reusable and, no less important, safe code design.
Good success,
Jonathan Parent-Lévesque from Montreal
You can try something like this:
class ARegister {
private $error = 0;
public function register($data) {
if (!$this->validateUser($data)){
$this->error++;
}
}
public function getErrorCount(){
return $this->error;
}
public resetErrorCount(){
$this->error = 0;
}
Or pass the error by reference:
public function register(&$error, $data) {
if (!$this->validateUser($data)){
$error++;
}
}
Personally, I would do all the validation in the same method (in the class for encapsulation), use an error message parameter (passed by reference) to return why the validation failed and use the return statement to return true or false.
class MyClass{
public function validation(&$errorMessage, $firstParameter, $secondParameter){
$success = false;
if (!$this->firstValidation($firstParameter)){
$errorMessage = "this is not working pal.";
}
elseif (!this->secondeValidation($firstParameter)){
$errorMessage = "Still not working buddy...";
}
else{
$success = true;
}
return $success;
}
private function firstValidation($firstParameter){
$success = false;
return $success;
}
private function secondeValidation($secondParameter){
$success = false;
return $success;
}
}
In your other file:
<?php
$instance = new MyClass();
$errorMessage = "";
if ($instance->validation($errorMessage, $firstParameter, $secondParameter)){
echo "Woot, it's working!!!";
}
else{
echo $errorMessage;
}
?>
Is one of these code solutions fit your needs?
Jonathan Parent-Lévesque from Montreal

how to set custom validation message in grocery crud

$crud = new grocery_CRUD();
$crud->set_table('generate_eblskyid');
$crud->set_rules('salt', 'Salt Code','callback_check_salt');
$output = $crud->render();
then in the call back function i did the following
function check_salt($str)
{
$salt = $_POST['salt'];
if($salt > 5)
{
$this->get_form_validation()->set_message('salt',"Salt value must be less then FIVE");
return FALSE;
}
}
When I go to add record if I give a salt value below five the is inserted successfully but when I give a value greater then five it says "An error has occurred in insert" without displaying my custom message.
What I am doing wrong ??
Your check_salt($str) function should be like this
function check_salt($str)
{
if($str > 5)
{
$this->form_validation->set_message('check_salt',"Salt value must be less then FIVE");
return false;
}else{
return true;
}
}
In set_message function, the callback function name 'check_salt' should be given, not the field name 'salt' This should solve your problem.
This was the only way that I found to makes this work using:
CI 3 and Grocery Crud 1.6.1
$crud->set_rules('name', 'Name', array(
'required',
array(
'company_check',
function ($str) {
$company = $this->Company_model->searchCompanyByName($str);
if (count($company) > 0) {
$this->form_validation->set_message('company_check', 'Error, The company already exist.');
return false;
} else {
return true;
}
}
)
));
Hope this help,

how to check callback validation codeigniter duplicate database entry?

This is my callback function, I want to check the database for duplicate value, I have tried a lot, but I can't get validation to work. I'm new to Codeigniter so any help would be appreciated!
public function alias_exist_check()
{
$scol_code = $this->input->post('school_code');
$user_id=$this->input->post('user_id');
$query=$this->db->get_where('user_application',array('school_code'=>$scol_code, 'user_id'=>$user_id));
$row= $query->row_array();
if(!$row['user_id']==$user_id && !$row['school_code']==$scol_code)
{
return TRUE;
} else {
$this->form_validation->set_message('alias_exist_check', 'Already exists.');
return FALSE;
}
}
UPDATE1 ::
i tried this but its not working me help me if i wrote any mistakes.
$this->form_validation->set_rules('school_code', 'School Name','required','callback_alias_exist_check', 'trim|xss_clean'); $where = array(
'school_code' => $this->input->post('school_code'),
'user_id' => $this->input->post('post'));
if( ! $this->lawschool_model->alias_exist_check($where))
{
$this->form_validation->set_message('alias_exist_check', 'Already exists.');
}
if ($this->form_validation->run() == FALSE)
{
$data['row']= $this->lawschool_model->Getuser($data1);
$data['row1']= $this->lawschool_model->GetData1();
$this->ag_auth->view('Home',$data);
}
else
{
$insert = $this->db->insert('user_application',$data);
if($insert==TRUE)
{
/*$idNum = $this->input->post('school_code');
$data1 = $this->lawschool_model->upddata_school();*/
$data['row'] = $this->lawschool_model->Getuser($data1);
$data['row1'] = $this->lawschool_model->GetData1();
$this->ag_auth->view('Home',$data);
}
}
UPDATE2::finaly its works fine,here is my working code
$this->form_validation->set_rules('school_code', 'School Name','required','callback_alias_exist_check1', 'trim|xss_clean');
function alias_exist_check1($scol_code,$user_id)
{
$sql = "SELECT * FROM user_application WHERE school_code = ? AND user_id = ?";
$val = $this->db->query($sql,array($scol_code ,$user_id ));
if ($val->num_rows)
{
$this->form_validation->set_message('alias_exist_check', 'Already exists.');
return TRUE;
}
else
{
return FALSE;
}
}
Model
public function alias_exist($where)
{
return $this->db->where($where)->count_all_results('user_application') > 0;
}
Controller
public function alias_exist_check()
{
$where = array(
'school_code' => $this->input->post('school_code'),
'user_id' => $this->input->post('user_id')
);
return ! $this->name_model->alias_exist($where);
}
The first function was not working because you tried to access post data from within the callback itself. This does not appear to work well with callbacks. This is because codeigniter will remove all post data from the request as soon as your run the form validator run method. It repopulates post data only when form processing is complete. Pass any extra parameters you need for you callback functions to work like this
callback_foo[bar]

Categories