-1

I am currently making a project about grading system and I currently do not know how to deal with this as I am still learning. I've taken this part of code from the internet and it is not my own.

        $('#percentage-form').submit(function(e){
            e.preventDefault();
            $('.pop_msg').remove()
            var _this = $(this)
            var total = $('#total').text()
                total = total.replace(/\%/gi,'')
                console.log(total)
            if(parseFloat(total) !== 100)
            {
                alert("Total Percentage must be 100%");
                return false;
            }
            var _el = $('<div>')
                _el.addClass('pop_msg')
            $('#uni_modal button').attr('disabled',true)
            $('#uni_modal button[type="submit"]').text('submitting form...')
            $.ajax({
                url:'./Actions.php?a=save_percentage',
                method:'POST',
                data:$(this).serialize(),
                dataType:'JSON',
                error:err=>{
                    console.log(err)
                    _el.addClass('alert alert-danger')
                    _el.text("An error occurred.")
                    _this.prepend(_el)
                    _el.show('slow')
                     $('#uni_modal button').attr('disabled',false)
                     $('#uni_modal button[type="submit"]').text('Save')
                },
                success:function(resp){
                    if(resp.status == 'success'){
                        _el.addClass('alert alert-success')
                        $('#uni_modal').on('hide.bs.modal',function(){
                            location.reload()
                        })
                    }else{
                        _el.addClass('alert alert-danger')
                    }
                    _el.text(resp.msg)

                    _el.hide()
                    _this.prepend(_el)
                    _el.show('slow')
                     $('#uni_modal button').attr('disabled',false)
                     $('#uni_modal button[type="submit"]').text('Save')
                }
            })
        })

I think the function save_percentage fits for sqlite3 and not with what I am using. I would like it so that this code would work with mine but I do not know how. I am using MySql and runs the server on XAMPP by the way. This is the code for Actions.php

<?php 

Class Actions{
    function save_percentage(){
        extract($_POST);
        $data = "";
        foreach($component_id as $k => $v){
            if(!empty($data)) $data .= ", ";
            $data .= "('$id','{$v}','{$percentage[$k]}')";
        }
        if(!empty($data))
        $this->query("DELETE FROM `component_subject_percentage` where `subject_id` = '{$id}'");
        $sql = "INSERT INTO `component_subject_percentage` (`subject_id`,`component_id`,`percentage`)VALUES {$data}";
        $insert = $this->query($sql);
        if($insert){
            $resp['status'] ='success';
            $resp['msg'] = "Data successfully saved";
        }else{
            $resp['status'] ='failed';
            $resp['msg'] = "Data fails to save. Error: ". $this->lastErrorMsg();
            $resp['sql'] = $sql;
        }
        return json_encode($resp);
    }
}
$a = isset($_GET['a']) ?$_GET['a'] : '';
$action = new Actions();
switch($a){

    case 'save_percentage':
        echo $action->save_percentage();
    break;
    default:
    // default action here
    break;
}

My DBConnection.PHP:

<?php
$con=mysqli_connect("localhost", "root", "", "resultgrading");
if(mysqli_connect_errno()){
    echo "Connection Fail".mysqli_connect_error(); 
}

  • 1
    **Warning:** You are wide open to [SQL Injections](https://php.net/manual/en/security.database.sql-injection.php) and should use parameterized **prepared statements** instead of manually building your queries. They are provided by [PDO](https://php.net/manual/pdo.prepared-statements.php) or by [MySQLi](https://php.net/manual/mysqli.quickstart.prepared-statements.php). Never trust any kind of input! Even when your queries are executed only by trusted users, [you are still in risk of corrupting your data](http://bobby-tables.com/). [Escaping is not enough!](https://stackoverflow.com/q/32391315) – Dharman May 19 '23 at 19:47
  • It doesnt matter this is just for a school project anyway – KHeisenberg May 19 '23 at 19:59
  • 1
    Why it doesn't matter? Why do you learn to write code the broken way? Why make your life harder? Prepared statements are easier and better. Don't make excuses. – Dharman May 19 '23 at 20:47
  • @KHeisenberg if it's for a school project, I note a very strong reason for doing good things. Security is not an optional for a developer – pierpy May 22 '23 at 07:07

2 Answers2

0

Okay, I was able to fix my code with this:

<?php 

Class Actions extends mysqli{
    public $sql;
    function __construct(){
        $this->sql = new mysqli("localhost", "root", "", "resultgrading");
    }
    function save_percentage(){
        extract($_POST);
        $data = "";
        foreach($component_id as $k => $v){
            if(!empty($data)) $data .= ", ";
            $data .= "('$id','{$v}','{$percentage[$k]}')";
        }
        if(!empty($data))
        $this->sql->query("DELETE FROM `component_subject_percentage` where `subject_id` = '{$id}'");
        $mb = "INSERT INTO `component_subject_percentage` (`subject_id`,`component_id`,`percentage`)VALUES {$data}";
        $insert = $this->sql->query($mb);
        if($insert){
            $resp['status'] ='success';
            $resp['msg'] = "Data successfully saved";
        }else{
            $resp['status'] ='failed';
            $resp['msg'] = "Data fails to save. Error: ". $this->sql->lastErrorMsg();
            $resp['sql'] = $sql;
        }
        return json_encode($resp);
    }
}
$a = isset($_GET['a']) ?$_GET['a'] : '';
$action = new Actions();
switch($a){

    case 'save_percentage':
        echo $action->save_percentage();
    break;
    default:
    // default action here
    break;
}
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community May 20 '23 at 10:05
-1

I do think it is a better idea to explain that to close this question.

First of all, your code is highly risky as @Dharman pointed out. You HAVE TO use prepared statements. Even if it is a school project, good habits must be taken.

Secondly, you use $_GET and $_POST in your code. You do a HTTP get or a HTTP post not both and your ajax is doing a post.

And your loop is out of the scope of your query.

Here is a small improvement to help you do it the right way, it might be wrong as we lack HTML :

<?php 

Class Actions{
    function save_percentage(){
        extract($_POST);
        foreach($component_id as $k => $v){
        $stmt = $this->prepare("DELETE FROM `component_subject_percentage` where `subject_id` = ?");
        $stmt->bind_param("s",$id);
        if (!$stmt->execute()) return false;
        $stmt = $this->prepare("INSERT INTO `component_subject_percentage` (`subject_id`,`component_id`,`percentage`) VALUES ?";
        $stmt->bind_param("sss",$id,$v,$percentage[$k]);
        if($stmt->execute()){
            $resp['status'] ='success';
            $resp['msg'] = "Data successfully saved";
        }else{
            $resp['status'] ='failed';
            $resp['msg'] = "Data fails to save. Error: ". $this->lastErrorMsg();
            $resp['sql'] = $sql;
        }
        }
        return json_encode($resp);
    }
}
$a = $_POST['a'] ?? '';
$action = new Actions();
switch($a){

    case 'save_percentage':
        echo $action->save_percentage();
    break;
    default:
    // default action here
    break;
}
JoelCrypto
  • 462
  • 2
  • 12