PHP RESTful services; AJAX and DELETE method with username/password credentials - php

I asked another question related to RESTful services here, and have another question involving DELETE (PUT):
Same kind of situation where I want to send along user credentials (username/password) with my PUT. This is my DELETE service so far:
$http_req = $_SERVER["REQUEST_METHOD"];
switch ($http_req) {
case DELETE:
$user = $acct->read($_REQUEST["usernameDel"], $_REQUEST["passwordDel"]); // this method used to read db table with 1 record
if (!empty($_REQUEST["delTaskId"]) && isset($_REQUEST["usernameDel"]) && isset($_REQUEST["passwordDel"])) {
if ($user == true) {
$delete = fopen("php://input", "r");
$data = stream_get_contents($deleted);
$params;
parse_str($data, $params);
$dropped = $mgr->delete($params["id"]) // calls the method that deletes a particular row based on its id
echo $dropped;
}
}
}
This is the html page I am working with. I updated it to be in a :
<form action="TaskService.php" method="POST">
<label for="usernameDel">Username</label>
<input type="text" name="usernameDel" id="usernameDel" required/><br />
<label for="passwordDel">Password</label>
<input type="password" name="passwordDel" id="passwordDel" required/><br />
<label for="delTaskId">Task ID</label>
<input type="text" name="delTaskId" id="delTaskId" required/><br /><br />
<button type="button" id="btnDelete">Delete Task</button><br /><br />
</form>
This is my ajax code (edit-now using #Devs modifications):
$("#btnDelete").click(function() {
$.ajax({
method: "DELETE",
url: "TaskService.php",
data: { 'username':$("#usernameDel").val(), 'password': $("#passwordDel").val(), 'id': $("#delTaskId").val()},
success: function(theResponse) {
alert(theResponse);
}
});
});
Currently it returns a 200 response, but gives me the error messages I had put in for my Account class (comes back with "Could not find account".
My gut is telling me it has something to do with my $_REQUEST[] superglobals since it's not doing anything with a form action, but I am not all too familiar with passing information via ajax
Thoughts?

Just arranged the ajax format, also some syntax error in the php code.
Note: never tested
Ajax
$(document).ready(function(){
$("#btnDelete").click(function() {
$.ajax({
method: "DELETE",
url: "TaskService.php",
data: { 'username':$("#usernameDel").val(), 'password': $("#passwordDel").val(), 'id': $("#delTaskId").val()},
success: function(theResponse) {
// Output
alert(theResponse); // comment this
}
});
});
});
TaskService.php
<?php
$http_req = $_SERVER["REQUEST_METHOD"];
switch ($http_req) {
case DELETE:
$user = $acct->read($_REQUEST["username"], $_REQUEST["password"]); // this method used to read db table with 1 record
if ($user == true) {
$delete = fopen("php://input", "r");
$data = stream_get_contents($deleted);
$params;
parse_str($data, $params);
$dropped = $mgr->delete($params["id"]); // calls the method that deletes a particular row based on its id
echo $dropped;
}
break;
}
?>

Found out why my validation wasn't working! I feel so blind!
I was ignoring the fact that the delete action was taking username, password, and id as parameters....as such, validation wasn't going to work because the "php://input" file hadn't been opened to parse through all 3 parameters.
Here's my updated PHP that works:
// I needed to access the file FIRST before doing anything with the parameters passed from AJAX
$deleted = fopen("php://input", "r");
$data = stream_get_contents($deleted);
$params;
parse_str($data, $params);
$user_auth = $acctMgr->readAcct($params["username"], $params["password"]);
if ($user_auth == true) {
$rows = $mgr->delete($params["id"]);
echo $rows;
} else {
echo "User not authenticated";
}

Related

How to use post() jquery method with codeigniter form_validation

I want to validate a form without refreshing the page using the .post() jQuery method.
I use codeigniter for validation. Could you please tell me how to make it right? I find it pretty confusing ...
Here is the jQuery code:
$(document).ready(function(){
$(".form_errors").hide();
$("#send").on("click",function(){ //the submit button has the id="send"
$(".form_errors").hide(); //these are <p> for each input to show the error
var user=$("input.box");
var data={};
var names=$("input.box").attr("name");
for(i=0;i<user.length;i++){
name=names[i];
value=user[i].val();
data.name=value;
}
$.post('ksite/account',
data,
function(result){
$("div.answer").html(result);
for(i=0;i<user.length;i++){
error_message=<?php echo form_error("?>names[i]<?php ");?>;
$("p#error_"+names[i]+".form_errors").html(error_message).show();
}
}
return false;});
});
form_error is a CodeIgniter function. (I suppose someone who used ci is familiar with).
The form:
<p id="error_user" class="form_errors"></p>
<input type="text" class="box" name="user">
<p id="error_password" class="form_errors"></p>
<input type="password" class="box" name="password">
<input type="submit" id="send">
Is the form tag neccessary ? And if yes,do i have to mention action and method ?
Do I have to specify the type of the response?
And in ksite/account I do:
/* ...... */
if (!this->form_validation->run(''account")) {
echo "The account couldn't be made";
} else {
echo "The account was successfully created ";
}
P.S.Although you may not be familiar with codeigniter, I would appreciate if someone could tell me if the code is correct and what improvements could be made.
Here is what I did.
You have to Ajax for getting data without refreshing the page.
HTML Page
$form = $(form);
var url = $form.attr('action');
dataString = $form.serialize();
$.ajax({
type: "POST",
url: url,
data: dataString,
dataType: "json",
success: function(data) {
$(data).each(function(j,details){
var status = details.status;
var message = details.message;
$('#message_ajax_register').show();
$('#message_ajax_register').html('<div class="alert alert-success">'+message+'</div>');
});
}
});//end of $.ajax**
I am first setting up the rules in my controller method and then validating it.
Controller
public function update_fest()
{
if($this->input->post())
{
$this->form_validation->set_rules('txtgpluswebsite', 'Google Plus Page URL', 'trim|xss_clean|prep_url');
$this->form_validation->set_error_delimiters('<div class="error">', '</div>');
if($this->form_validation->run() == false){
$message = validation_errors();
$data = array('message' => $message,'status'=>0);
}
else{
$message = $this->add_fest_database();
$data = $message;
}
}
else{
$message = "Fest details are required";
$data = array('message' => $message,'status'=>0);
}
$this->output->set_content_type('application/json');
$json = $this->output->set_output(json_encode($data));
return $json;
}
If validation run is not false, then go to add_fest_database(other function). In that function,
function add_fest_database()
{
$youtubeWebsite = $this->input->post('txtyoutubewebsite');
$gplusWebsite = $this->input->post('txtgpluswebsite');
$this->load->model('model_fest');
$data = array("fest_youtube"=>$youtubeWebsite,"fest_gplus"=>$gplusWebsite);
return data;
}

Ajax returning undefined from JSON - Login system & best practice

I'm receiving an error of undefined when I try and retrieve values in the JSON. I'm new to ajax / js etc and trying to create an 'elegant' drop down login down.
I've tried various things and read a few of the posts that I've found here but I notice that the layout has changed somewhat and I also notice that I'm using success and now that deprecated.
So could I ask for help in firstly understanding what the problem is and how i solve the undefined issue and secondly what is the best way to achieve this. I'd prefer not to use deprecated code if I can help it.
I've also noticed that since changing the code so that it gets to the 'success' park of the ajax call, the drop down box no longer rolls back up or displays the error messages. -.-
Thanks in advance.
The Ajax
function validLogin(){
$('.error').hide();
var username = $('#username').val();
if(username == ""){
$('label#usernameError').show();
$('input#username').focus();
return false;
}
$('.error').hide();
var password = $('#password').val();
if(password == ""){
$('label#passwordError').show();
$('input#password').focus();
return false;
}
var params = {username: username, password: password};
var url = "../js/loginProcessAjax.php";
$("#statusLogin").show();
$("#statusLogin").fadeIn(400).html('<img src="images/loading.gif" />');
$.ajax({
type: 'POST',
url: url,
data: params,
datatype: 'json',
beforeSend: function() {
document.getElementById("statusLogin").innerHTML= 'checking...' ;
},
success: function(data) {
alert("success Area ofAjax");
$("#statusLogin").hide();
if(data.success == true){
alert("if data.success Area of Ajax");
alert(data.message);
}else{
alert("data.message... " + data.message);//undefined
$("#errorConsole").html(data.message);
}
},
error: function( error ) {
console.log(error);
}
}, 'json');
}
PHP
<?php
if($_POST){
if($users->userExists($username) === false){
$data['message'] = "User doesn't exist";
$data['success'] = false;
}else if($users->userExists($username) === false){
$data['message'] = 'That username does not exist';
$data['success'] = false;
}else if($users->emailActivated($username) === false){
$data['message'] = 'You need to activate the account, please check your email.';
$data['success'] = false;
}else{
$login = $users->login($username, $password);
if($login === false){
$data['message'] = 'Incorrect Password or username';
$data['success'] = false;
}else{
$data['success'] = true;
//destroy old session and create new - prevents session fixation attacks
session_regenerate_id(true);
//all details are correct - the method returns the id to be sotred as a session
$_SESSION['id'] = $login;
}
echo json_decode($data);
}
}
Markup:
<form method="post" action="" id="ourLoginFormID_JS">
<div class="ourContactFormElement2">
<label for="username">Username:</label>
<input type="text" id="username" name="username" autocomplete="off" class="required" value="<?php if(isset($_POST['username'])) echo htmlentities($_POST['username']); ?>" />
</div>
<div class="ourContactFormElement2">
<label for="password">Password:</label>
<input type="password" id="password" name="password" autocomplete="off" class="required"/>
</div>
<div class="ourContactFormElement2">
<label> </label>
<input type="submit" name="loginButton" id="loginButton" value="Login!" onclick="validLogin(); return false;"/>
</div>
<div id="statusLogin"></div>
</form>
Your if/else/else/else chain only outputs json if the final else block executes. You need to move the json_encode call outside the block:
if (...) {
} else if (...) {
} else if (...) {
} else {
...
}
echo json_encode($data);
This way your code will output the encoded $data, no matter WHICH of the various if() clauses actually executed.
The problem with your undefined error is this:
datatype: 'json',
Javascript is case sensitive and the property is dataType not datatype. Because of this, jQuery is not being told to automatically parse the JSON and so you're just getting the JSON string, causing the undefined error on data.message.
Also I don't see where you access $_POST['username'] or where you instantiate the $users object, I see $username but not $_POST['username'].
A couple of things. You might want to explicitly use contentType parameter of application/json here so that it is clear that you are both sending and receiving JSON.
The main issue is that when sending POST data to PHP that is not form-encoded, $_POST will not be populated automitically. You need to read http raw input like this:
$json = file_get_contents('php://input');
if(!empty($json)) { // replace your if($_POST) with this
$object = json_decode($json);
$username = $object->username;
$password = $object->password;
// the rest of your code
}

php - codeigniter ajax form validation

Hi I’m quite new to jquery -ajax and I’d like some help please to join it with CI.
I have followed this tutorial on Submitting a Form with AJAX and I’d like to add this functionality to my CodeIgniter site. What I’d like to do is when the user submits the form, if there are any validation errors to show the individually on each input field (as in native ci process), or if this is not possible via validation_errors() function. If no errors occured to display a success message above the form.
Here's my code so far:
my view
// If validation succeeds then show a message like this, else show errors individually or in validation_errors() in a list
<div class="alert alert-success">Success!</div>
<?php echo validation_errors(); //show all errors that ajax returns here if not individualy ?>
<?php echo form_open('admin/product/add, array('class' => 'ajax-form')); ?>
<p>
<label for="product_name">Product *</label>
<input type="text" name="product_name" value="<?php echo set_value('product_name', $prod->product_name); ?>" />
<?php echo form_error('product_name'); ?>
</p>
<p>
<label for="brand">Brand</label>
<input type="text" name="brand" value="<?php echo set_value('brand', $prod->brand); ?>" />
<?php echo form_error('brand'); ?>
</p>
...
my controller
public function add($id){
// set validation rules in CI native
$rules = $this->product_model->rules;
$this->form_validation->set_rules($rules);
if ($this->form_validation->run() === true) {
// get post data and store them in db
$data = $this->input_posts(array('product_name', 'brand', 'category_id', 'description'));
$this->product_model->save($data, $id);
// no errors - data stored - inform the user with display success-div
} else {
// validation failed - inform the user by showing the errors
}
//load the view
$this->load->view('admin/products/add', $data);
}
and here’s the js script
$(document).ready(function () {
$('form.ajax-form').on('submit', function() {
var obj = $(this), // (*) references the current object/form each time
url = obj.attr('action'),
method = obj.attr('method'),
data = {};
obj.find('[name]').each(function(index, value) {
// console.log(value);
var obj = $(this),
name = obj.attr('name'),
value = obj.val();
data[name] = value;
});
$.ajax({
// see the (*)
url: url,
type: method,
data: data,
success: function(response) {
console.log(response); // how to output success or the errors instead??
}
});
return false; //disable refresh
});
});
How should I pass my validation results (either success or the post errors) throught the ajax request and display them on my view??
From some little research I did I've found that you can use a single controller, that holds both the native proccess and the ajax request (instead of using 2 controllers), but my main difficulty is, I don't understand how the results of the validation will pass through the js script and display them on my view?? Please note that I don't want to display anything on an alert box, instead show the results on a div or the errors individualy(if possible).
EDIT I did some changes to my application, here's the code so far:
the controller
public function manage($id = NULL){
$this->load->library('form_validation');
$data['categ'] = $this->category_model->with_parents();
//fetch a single product or create(initialize inputs empty) a new one
if (isset($id) === true) {
$data['prod'] = $this->product_model->get($id);
$data['attr'] = $this->attribute_model->get_by('product_id', $id, null, true);
} else {
$data['prod'] = $this->product_model->make_new();
$data['attr'] = $this->attribute_model_model->make_new();
}
if (isset($_POST['general_settings'])) {
if ($this->form_validation->run('product_rules') === true) {
// get post inputs and store them in database
$data = $this->product_model->input_posts(array('product_name', 'brand', 'category_id', 'general_description'));
$this->product_model->save($data, $id);
$status = true;
} else {
// validation failed
$status = validation_errors();
}
if ( $this->input->is_ajax_request() ) {
echo json_encode($status);
exit;
}
redirect('admin/product');
}
//if (isset($_POST['attributes_settings'])) { the same thing here }
// load the view
$this->load->view('admin/products/manage', $data);
}
and the js
success: function(response) {
//console.log(response);
if (data.status === true) {
$('#ajaxResults').addClass('alert alert-success').html(response);
} else {
$('#ajaxResults').addClass('alert alert-error').html(response);
};
}
But I'm having some issues
Although I get the error messages from validation_errors() as an alert-error when there are no errors I get the true in an alert-error too, insted of alert-success.
2.how should I return the success message too? eg. a message saying "Saves were done!".
Althought in a non-ajax-request the data are stored in the database, in case fo ajax the don't store. Any ideas What may be wrong???
HTML:
<div id="ajaxResults"></div>
Javascript ajax:
success: function(response) {
$('#ajaxResults').text(response);
}
this script you've wrote is only if the validation succeeds, right?
Wrong. The code in "success" gets executed any time you get a response back from the server (assuming the HTTP header is 200). Does your javascript knows if the server has any error for you? No.
You need your JavaScript to recognize if the validation failed or succeeded. You have many ways to do that. One of these could be sending the message to display followed by a 0 or 1.
So your PHP will looks like:
return "0 " . $errorMessage;
and
return "1 " . $successMessage;
and your javascript should then recognize, with if statement and substring, if the message starts with 0 or with 1.
Use this way i hope this will work for you
<script type='text/javascript'>
var base_url = '<?=base_url()?>';
function ajax_call()
{
var ids = $("#all_users").val();
$.ajax({
type:"POST",
url: base_url+"expense/home/get_expense",
data: "userid=" + ids,
success: function(result){
$("#your_div_id").html(result);
}
});
}
</script>

strange behavior while including a class in php

I'm experiencing a strange behavior with PHP. Basically I want to require a class within a PHP script. I know it is straight forward and I did it before but when I do so, it change the behavior of my jquery (1.8.3) ajax response. I'm running a wamp setup and my PHP version is 5.4.6.
Here is a sample as for my index.html
head (omitting the jquery js include)
<script>
$(document).ready(function(){
$('#submit').click(function(){
var action = $('#form').attr('action');
var form_data = {
fname: $('#fname').val(),
lname: $('#lname').val(),
phone: $('#phone').val(),
email: $('#email').val(),
is_ajax: 1
};
$.ajax({
type: $('#form').attr('method'),
url: action,
data: form_data,
success: function(response){
switch(response){
case 'ok':
var msg = 'data saved';
break;
case 'ko':
var msg = 'Oops something wrong happen';
break;
default:
var msg = 'misc:<br/>'+response;
break;
}
$('#message').html(msg);
}
});
return false;
});
});
</script>
body
<div id="message"></div>
<form id="form" action="handler.php" method="post">
<p>
<input type="text" name="fname" id="fname" placeholder="fname">
<input type="text" name="lname" id="lname" placeholder="lname">
</p>
<p>
<input type="text" name="phone" id="phone" placeholder="phone">
<input type="text" name="email" id="email" placeholder="email">
</p>
<input type="submit" name="submit" value="submit" id="submit">
</form>
And as for the handler.php file:
<?php
require('class/Container.php');
$filename = 'xml/memory.xml';
$is_ajax = $_REQUEST['is_ajax'];
if(isset($is_ajax) && $is_ajax){
$fname = $_REQUEST['fname'];
$lname = $_REQUEST['lname'];
$phone = $_REQUEST['phone'];
$email = $_REQUEST['email'];
$obj = new Container;
$obj->insertData('fname',$fname);
$obj->insertData('lname',$lname);
$obj->insertData('phone',$phone);
$obj->insertData('email',$email);
$tmp = $obj->give();
$result = $tmp['_obj'];
/*
Push data inside array
*/
$array = array();
foreach($result as $key => $value){
array_push($array,$key,$value);
}
$xml = simplexml_load_file($filename);
// check if there is any data in
if(count($xml->elements->data) == 0){
// if not, create the structure
$xml->elements->addChild('data','');
}
// proceed now that we do have the structure
if(count($xml->elements->data) == 1){
foreach($result as $key => $value){
$xml->elements->data->addChild($key,$value);
}
$xml->saveXML($filename);
echo 'ok';
}else{
echo 'ko';
}
}
?>
The Container class:
<?php
class Container{
private $_obj;
public function __construct(){
$this->_obj = array();
}
public function addData($data = array()){
if(!empty($data)){
$oldData = $this->_obj;
$data = array_merge($oldData,$data);
$this->_obj = $data;
}
}
public function removeData($key){
if(!empty($key)){
$oldData = $this->_obj;
unset($oldData[$key]);
$this->_obj = $oldData;
}
}
public function outputData(){
return $this->_obj;
}
public function give(){
return get_object_vars($this);
}
public function insertData($key,$value){
$this->_obj[$key] = $value;
}
}
?>
The strange thing is that my result always fall under the default switch statement and the ajax response fit both present statement. I noticed then if I just paste the Container class on the top of the handler.php file, everything works properly but it kind of defeat what I try to achieve.
I tried different way to include the Container class but it seem to be than the issue is specific to this current scenario.
I'm still learning PHP and my guess is that I'm missing something really basic. I also search on stackoverflow regarding the issue I'm experiencing as well as PHP.net, without success.
Regards,
My guess is that you have white space at the end of your class file, which is causing the output to be ' ok' instead of 'ok'. This can be the result of using certain applications to edit your files, or accidentally adding a space after the closing ?>. Try removing the closing ?> in your php class all together. This is not only allowed (php will automatically end processing at the end of the file anyways), but often encouraged in many style guides to prevent exactly the kind of thing that you are describing.
Another thing I usually do for this type of situation, is instead of returning a plain string, I return a json string, which jQuery will automatically turn into a javascript object for you. This would also prevent, or at least let you know right away that you are having the above type of problem.
so php would echo like this:
exit( json_encode( array( 'status' => 'ok' ) ) );
and jQuery would receive like this:
$.ajax({
type: $('#form').attr('method'),
url: action,
data: form_data,
dataType: 'json',
success: function(response){
switch(response.status){
case 'ok':
var msg = 'data saved';
break;
case 'ko':
var msg = 'Oops something wrong happen';
break;
default:
var msg = 'misc:<br/>'+response;
break;
}
$('#message').html(msg);
}
});
Note the added dataType parameter in the ajax call, as well as using response.status to check the status property that we created in PHP.
This also allows you to return more than one value in your response. You can build the object or array however you like on the PHP side, and you would basically receive the same as a javascript object on the javascript side.

PHP: How to excute query without form postback?

I have a form in which i want to do the validations. But there is a field which i want to validate writing a query. I dont want the form to postback because after postback all the values filled in the form are lost. Is there any way i can write a query without postback or if i have to postback how to retain the values ? Please help
If you use AJAX (jQuery), you can post an XML Request without refreshing the browser, if this is what you need.
For this, just create a form with some textfields and a submit button, give everything an ID and add an click-Listener for the button:
$('#submit-button').click(function() {
var name = $('#username').val();
$.ajax({
type: 'POST',
url: 'php_file_to_execute.php',
data: {username: name},
success: function(data) {
if(data == "1") {
document.write("Success");
} else {
document.write("Something went wrong");
}
}
});
});
If the user clicks on the button with the "submit-button"-ID, this function is called. Then you send the value of the textfield using POST to the php_file_to_execute.php. Inside this .php-File, you can validate the username and output theresult:
if($_POST['username'] != "Neha Raje") {
echo "0";
} else {
echo "1";
}
I hope that I could help you! :)
You might want to rephrase what you wrote, its a bit unclear. FYI I do it like this;
<form method="post">
Text 1: <input type="text" name="form[text1]" value="<?=$form["text1"]?>" size="5" /><br />
Text 2: <input type="text" name="form[text2]" value="<?=$form["text2"]?>" size="5" /><br />
<input type="submit" name="submit" value="Post Data" />
</form>
And when I am processing the data, it's like this;
<?php
if ($_POST["submit"]) {
$i = $_POST["form"];
if ($i["text1"] or ..... ) { $error = "Something is wrong."; }
if ($i["text2"] and ..... ) { $error = "Maybe right."; }
if (!$error) {
/*
* We should do something here, but if you don't want to return to the same
* form, you should definitely post a header() or something like that here.
*/
header ("Location: /"); exit;
}
//
}
if (!$_POST["form"] and !$_GET["id"]) {
} else {
$form = $_POST["form"];
}
?>
By this method, the values are not lost unless you set them to get lost.
Use jQuery's $.post() method as:
$('#my_submit_button').click(function(event){
event.preventDefault();
var username = $('#username').val();
$.post('validate.php', {username: username, my_submit_button: 1}, function(response){
console.log(response); //response contain either "true" or "false" bool value
});
});
In validate.php get the username from your form asynchronously as like this:
if(isset($_POST['my_submit_button']) && $_POST['my_submit_button'] == 1 && isset($_POST['username']) && $_POST['username'] != "") {
// now here you can check your validations with $_POST['username']
// after checking validations, return or echo appropriate boolean value like:
// if(some-condition) echo true;
// else echo false;
}
Note: Please consider knowing security-related vulnerabilities and other issues before using AJAX for executing database-altering scripts.

Categories