I am attempting to split up image file uploading to an ajax method. All of the html and JS is in one file and then I made up a PHP file that contains all of the PHP.
What I am struggling with is I am not sure how to send the image file info over to the php file and then for the rest of the php to work as it used to.
As of now, this line of code $p_img = $_POST['file']; is getting an undefined index error. However, even if that is populating, I am not sure if this will work correctly with the files being seperated.
Is there anyway that I can leave my first PHP function, UploadFile in the file with the HTML and JS and then send the function over to the PHP file?
IF not, what can I do?
HTML
<form action="" method="POST" id="projectForm" enctype="multipart/form-data">
<label>Project Name</label>
<input type="text" class="input block" name="p_name">
<label>Project Img</label>
<input type="file" id="file" name="file" class="file-input block">
<button id="submit">Submit Project</button>
</form>
JS
$('#projectForm').validate({
ignore: [],
rules: {
p_name: {
required: true,
minlength: 5
},
p_alt: {
required: true,
minlength: 2
}
},
messages: {
p_name: {
required: "Please enter the project name",
minlength: "The project name is too short"
},
p_alt: {
required: "Please enter the alt text",
minlength: "Your alt text is too short"
}
},
submitHandler: function (form, e) {
e.preventDefault();
var formData = new FormData(form);
category = $(this).data('category');
console.log(category);
$.ajax({
url: '/php/projectSend.php',
type: 'POST',
data: formData,
success: function (data) {
console.log(data);
},
contentType: false,
processData: false,
error: function (xhr, textStatus, errorThrown) {
alert(textStatus + " | " + errorThrown);
alert('There are currently no project images for this selection');
}
});
}
});
PHP
ini_set('display_errors', 1);
error_reporting(E_ALL);
include($_SERVER['DOCUMENT_ROOT'].'/config.php');
$p_name = trim(htmlspecialchars($_POST['p_name'], ENT_QUOTES));
$p_img = $_POST['file'];
$p_alt = trim(htmlspecialchars($_POST['p_alt']));
$category = trim(htmlspecialchars($_POST['categoryName']));
$creator = trim(htmlspecialchars($_POST['creatorName']));
$status = $_POST['status'];
function UploadFile($fileArray = array(), $destinationFolder = '../project_images/') {
$filename = $fileArray['file']['name'];
$tmp_name = $fileArray['file']['tmp_name'];
$filesize = $fileArray['file']['size'];
$file_error = $fileArray['file']['error'];
$file = $fileArray['file'];
// Save all the default data.
$return['error'] = true;
$return['success'] = false;
$return['file']['dest'] = $destinationFolder.$filename;
$return['file']['size'] = $filesize;
if($file_error == 0)
$return['error'] = false;
if(!is_dir($destinationFolder))
mkdir($destinationFolder,0755,true);
// If your filename is not empty, return success or fail of upload
if (!empty($filename))
$return['success'] = (move_uploaded_file($tmp_name, $destinationFolder.$filename));
return $return;
}
try {
$con = getConfig('pdo');
$con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
function SaveToDb($con,$filename = false) {
// Return fail immediately if the connection is false or image is invalid
if(empty($filename) || !$con)
return false;
$project_sql = "
INSERT INTO quotes
(p_name, p_img, p_alt, category, creator, status, date_added)
VALUES(?, ?, ?, ?, ?, ?, NOW())
";
if ($project_stmt = $con->prepare($project_sql)) {
$project_stmt->execute(array($p_name, $p_img, $p_alt, $category, $creator, $status));
return true;
$proj_succ = "Success";
echo json_encode($proj_succ);
}
return false;
}
} catch (PDOException $e) {
echo "Connection failed: " . $e->getMessage();
}
if(isset($_POST['create'])) {
// Try uploading
$upload = UploadFile($_FILES);
// If upload fails
if(!$upload['success']) {
echo '<h3>Sorry, an error occurred</h3>';
}
else {
// Try to save it
$saveToDb = SaveToDb($con,$upload['file']['dest']);
// Get the profile from image name
$profPic = ($saveToDb)? getPhoto($con,$upload['file']['dest']) : false;
}
}
I think your form object you are sending to FormData is not what FormData expects.
var form = document.forms.namedItem("fileinfo");
form.addEventListener('submit', function() {
var oOutput = document.querySelector("div"),
oData = new FormData(form);
}
you can read more
That's because you're trying to access the uploaded file via the $_POST array, which doesn't include files. What you're looking for is $_FILES.
Reference
Related
I have multiple uploads on a page, and I am workin on tidying it up, so:
Here's my js:
$(".img").change(function () {
var form = $(this).closest('form');
getPath(form);
})
deleteButton();
copyGalleryData();
});
function getPath(form) {
var name = $(form).attr('name');
submitImage(form, name);
}
var path_to_delete;
function submitImage(form, name) {
var url = '/image/upload';
var form_data = new FormData($(form)[0]);
submit(name);
form_data.append('img', $(form).children(".img"));
$.ajax({
url: url,
data: form_data,
dataType: 'json',
async: true,
type: 'post',
processData: false,
contentType: false,
success: function (data) {
console.log(data);
$(form).children('.image-container').append('<img id="image" name=' + name + '" src="' + data + '" />')
$(".imageDelete").attr('data', data);
alerts();
var deleting = false;
success(name, deleting, data);
$('.messages').html('<div class="alert alert-success">Image Uploaded!<div>');
},
error: function (data) {
alerts();
fail();
$('.messages').html('<div class="alert alert-danger">File type not supported! Use files with image extension only!</div>');
},
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
}
and controller:
class ImageController extends Controller
{
use S3;
public function upload(ImgRequest $request)
{
if ($request->hasFile('img')) {
$this->imageEntity();
return response()->json($path);
}
if ($request->hasFile('coverUpload')) {
$this->imageCover();
}
}
public function imageEntity()
{
$s3Path = config('app.path', public_path());
$image = Input::file('img');
Log::info('Retrieving Image', ['image' => $image]);
$filePath = 'public/logo/' . time() . '.' . $image->getClientOriginalExtension();
$path = $s3Path . $filePath;
$this->S3Store($filePath, $image);
$session = session()->get('key');
try {
$update_image = Entity::find($session);
$update_image->logo = $path;
$update_image->save();
Log::info('Succesfully saved logo for', ['entity_id' => $session]);
return response()->json($path);
} catch (Exception $e) {
Log::error('Images:', ['message' =>$e->getMessage(), 'entity_id' => $session]);
}
}
public function imageCover()
{
$s3Path = config('app.path', public_path());
$image = Input::file('coverUpload');
Log::info('Retrieving Cover', ['image' => $image]);
$filePath = 'public/cover/' . time() . '.' . $image->getClientOriginalExtension();
$path = $s3Path . $filePath;
$this->S3Store($filePath, $image);
$session = session()->get('key');
try {
$image = new Images;
$image->path = $path;
$image->cover = true;
$image->entity_id = $session;
$image->save();
Log::info('Succesfully saved logo for', ['entity_id' => $session]);
return $path;
} catch (Exception $e) {
Log::error('Images:', ['message' =>$e->getMessage(), 'entity_id' => $session]);
}
}
Now the funny thing is response is 200, however it is empty ($path is defined) and ajax is triggering error: part of the code and not success. I have checked the log, and try has been successful:
[2017-10-16 11:22:01] local.INFO: Retrieving Image {"image":"[object]
(Illuminate\Http\UploadedFile: /tmp/phpHPchM4)"} [2017-10-16
11:22:01] local.INFO: Adding to S3 [2017-10-16 11:22:05] local.INFO:
Succesfully added to S3 [2017-10-16 11:22:05] local.INFO:
Succesfully saved logo for {"entity_id":"324"}
Could anyone please help me solve this matter?
Update::
I have updated the controller so that the function returns $path, and main function return the response, however for some reason it is saying that $path is undefined, how to pass data from return to controller that is returned it?
I am making a single registration form with all the data and input tags I need and pass that data to the next page via AJAX. But I do not get my image upload value to the next page. Please help me find a solution regarding ajaxfileupload.js and validation.js and tell me how to store image in a database using codeigniter.
<script src="<?php echo JS_PATH;?>jquery-validation.js"></script>
javascript:
$(document).ready(function() {
$("#registration_form").validate({
rules: {
name: {
required: true
},
surname: "required",
email: {
required: true,
email: true
},
password: {
required: true,
minlength: 5
}
},
messages: {
name: {
required: "Please enter your name"
},
surname: "Please enter your surname",
password: {
required: "Please provide a password",
minlength: "Your password must be at least 5 characters long"
}
},
submitHandler: submitForm
});
function submitForm() {
var name = $('#name').val();
var surname = $('#surname').val();
var age = $('#age').val();
var dob = $('#datepicker').val();
var ph_no = $('#ph_no').val();
var gender = $('input[type="radio"]:checked').val();
var hobbies = new Array();
$('input[name="hobbies[]"]:checked').each(function() {
hobbies.push(this.value);
});
var city = $('#city').val();
var email = $('#email').val();
var pwd = $('#password').val();
var photo = $("#userfile").val();
$.ajax({
url: "<?php echo SITE_ROOT;?>Registration/insertdata",
type: "POST",
data: {
username: name,
user_surname: surname,
user_email: email,
password: pwd,
user_age: age,
user_dob: dob,
user_ph_no: ph_no,
user_gender: gender,
user_hobbies: hobbies,
user_city: city,
user_photo: photo
},
success: function(data) {
alert(data);
}
}
});
}
html:
<form method="post" enctype = "multipart/form-data" >
<label> File Input: </label>
<input type="file" name="userfile" id="userfile">
<input type="submit" name="submit" value="Submit" />
</form>
php controller:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Registration extends CI_Controller
{
function __construct() {
parent::__construct();
$this->load->model('menupages/registration_model');
}
public function index() {
$this->first();
}
function first() {
$data['title'] = "Registration Page";
$this->load->view('menupages/registration', $data);
}
function insertdata() {
$file = $_POST['user_photo'];
print_r($file);
exit();
$config['upload_path'] = '/var/www/html/upload/';
$config['allowed_types'] = 'gif|jpg|png';
$config['max_size'] = '100';
$config['file_name'] = $file;
$this->load->library('upload'); //initialize
$this->upload->initialize($config);
if ( ! $this->upload->do_upload('userfile')) {
$error = array('error' => $this->upload->display_errors());
print_r($error);
exit();
} else {
$data = array('upload_data' => $this->upload->data());
print_r($data);
exit();
}
}
}
First of all , there are many things that are not okay with your current code inside php codeginiter 's controller, let's first see a difference between $_POST vs $_FILES
$_POST contains all the data from forms (except files)
$_FILES contains all files sent to server via forms (only from <input type="file" />)
What you are doing is , you are using $_POST['user_photo'] to fetch the file details , which is not okay to fetch the file information for uploading it. And also another thing is :
$this->upload->do_upload('userfile');
You are wrong here. the parameter userfile does not even exist in your http request. While sending the data to the server , you have replaced the userfile with user_photo , so what you have to here is also you have to change these two things
$_POST['user_photo'];
$this->upload->do_upload('userfile');
to
$_FILES['user_photo'];
$this->upload->do_upload('user_photo');
change your :
$('#userfile').val();
to
$("#userfile").prop("files")[0];
and add these parameters into javascript parameters along with url , data and etc..
contentType: false,
processData: false,
cache: false,
change your submitForm function to this:
function submitForm() {
var name = $('#name').val();
var surname = $('#surname').val();
var age = $('#age').val();
var dob = $('#datepicker').val();
var ph_no = $('#ph_no').val();
var gender = $('input[type="radio"]:checked').val();
var hobbies = new Array();
$('input[name="hobbies[]"]:checked').each(function() {
hobbies.push(this.value);
});
var city = $('#city').val();
var email = $('#email').val();
var pwd = $('#password').val();
var photo = $("#userfile").prop("files")[0];
var form_data = new FormData();
form_data.append("user_photo", photo);
form_data.append("username",name);
form_data.append("user_surname",surname);
form_data.append("password",pwd);
form_data.append("user_age",age);
form_data.append("user_dob",dob);
form_data.append("user_ph_no",ph_no);
form_data.append("user_gender",gender);
form_data.append("user_hobbies",hobbies);
form_data.append("user_city",city);
$.ajax({
url: "<?php echo SITE_ROOT;?>Registration/insertdata",
type: "POST",
data: form_data,
success: function(data) {
alert(data);
}
}
});
}
Make use of FormData() on javascript.
data = new FormData();
data.append('name', $('#name').val());
data.append('surname', $('#surname').val());
data.append('age', $('#age').val());
data.append('dob', $('#datepicker').val());
data.append('ph_no', $('#ph_no').val());
data.append('gender', $('input[type="radio"]:checked').val());
//for Photo
data.append('photo', $('#userfile')[0].files[0]);
//AJAX
$.ajax({
url: "<?php echo SITE_ROOT;?>Registration/insertdata",
data: data,
processData: false,
contentType: false,
type: 'POST',
success: function(data){
console.log(data)
}
});
PHP CODE:
To test if you successfully passed file and post data on php:
print_r($_FILES);
print_r($_POST);
You can submit the form and send it by form.serialize in JQuery. It will send data with picture by Ajax.
I tried to send post value to OrderController (I use ZF2). I have javascript code in view folder.These are the code:
function submitHandler(form) {
var urls = '<?php echo $this->baseurl; ?>/order/saveOrder';
var pack= $("#pack").val(),
name= $("#name").val(),
instit= $("#instit").val(),
telp= $("#telp").val(),
email= $("#email").val(),
address= $("#address").val(),
orderno = "test",
order_stat ="phone",
pack_type = "recurring",
rec_period ="monthly";
$.ajax({
type: 'POST',
url: urls,
data: {
pack: pack,
name: name,
instit:instit,
telp: telp,
email: email,
address: address,
orderno : orderno,
order_stat :order_stat,
pack_type : pack_type,
rec_period :rec_period
},
success: function(msg) {
var result = JSON.parse(msg);
if (result.success) {
alert("SUccESSSS");
} else {
alert(result.msg);
}
},
error: function(xhr, status, error){
alert("Failed");
}
});
}
And these are code from controller:
public function saveOrderAction() {
$post = $this->getRequest()->getPost();
$response = $this->getResponse();
/*
$storage = Order\Storage::factory($this->getDb());
$attd = new Order($storage);
$success = false;
$msg = '';
$attd->orderno = $post['orderno'];
$attd->order_stat = $post['order_stat'];
$attd->pack = $post['pack'];
$attd->pack_type = $post['pack_type'];
$attd->rec_period = $post['rec_period'];
$attd->name = $post['name'];
$attd->instit = $post['instit'];
$attd->telp = $post['telp'];
$attd->email = $post['email'];
$attd->address = $post['address'];
//$save = $attd->saveOrder();
if ($attd->saveOrder(true)) { */
$success = true;
$msg = 'Saved Success';
echo "<script type='text/javascript'>alert($msg);</script>";
print_r('test');
printf('test2');
$response->setContent(json_encode(array("success" => $success, "msg" => $msg)));
return $response;
}
But it doesn't show anything. So I have commented and just want to show alert, but it doesn't show. Help me,thanks.
Probably you need to change your URL to:
var urls = '<?php echo $this->baseurl; ?>/order/save-order';
URL's in zend are lowercase. Multiple words are seperated by dashes. When the request is processed the action is camelCased so your action methods are proper PSR-2.
How can I make this form redirect the user to an external site, for example http://amaze.bg, after the user submits the form with the "Register" button and after the form sends the e-mail to antoniya.p#amaze.bg with the entered by the user details?
Here is the PHP code (contact_process.php):
<?php
usleep(500000);
$to = "antoniya.p#amaze.bg";
$author = "";
$email = "";
$comment = "";
$class = "FORM CONTACT ";
if (isset($_POST['input_name']))
$author = $_POST['input_name'];
if (isset($_POST['input_email']))
$email = $_POST['input_email'];
if (isset($_POST['input_class']))
$class = $_POST['input_class'];
if (isset($_POST['input_message']))
$comment = $_POST['input_message'];
$sub="Alumni registration recieved - ".$date1;
$name=$authorlast."< ".$email." >";
$msg = '';
if (#mail($to,$sub,$body,"Content-Type: text/html; charset=iso-8859-1"))
{
$msg = 'Your registration was sent successfully';
//echo '<div class="alert success pngfix">'. $msg .'</div>';
}
else{
$msg = 'Email failed to be sent (mail function not work)';
//echo '<div class="alert error pngfix">'. $msg .'</div>';
}
echo $msg;
?>
And here is the .js part:
jQuery.validator.addMethod(
"math",
function(value, element, params) {
if (value==='')
return false;
return this.optional(element) || value == params[0] + params[1];
},
jQuery.format("Please enter the correct value for {0} + {1}")
);
$('.form-register').validate({
rules: {
input_name: {
minlength: 3,
required: true
},
input_email: {
required: true,
email: true
},
input_message: {
minlength: 0,
required: false
}
,
submitHandler: function(form) {
var a=$('.form-register').serialize();
$.ajax({
type: "POST",
url: "contact_process.php",
data:a,
complete:function(){
},
beforeSend: function() {
},
success: function(data){
if (data=='success') {
$('.form-register').find("input[type=text], textarea").val("");
alert('You have successfully registered. Thank you for being active alumni!');
} else {
alert(data);
}
},
error : function() {
}
});
return false;
}
});
});
Thank you for the help.
After some experiments and help from Charlie I managed to find where and what exactly to add to the code, so that the form sends the information to the server and them redirects the user to another website. The change should be made in the .js file with the addition of the following line:
location = "http://amaze.bg/"
But it should be added under "else" in the .js file, with the "alert" being under "success" for everything to work properly:
success: function(data){
if (data=='success') {
alert(data);
} else {
location = "http://amaze.bg/"
}
},
error : function() {
}
In Your Success Callback, Add location = "http://amaze.bg"
success: function(data) {
// if you echo "success" in your php script when the mail is sent
if (data === 'success') {
$('.form-register').find("input[type=text], textarea").val("");
alert('You have successfully registered. Thank you for being active alumni!');
// Now redirect
location = "http://amaze.bg"
} else {
// if you echo "Some Error Message" from your php script
alert(data);
}
},
Ultimately, You should be sending the proper headers from php so that the success hook in your $.ajax fires on a 200 Status Code and the error hook fires in your $.ajax when a 400 - 500 Status Code is encountered. Please look into HTTP Status Codes and Sending Proper Headers in PHP
I'm trying to make a login script that uses ajaxForm and the validate plugin, but if PHP provides an error, it doesn't know. This is my Javascript
$(function login() {
$("#login").validate({ // initialize the plugin
// any other options,
onkeyup: false,
rules: {
email: {
required: true,
email: true
},
password: {
required: true
}
}
});
$('form').ajaxForm({
beforeSend: function() {
return $("#login").valid();
},
success: function() {
window.location="index.php";
},
error: function(e) {
alert(e);
}
});
});
Keep in mind I'm new to JS and there's probably a better way to do this. What I need is, if when the form is submitted but the username or password is wrong, I need it to not redirect, and give the error alert, but this does not work currently. I've googled this before, and checked here and so far have found nothing.
edit: using the below code, it still doesn't work:
JS
$(function login() {
$("#login").validate({ // initialize the plugin
// any other options,
onkeyup: false,
rules: {
email: {
required: true,
email: true
},
password: {
required: true
}
}
});
$("#login").submit(function(e) {
e.preventDefault();
$.ajax({
type : "POST",
dataType : "json",
cache : false,
url : "/doLogin",
data : $(this).serializeArray(),
success : function(result) {
if(result.result == "success"){
window.location = "/index.php";
}else if(result.result == "failure"){
$("#alert").html("Test");
}
},
error : function() {
$("#failure").show();
$(".btn-load").button('reset');
$("#email").focus();
}
});
});
});
HTML
<div class="shadowbar">
<div id="alert"></div>
<form id="login" method="post" action="/doLogin">
<fieldset>
<legend>Log In</legend>
<div class="input-group">
<span class="input-group-addon">E-Mail</span>
<input type="email" class="form-control" name="email" value="" /><br />
</div>
<div class="input-group">
<span class="input-group-addon">Password</span>
<input type="password" class="form-control" name="password" />
</div>
</fieldset>
<input type="submit" class="btn btn-primary" value="Log In" name="submit" />
</form></div>
PHP
public function login() {
global $dbc, $layout;
if(!isset($_SESSION['uid'])){
if(isset($_POST['submit'])){
$username = mysqli_real_escape_string($dbc, trim($_POST['email']));
$password = mysqli_real_escape_string($dbc, trim($_POST['password']));
if(!empty($username) && !empty($password)){
$query = "SELECT uid, email, username, password, hash FROM users WHERE email = '$username' AND password = SHA('$password') AND activated = '1'";
$data = mysqli_query($dbc, $query);
if((mysqli_num_rows($data) === 1)){
$row = mysqli_fetch_array($data);
$_SESSION['uid'] = $row['uid'];
$_SESSION['username'] = $row['username'];
$_SERVER['REMOTE_ADDR'] = isset($_SERVER["HTTP_CF_CONNECTING_IP"]) ? $_SERVER["HTTP_CF_CONNECTING_IP"] : $_SERVER["REMOTE_ADDR"];
$ip = $_SERVER['REMOTE_ADDR'];
$user = $row['uid'];
$query = "UPDATE users SET ip = '$ip' WHERE uid = '$user' ";
mysqli_query($dbc, $query);
setcookie("ID", $row['uid'], time()+3600*24);
setcookie("IP", $ip, time()+3600*24);
setcookie("HASH", $row['hash'], time()+3600*24);
header('Location: /index.php');
exit();
} else {
$error = '<div class="shadowbar">It seems we have run into a problem... Either your username or password are incorrect or you haven\'t activated your account yet.</div>' ;
return $error;
echo "{\"result\":\"failure\"}";
}
} else {
$error = '<div class="shadowbar">You must enter both your username AND password.</div>';
return $error;
$err = "{\"result\":\"failure\"}";
echo json_encode($err);
}
echo "{\"result\":\"success\"}";
}
} else {
echo '{"result":"success"}';
exit();
}
return $error;
}
In your login script, you will need to return errors in json format.
For Example
In your login script, if your query finds a row in the database for that user, echo this:
echo "{\"result\":\"success\"}";
and if it fails:
echo "{\"result\":\"failure\"}";
You then can parse these in JavaScript like so:
$('form').ajaxForm({
beforeSend: function() {
return $("#login").valid();
},
success: function(result) {
if(result.result == "success"){
window.location = "index.php";
}else if(result.result == "failure"){
alert('Failure!');
}
error: function(e) {
alert(e);
}
}
});
Here's an example of an Ajax script I use to log users into my site, you can use this for reference if needed. This is just to help you get an even broader understanding of what I am talking about:
I return more than just a success and failure for various reasons such as user intuitiveness, but the gist is there.
$("#loginForm").bind("submit", function() {
$("#invalid").hide();
$("#disabled").hide();
$("#error").hide();
$("#failure").hide();
$("#blocked").hide();
var email = document.getElementById("email").value;
var password = document.getElementById("password").value;
if(email != "" && password != ""){
$.ajax({
type : "POST",
dataType : "json",
cache : false,
url : "/ajax/functions/login",
data : $(this).serializeArray(),
success : function(result) {
if(result.result == "success"){
window.location = "/account";
}else if(result.result == "failure"){
$("#invalid").show();
$(".btn-load").button('reset');
$("#email").focus();
}else if(result.result == "disabled"){
$("#disabled").show();
$(".btn-load").button('reset');
$("#email").focus();
}else if(result.result == "blocked"){
$("#blocked").show();
$(".btn-load").button('reset');
$("#email").focus();
}
},
error : function() {
$("#failure").show();
$(".btn-load").button('reset');
$("#email").focus();
}
});
}else{
$("#error").show();
$(".btn-load").button('reset');
$("#email").focus();
}
return false;
});