I tried creating a universal delete function in 3 ways.
function DeleteByID($table, $id){
1. DB::table("$table")->delete("$id");
2. DB::table("$table")->find("$id")->delete();
3. DB::table("$table")->where('id', '=', "$id")->delete();
}
I'm using ajax to send the request to an Ajax Controller class, which sends it to the according controller class of the specific subject. Everything goes fine with the ajax request, it does what it should do. But deleting something from the table doesn't work.
And yes, I am putting the right table names into the $table parameter when I'm calling the DeleteByID($table, $id) function.
Update 1
removed every double "" from the ajax request to the call of the delete function.
DB::table($table)->where('id', '=', $value)->delete();
Is what it is now. Still doesn't work.
Update 2
This triggers the DeleteRole function. This will open a modal, asking if you are sure you want to delete the record. there will be another button with onclick="DeleteRole(this.id, true)" with ofcourse the id send with it.
<a id="{{$role->id}}" onclick="DeleteRole(this.id, false)">
<button class="btn btn-neutral btn-icon btn-round" data-toggle="modal"
id="{{$role->id}}" data-target="#rolesModalDelete">
<i class="material-icons" style="color:rgba(185,14,22,0.81)">clear</i>
</button>
</a>
AJAX Request:
function DeleteRole(id, bool){
let contentModal = $('#DeleteRoleContent');
if(bool === false){
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
url: '/DeleteRole',
type: 'POST',
dataType: "json",
beforeSend: function (xhr) {
const token = jQuery('meta[name="csrf_token"]').attr('content');
if (token) {
return xhr.setRequestHeader('X-CSRF-TOKEN', token);
}
},
data: {
roleID: id,
popup: bool,
},
success: function (data) {
contentModal.empty();
contentModal.append(data);
}
});
}else if (bool === true){
let row = $('#' + id);
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
url: '/DeleteRole',
type: 'POST',
dataType: "json",
beforeSend: function (xhr) {
const token = jQuery('meta[name="csrf_token"]').attr('content');
if (token) {
return xhr.setRequestHeader('X-CSRF-TOKEN', token);
}
},
data: {
roleID: id,
popup: bool,
},
success: function (data) {
row.empty();
}
});
}
}
Update 3
The if statement where it checks if the $_POST['popup'] is true or not, was ignored. Changed it, so the deletion works now. But now the succes handler won't be called. the ajaxrequest returns 200 OK.
public function RoleDelete()
{
if($_POST['roleID']){
if($_POST['popup'] == 0){
$htmlObject = $this->roleController->GetData($_POST['roleID']);
echo json_encode($htmlObject);
} else {
if($_POST['roleID'] !== null) {
$this->db->DeleteByID('rollen', $_POST['roleID']);
} else {
echo json_encode('ID is null');
}
}
} else {
echo json_encode('Geen gegevens gevonden, is het record al verwijderd? AC 256;');
}
}
You should try this
Do not use "" for variable
1. DB::table($table)->delete($id);
2. DB::table($table)->find($id)->delete();
3. DB::table($table)->where('id', '=', $id)->delete();
I apologize if this comes off as a "make sure it's plugged in" kind of answer, but sometimes the simple stuff is the easiest to overlook, especially when you're tunnel-visioned on the code. That said, are you sure your DB credentials actually have delete-permissions?
The if statement where it checks if the $_POST['popup'] is true or not, was ignored. Changed it, so the deletion works now. But now the succes handler won't be called. the ajaxrequest returns 200 OK.
public function RoleDelete(){
if($_POST['roleID']){
if($_POST['popup'] == 0){
$htmlObject = $this->roleController->GetData($_POST['roleID']);
echo json_encode($htmlObject);
} else {
if($_POST['roleID'] !== null) {
$this->db->DeleteByID('rollen', $_POST['roleID']);
} else {
echo json_encode('ID is null');
}
}
} else {
echo json_encode('Geen gegevens gevonden, is het record al verwijderd? AC 256;');
}
}
Related
I have a project in Cakephp 3.6 in which 3 actions in MessageController are called by Ajax. I have a problem, however, when I send a request to one of the action, XHR returns to me this:
{
"message": "CSRF token mismatch.",
"url": "\/messages\/changepriority\/8",
"code": 403,
"file": "D:\\xampp\\htdocs\\myapp\\vendor\\cakephp\\cakephp\\src\\Http\\Middleware\\CsrfProtectionMiddleware.php",
"line": 195
}
This is one of the action what I try to call from Ajax:
public function changepriority($id=null)
{
$this->autoRender = false;
$message = $this->Messages->get($id);
$message->priority = ($message->priority === false) ? true : false;
if ($this->Messages->save($message)) {
echo json_encode($message);
}
}
And this is my ajax:
$(".email-star").click(function(){
var idmessage = this.id;
$.ajax({
headers : {
'X-CSRF-Token': $('[name="_csrfToken"]').val()
},
dataType: "json",
type: "POST",
evalScripts: true,
async:true,
url: '<?php echo Router::url(array('controller'=>'Messages','action'=>'changepriority'));?>' +'/'+idmessage,
success: function(data){
if(data['priority'] === false) {
$("#imp_" + idmessage).removeClass("fas").removeClass('full-star').addClass( "far" );
}
else {
$("#imp_" + idmessage).removeClass("far").addClass( "fas" ).addClass("full-star");
}
}
});
});
I have read the documentation about Cross Site Request Forgery, and I tried to turn off the Csrf for these action first with:
public function beforeFilter(Event $event)
{
$this->getEventManager()->off($this->Csrf);
}
and then with:
public function beforeFilter(Event $event)
{
$this->Security->setConfig('unlockedActions', ['index', 'changepriority']);
}
But nothing. The Xhr return always the CSRF token mismatch.
What can I do ?
Edit:
I change the action in this way:
public function changepriority($id=null)
{
$this->autoRender = false;
$message = $this->Messages->get($id);
$message->priority = ($message->priority === false) ? true : false;
if ($this->Messages->save($message)) {
$content = json_encode($message);
$this->response->getBody()->write($content);
$this->response = $this->response->withType('json');
return $this->response;
}
}
In that way the action works. Can it be like that?
First check your $('[name="_csrfToken"]').val() output.
If you didn't get any output, need to check csrfToken hidden field is exist or not. Just right click in your page and click View Page Source
If not exist, you don't follow proper way when you create Form. Basically, when forms are created with the Cake\View\Helper\FormHelper, a hidden field is added containing the CSRF token.
If everything is correct, add the following line inside your ajax call after header
beforeSend: function (xhr) {
xhr.setRequestHeader('X-CSRF-Token', $('[name="_csrfToken"]').val());
},
Ps. Disabling the CSRF is not recommended by cakePHP and most of the developer aware of this. Hope this help.
beforeSend: function (xhr) {
xhr.setRequestHeader('X-CSRF-Token', <?= json_encode($this->request->getAttribute('csrfToken')) ?>);
},
I'm working on a project where I have some jQuery code that is supposed to check if a certain row in the database exists. If the row does exist, The code within the success stage gets executed. But the problem I have with this script is when the 'checkdb' function gets executed the code within success happens even though the row doesn't exist in the database. What is causing this?
jQuery code
checkdb = function () {
$.ajax({
type: 'GET',
url: '/droplet/get/' + {{ $webshop->id }},
data: '_token = <?php echo csrf_token() ?>',
success: function(data) {
var id = setInterval(frame, 500);
function frame() {
console.log('Executing "Frame"');
if (width2 >= 30) {
clearInterval(id);
clearInterval(mainInterval);
installWebshop();
alert('This is done');
} else {
width2++;
elements(width2);
}
}
},
error: function(data) {
alert('Something went wrong' . data);
}
});
console.log('Executing "checkDB"');
};
mainInterval = setInterval(checkdb,1000 * 60);
The jQuery above gets executed every minute, To check if the row is present.
The PHP code below is supposed to check if the row in the database exists. If it does, it should return a response which then ends up in the succeeding stage in jQUery. If it does not already exist, Do something else
PHP code
public function getAll(Request $request, $id)
{
$droplet = Droplet::where("webshop_id", "=", $id)->exists();
if ($droplet != null) {
$info = Droplet::where("webshop_id", "=", $id)->get();
return response()->json(array($info));
} else {
return response()->json('There is nothing');
}
}
Why is it executing the succeeding stage even though the row does not already exist? Thanks in advance
response('content', 200, $headers) and `json()` helper also takes three param `json($data, status, $headers)`
methods take three parameters replace the content of the else
like
public function getAll(Request $request, $id)
{
$droplet = Droplet::where("webshop_id", "=", $id)->exists();
if ($droplet != null) {
$info = Droplet::where("webshop_id", "=", $id)->get();
return response()->json(array($info));
} else {
return response()->json('There is nothing',404);
}
}
In jQuery, success block gets executed when response status code is 200. If you send status code as 404 which is in else block when DB is not exist, then error block will get executed instead of success. Laravel by default will send 200 as status code for AJAX requests in response.
Add dataType:"JSON"
checkdb = function () {
$.ajax({
type: 'GET',
url: '/droplet/get/' + {{ $webshop->id }},
data: '_token = <?php echo csrf_token() ?>',
datatype:'JSON',
success: function(data) {
var id = setInterval(frame, 500);
function frame() {
console.log('Executing "Frame"');
if (width2 >= 30) {
clearInterval(id);
clearInterval(mainInterval);
installWebshop();
alert('This is done');
} else {
width2++;
elements(width2);
}
}
},
error: function(data) {
alert('Something went wrong' . data);
}
});
console.log('Executing "checkDB"');
};
mainInterval = setInterval(checkdb,1000 * 60);
I am trying to get foreach data I am using jquery to submit the page without a refresh being required for some reason jQuery is not retrieving the foreach data, It needs to loop through each admin input field to see each data seperatly.
If it's not possible I won't use JQuery for this but thought I ask
PHP:
if(isset($_POST['admin_add']) AND is_array($_POST['admin_add'])) {
foreach($_POST['admin_add'] as $admin_add) {
if(strlen($admin_add) > 0) {
// $sql=mysql_query("insert into hobbies(hobby)values('$hobby')");
}
}
}
die('<h3>'.$admin_add.'<h3/>');
jQuery:
$(document).ready(function () {
var clan_url_string = window.location.search.substring(1);
// Make a function that returns the data, then call it whenever you
// need the current values
function getData() {
return {
clan_title_edit: $('#clan_title_edit').val(),
clan_des: $('#clan_des').val(),
admin_add: $('#admin_add').val(),
//remember_me: ($('#remember_me').is(':checked')) ? 1 : 0
}
}
$(window).load(function(){
$('#background_cycler').fadeIn(1500);//fade the background back in once all the images are loaded
setInterval('cycleImages()', 4000); // run every 4s
});
function loading(e) {
$('#loading_status').show();
}
function hide_loading(e) {
$('#loading_status').hide();
}
function success_message(e) {
$('#success_login').html("We're Just Signing You In");
}
function clearfields() {
$('#login-username').val(''); //Clear the user login id field
$('#login_password').val(''); //Clear the user login password field
}
function check(e) {
e.preventDefault();
$.ajax({
url: 'ajax/save_settings.php?'+clan_url_string,
type: 'post',
error: function () {
//If your response from the server is a statuscode error. do this!!!'
hide_loading(e);
$('#status_message').html('<b>Something Has Gone Wrong</b><br> Please Try Again Later');
},
beforeSend: function () {
loading(e);
},
data: {
clan_title_edit: $('#clan_title_edit').val(),
clan_des: $('#clan_des').val(),
admin_add: $('#admin_add').val(),
remember_me: ($('#remember_me').is(':checked'))
}, // get current values
success: function (data) {
//if your response is a plain text. (e.g incorrect username or password)
hide_loading(e);
$('#status_message').hide();
$('#status_message').fadeIn(1000).html(data);
}
});
}
// Don't repeat so much; use the same function for both handlers
$('#login_content').keyup(function (e) {
if (e.keyCode == 13) {
var username = $('#login-username').val();
check(e);
}
});
$('#submit_clan_settings').click(function (e) {
if (e.keyCode != 13) {
check(e);
}
});
There's the php and jquery
Thanks
Yes its SQL injection prone, havent fix this yet and I should be using mysqli or $db->);
I am using codeigniter, i have written a function to check if a user password exists which it does. This is my model
The model: user
public function get_some_password($username,$password) {
$this->db->where('user_password', $password);
$this->db->where('user_username',$username);
$query=$this->db->get('some_users_table');
if($query->num_rows()==1){
return true;
}else{
return false;
}
the controller
public function check_password() {
$username=$this->uri->segment(3);
$temp_pass= $this->input->post('current_password');
$password=md5($temp_pass);
$this->user->get_some_password($username,$password);
}
The ajax on the view
//done on page load
var success1 = $(".success"); //a div on the view that appears if success
var error1 = $(".error"); //a div on the view that appears if error
success1.hide();
error1.hide();
$('#change_password').click(function() {
var username = $('#username').val();
dataString2 = $('#changpassword').serialize();
$.ajax({
type: "POST",
url: '<?php echo base_url(); ?>controller_name/check_password/' + username,
data: dataString2,
success: function() {
$('.success').html('password successfully updated!'),
success1.slideDown('slow');
},
error: function() {
$('.error').html('Wrong current password!'),
error1.slideDown('slow');
}
});
The problem: Ajax loads the success div even when the username or password returned is false, where am i missing something
This is a correct behavior as jquery error is executed when response code is not 200:
1) You can parse returned value in success method.
e.g.
success: function(data) {
if (data == 'true') {
// Success
} else {
// Error
}
}
2) You can return error code from server 404, 500, 503 ... To trigger execution of error function.
e.g.
header("Status: 404 Not Found");
note: Header should executed before any output is done.
Try in your controller:
public function check_password() {
$username=$this->uri->segment(3);
$temp_pass= $this->input->post('current_password');
$password=md5($temp_pass);
if(!$this->user->get_some_password($username,$password)) {
$this->output->set_status_header('500');
return;
}
...
}
I am sure this is probably something simple that i am not doing. Running livevalidation.js jquery plugin (livevalidation.com). It provides for custom function callbacks. I am trying to check for username availability. The server side is working fine and I am getting the proper responses back in my data var...
Here is my JS:
Validate.Username = function(value, paramsObj) {
var paramsObj = paramsObj || {};
var message = paramsObj.failureMessage || "Username is not available";
var isSuccess = true;
$.post("<?php echo fURL::getDomain(); ?>/ajax/username",
function(data) {
if (data.status === 'notavailable')
{
Validation.fail('oops, not available.');
}
});
};
I am calling it using:
var username = new LiveValidation('username', { validMessage: curr_username + "is available!" });
username.add( Validate.Presence, { failureMessage: "Choose a username" });
username.add( Validate.Username, { failureMessage: "Username is not available." } );
The problem I am getting is:
Uncaught ReferenceError: Validation is not defined
If I put the Validation.fail() outside of my .post() function it works fine. So am pretty sure it is because it's not able to be referenced inside the .post() function.
I've tried using a callback function
if (data.status === 'notavailable')
{
status_not_available();
}
I get the same error.
I realize this is something probably extremely simple, but any help would be appreciated. Thank you in advance.
i am having the same issue.
Ive found the following, http://forum.jquery.com/topic/ajax-return-value-on-success-or-error-with-livevalidation but have not been able to get it working.
BUT YES! At this very moment i made som (crappy) javascript addon that made it behave, i think :)
This is what i use.
function check_avail(name, id, postUrl)
{
var dataVal = name+'='+$(id).val();
var isaccepted = ''
$(id).next('div').remove();
$(id).after("Undersøger om "+name+" er ledigt");
$.ajax({
url: postUrl,
cache: false,
type: 'post',
dataType: 'json',
data: dataVal,
async: false,
success: function(data) {
if( data.success == 'true' )
{
$('#'+name+'-availability').remove();
//return false;
isaccepted = false;
}
if( data.success == 'false' )
{
$('#'+name+'-availability').remove();
// name.destroy();
isaccepted = true;
}
}
});
if (isaccepted == false) {
return false;
} else{
return true
};
}
And
f1.add( Validate.Custom, { against: function() {
return check_avail( 'brugernavn', '#ft001', 'usernamecheck.asp' );
}, failureMessage: 'Brugernavnet er optaget' } );
Hope it helps you :)
The json query you can read about on the link in the begining :)
(I am not at all skilled at javascript, and the "isaccepted" solution could problalby be made a lot better)
try to change it from Validation.fail to Validate.fail
try wrapping it in another function and try putting your validateStatus(status) function both inside and outside your Validate.Username function. example below is inside
Validate.Username = function(value, paramsObj) {
var paramsObj = paramsObj || {};
var message = paramsObj.failureMessage || "Username is not available";
var isSuccess = true;
$.post("<?php echo fURL::getDomain(); ?>/ajax/username",
function(data) {
validateStatus(data.status);
});
function validateStatus(status){
if (status === 'notavailable'){
Validate.fail("not available");
}
}
};