3 Replies - 134 Views - Last Post: 23 October 2017 - 02:16 PM

#1 Nicolas5150  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 27
  • Joined: 19-November 13

File not being included when sending form data over AJAX call to PHP

Posted 23 October 2017 - 11:34 AM

Hello all, I am currently testing a file upload system that takes in some form data as well as an image that needs to be included.
All this data gets sent to my database and the image is sent to a folder to store for later reference.
Currently all works well when I remove the logic of an AJAX call out of the equation and send all the data over to the .PHP alone. But when I change the form input from submit to button and allow for the Ajax call to send over the data I get:
Array()
<br />
<b>Notice</b>: Undefined index: myimage in <b>/Applications/XAMPP/xamppfiles/htdocs/back_logic/php/admin_products_add.php</b> on line <b>101</b><br />
{"status":"400","statusMessage":["File is not included"]}

So I know from the print statement that the array is not containing the file when implementing the AJAX call.
If someone could point me in the correct direction as to how this problem can be solved I would really appreciate it.
Thank you in advanced.

Currently I have used the same logic for other pages in my site and it has worked, the only difference has been the addition of adding a file to the form, rather than just plane text to be sent across.

Here is the code as it stands (with the ajax call implemented in so far)

<!DOCTYPE html>
<html>
<body>

<form action="#" method="post" enctype="multipart/form-data" id="form-product-add-data">
  sku:<br>
  <input type="text" name="sku" value="123456">
  <br>
  name:<br>
  <input type="text" name="name" value="royal blanket">
  <br><br>
  flat_value:<br>
  <input type="text" name="flat_value" value="">
  <br>
  yard_value:<br>
  <input type="text" name="yard_value" value="5.59">
  <br><br>
  stock:<br>
  <input type="text" name="stock" value="25">
  <br><br>
  description:<br>
  <input type="text" name="description" value="royal like blanket">
  <br>
  category:<br>
  <input type="text" name="category" value="fabric">
  <br><br>
  tag_one:<br>
  <input type="text" name="tag_one" value="silk">
  <br>
  tag_two:<br>
  <input type="text" name="tag_two" value="soft">
  <br><br>
  color:<br>
  <input type="text" name="color" value="red">
  <br><br>
  rating:<br>
  <input type="text" name="rating" value="na">
  <br><br>

  <input type="file" name="myimage" multiple accept="image/x-png, image/gif, image/jpeg, image/jpg" />
  <input type="button" value="Submit" id="form-product-add-btn">

</form>

<p>If you click the "Submit" button, the form-data will be sent to a page called "/action_page.php".</p>

<p>Notice that the value of the "First name" field will not be submitted, because the input element does not have a name attribute.</p>


<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="../js/submit_data.js"></script>
</body>
</html>




window.onload = function () {
  // Add product product as an upper level account.
  $( "#form-product-add-btn" ).click(function() {
    // var formElement = document.forms['myform'].elements['username'].value;
    // console.log(formElement);
      $.ajax({
        type: 'POST',
        url: 'admin_products_add.php',
        contentType: 'multipart/form-data',
        data: $('#form-product-add-data').serialize(),
        success: function (returnedData) {

          // Raw returned JSON
          console.log(returnedData);
          // How to get a specific value from the returned data object
          var data = jQuery.parseJSON(returnedData);
          console.log(data.status);

          // Code to send the user to a new page when need be.
          // similar behavior as an HTTP redirect
          // window.location.replace("http://stackoverflow.com");
        }
      });
  });
}



<?php
  // Used to add products to the inventory.
  require('connection_info.php');

  attemptAdd();

  function attemptAdd () {
    $status = gatherProductInfo();
    if ($status['statusCode'] !== '200') {
      return (returnMessage($status['statusCode'], $status['statusMessage']));
    }
    else {
      // Pull out only the account information to be validated.
      $formFields = $status['$formFields'];
    }

    // Validate data from form.
    $status = productValidate($formFields);
    if ($status['statusCode'] !== '200') {
      return (returnMessage($status['statusCode'], $status['statusMessage']));
    }

    // Send valid data to the products table
    $status = productInfoToProductsDatabase($formFields);
    if ($status['statusCode'] !== '200') {
      return (returnMessage($status['statusCode'], $status['statusMessage']));
    }

    // Cereate relational table based on the product just added.
    // Send valid data to the products table
    $status = createRelatedReview($formFields[0][2]);
    if ($status['statusCode'] !== '200') {
      return (returnMessage($status['statusCode'], $status['statusMessage']));
    }

    $status['statusCode'] = '200';
    $status['statusMessage'] ='All accounts created';
    return (returnMessage($status['statusCode'], $status['statusMessage']));
  }


  // Create array that stores all the data from the form.
  function gatherProductInfo () {
    $accountIssues = array();
    $status['statusCode'] = '200';

    // Array that conains an array within each postion; structure is as followed:
    // 0 the column to be instered into in the db
    // 1 contains the filter to be applied to check the value against.
    // 2 gets pushed value from form - if passes sanitization, gets pushed to db.
    // https://www.w3schools.com/php/php_arrays_multi.asp
    $formFields = array (
      array('sku', FILTER_SANITIZE_STRING),
      array('name', FILTER_SANITIZE_STRING),
      array('flat_value', FILTER_SANITIZE_STRING),
      array('yard_value', FILTER_SANITIZE_STRING),
      array('stock', FILTER_SANITIZE_STRING),
      array('description', FILTER_SANITIZE_STRING),
      array('category', FILTER_SANITIZE_STRING),
      array('tag_one', FILTER_SANITIZE_STRING),
      array('tag_two', FILTER_SANITIZE_STRING),
      array('color', FILTER_SANITIZE_STRING),
      array('rating', FILTER_SANITIZE_STRING),
    );

    // Gather all data from form and push to the formFields array.
    for ($i = 0; $i < count($formFields); $i++ ) {
      // echo $_POST[$formFields[$i][0]];
      // echo '</br>';
      if (isset($_POST[$formFields[$i][0]]) && !empty($_POST[$formFields[$i][0]])) {
        array_push($formFields[$i], $_POST[$formFields[$i][0]]);
      }
      // Either flat value or yard value needs to be filled in
      else if ($i == 2 && (!isset($_POST[$formFields[2][0]]) || empty($_POST[$formFields[2][0]]))) {
        array_push($formFields[$i], 'na');
      }
      else if ($i == 3 && (!isset($_POST[$formFields[3][0]]) || empty($_POST[$formFields[3][0]]))) {
        array_push($formFields[$i], 'na');
      }
      else {
        array_push($accountIssues, $formFields[$i][0]);
        $status['statusCode'] = '400';
      }
    }

    // Only one value should be filled in not both.
    if (isset($_POST[$formFields[2][0]]) && !empty($_POST[$formFields[2][0]]) &&
      isset($_POST[$formFields[3][0]]) && !empty($_POST[$formFields[3][0]])) {
      array_push($accountIssues, 'Both yard and flat values set');
      $status['statusCode'] = '400';
    }

    else if (isset($_POST[$formFields[2][0]]) && empty($_POST[$formFields[2][0]]) &&
      isset($_POST[$formFields[3][0]]) && empty($_POST[$formFields[3][0]])) {
      array_push($accountIssues, 'Neither yard or flat values set');
      $status['statusCode'] = '400';
    }

   // HERE IS WHERE THE ISSUE BEGINS IN THE CODE.
    print_r($_FILES);

    if ($_FILES["myimage"]["name"] == '') {
      array_push($accountIssues, 'File is not included');
      $status['statusCode'] = '400';
    }

    $status['statusMessage'] = $accountIssues;
    $status['$formFields'] = $formFields;
    return $status;
  }

  function productValidate ($formFields) {
    // Validating all registration information from the array.
    $accountIssues = array();
    $status['statusCode'] = '200';
    for ($i = 0; $i < count($formFields); $i++) {
      if (!sanatizeString($formFields[$i][2], $formFields[$i][1])) {
        $status['statusCode'] = '406';
        array_push($accountIssues, $formFields[$i][0]);
      }
    }

    $status['statusMessage'] = $accountIssues;
    return $status;
  }

  // Function to validate all data for the account to register.
  // http://php.net/manual/en/filter.filters.sanitize.php
  function sanatizeString($stringToCheck, $sanitizationFilter) {
    $stringChecked = filter_var($stringToCheck, $sanitizationFilter);

    // If the strings are same length, no values were removed.
    if (strlen($stringToCheck) ===  strlen($stringChecked)) {
      return true;
    }
    return false;
  }

  // With all data finally cleaned and passed of all tests, add to the database.
  function productInfoToProductsDatabase ($formFields) {
    $conn = connectToDatabase();
    // Check for a duplicate in the database prior to adding.
    if (!productDuplicate($formFields[0][2], $conn)) {

      // Needed for tracking and moving picture to the database.
      // http://talkerscode.com/webtricks/upload%20image%20to%20database%20and%20server%20using%20HTML,PHP%20and%20MySQL.php
      $upload_image = $_FILES["myimage"]["name"];
      $folder = "/Applications/XAMPP/xamppfiles/htdocs/back_logic/img/";
      $imagePath = $folder.$upload_image;

      $sql = "INSERT INTO products (sku,
        name,
        image,
        flat_value,
        yard_value,
        stock,
        description,
        category,
        tag_one,
        tag_two,
        color,
        rating)
        VALUES ('".$formFields[0][2]."',
          '".$formFields[1][2]."',
          '".$imagePath."',
          '".$formFields[2][2]."',
          '".$formFields[3][2]."',
          '".$formFields[4][2]."',
          '".$formFields[5][2]."',
          '".$formFields[6][2]."',
          '".$formFields[7][2]."',
          '".$formFields[8][2]."',
          '".$formFields[9][2]."',
          '".$formFields[10][2]."')";

      // If query is valid return 200 and move the image to the img directory
      if ($conn->query($sql) === TRUE) {
        move_uploaded_file($_FILES["myimage"]["tmp_name"], "$folder".$_FILES["myimage"]["name"]);
        $status['statusCode'] = '200';
        $status['statusMessage'] = "New product created successfully";
      }
      else {
        $status['statusCode'] = '400';
        $status['statusMessage'] = $conn->error;
      }
      $conn->close();
    }

    else {
      $status['statusCode'] = '406';
      $status['statusMessage'] = 'product found already';
    }

    return $status;
  }

  // Returns true if a sku with the same value has been found already.
  function productDuplicate ($skuDuplicate, $conn) {
    $result = mysqli_query($conn, "SELECT * FROM products WHERE sku='".$skuDuplicate."' ");
    $count = mysqli_num_rows($result);
      if ($count > 0) {
        return true;
      }
      return false;
  }

  // Upon creating new user and cart, create a history for each individual user.
  function createRelatedReview ($sku) {
    $conn = connectToDatabase();

    // sql to create table
    $tableName = 'review_'.$sku;
    $sql = "CREATE TABLE $tableName (
      username VARCHAR(120) PRIMARY KEY,
      review VARCHAR(1000) NOT NULL
    )";

    if ($conn->query($sql) === TRUE) {
      $status['statusCode'] = '200';
      $status['statusMessage'] = "History created successfully";
    }
    else {
      $status['statusCode'] = '400';
      $status['statusMessage'] = $conn->error;
    }

    $conn->close();
    return $status;
  }


  // When finished or broken out of code, send back response to request.
  // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
  function returnMessage ($statusCode, $statusMessage) {
    // var_dump($statusCode);
    // var_dump($statusMessage);

    $data = array(
    "status" => $statusCode,
    "statusMessage" => $statusMessage
    );

    echo json_encode($data);
  }
?>




Is This A Good Question/Topic? 0
  • +

Replies To: File not being included when sending form data over AJAX call to PHP

#2 andrewsw  Icon User is online

  • the case is sol-ved
  • member icon

Reputation: 6376
  • View blog
  • Posts: 25,763
  • Joined: 12-December 12

Re: File not being included when sending form data over AJAX call to PHP

Posted 23 October 2017 - 11:48 AM

If you are going to use the click event of the submit button then you need to cancel the default submission behaviour. Preferable is to use the submit event of the form itself.

I will also note that the use of forms, elements is an indication that you are using old material for reference. If you have a very old tutorial then you should find something more current. (The use of window.onload also indicates this, as does the overuse of br tags.)
Was This Post Helpful? 0
  • +
  • -

#3 ArtificialSoldier  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1828
  • View blog
  • Posts: 5,755
  • Joined: 15-January 14

Re: File not being included when sending form data over AJAX call to PHP

Posted 23 October 2017 - 12:54 PM

I don't think jQuery provides a way to handle file uploads, you need to use FileReader yourself to get that data and add it to the request. In this case it will be part of $_POST with the rest of the ajax data.

https://stackoverflo...ajax-and-jquery
Was This Post Helpful? 1
  • +
  • -

#4 Nicolas5150  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 27
  • Joined: 19-November 13

Re: File not being included when sending form data over AJAX call to PHP

Posted 23 October 2017 - 02:16 PM

View PostArtificialSoldier, on 23 October 2017 - 12:54 PM, said:

I don't think jQuery provides a way to handle file uploads, you need to use FileReader yourself to get that data and add it to the request. In this case it will be part of $_POST with the rest of the ajax data.

https://stackoverflo...ajax-and-jquery


Thank you for the link,
I was able to resolve the issue after going down the pathway you had suggested being that ajax can't really handle it.
The document / site I found helpful was:
http://codejaxy.com/...ng-ajax-and-php

In the html I switched the submit line to a button and the javascript manipulated slightly as well and was able to get the result I was looking for.
  $("form#form-product-add-data").submit(function(e){
    e.preventDefault();
     var formData = new FormData(this);
      $.ajax({
        type: 'POST',
        url: 'admin_products_add.php',
        processData: false,
        contentType: false,
        data: formData,
        success: function (returnedData) {

          // Raw returned JSON
          console.log(returnedData);
          // How to get a specific value from the returned data object
          var data = jQuery.parseJSON(returnedData);
          console.log(data.status);

          // Code to send the user to a new page when need be.
          // similar behavior as an HTTP redirect
          // window.location.replace("http://stackoverflow.com");
        }
      });
  });


Was This Post Helpful? 0
  • +
  • -

Page 1 of 1