How can I delete files with CakePHP and Ajax? - php

I'm in a page called 'add.cpt' that has a list of images. The user has the option to remove the images but I can't make it work. In the event of click I try to call an ajax trying to pass the name of the image and id of the item (.../item/imageName) but it does delete the image and alerts what seems to be the content of delete_photo_file.ctp. It looks like the ajax is using the URL but it is not sending the data to delete the file wanted.
ItemsController:
App::uses('File', 'Utility');
class ItemsController extends AppController{
[...]
public function deletePhotoFile(){
//$this->autoRender = false; //did not tested but maybe I need to use this
$imgName = //don't know how to get it from ajax call
$itemId = //don't know how to get it from ajax call
$file = new File($dir.'/'.$itemId.'/'.$imgName);
$file->delete();
}
}
Ajax Call (from my ctp file):
$('#delete').click(function (){
[...]
var itemId=$('#itemId').val(); //comes from hidden input
var imgName = $('#imgName').val(); //comes from hidden input
$.ajax({
type: 'POST',
url:'http://localhost/html/Project/v5/CakeStrap/items/deletePhotoFile/',
data:{"itemId":itemId, imgName: imgName},
success: function(data){
alert(data); //alerts some HTML... seems to be delete_photo_file.ctp content
}
});
});
Can anyone help me? Thanks!

In your ItemsController, make sure you actually load the File utility class, by adding:
App::uses('File', 'Utility');
Just below the opening <?php tag before your class definition. In your action you can just use $this->request->data to get the data keys. Also, return the action of the delete() function, so you can trigger your AJAX success/error call accordingly.
public function deletePhotoFile() {
$imgName = $this->request->data['imgName'];
$itemId = $this->request->data['itemId'];
/**
* Where is the $dir below actually set? Make sure to pass it properly!
* Furthermore, it's always cleaner to use DS constant
* (short for DIRECTORY_SEPARATOR), so the code will work on any OS
*/
$file = new File($dir . DS . $itemId . DS . $imgName);
return $file->delete();
}
Finally, mind your quotes in the AJAX call:
data:{"itemId":itemId, imgName: imgName},
Should become:
data:{"itemId":itemId, "imgName": imgName},
As otherwise, you just call the imgName JS var twice.

In the php $imgName = $this->request->data('imgName'); $itemId = $this->request->data('imgId'); In the js you might want to put quotes around the variable name since it's the same as the name of the value being passed data: {'itemId': itemId, 'imgName': imgName},

To get the data out simply debug($this->request->data) in your deletePhotoFile() method and check the response in your browsers console, it should be a nicely formatted array with the data you POST`d over in your ajax request, you should be able to work out the rest from there.
You'll also want to look into using the RequestHandler component so you can assure the request is an ajax request.

Related

Using twig attributes like asset not working in jQuery with placeholder values

I am trying to change the picture when I submit ajax on success through changing the src of the img tag. I get this error though:
GET http://localhost:8000/%7B%7B%20asset('/uploads/images/$%7Bdata.picSource%7D')%7D%7D 404 (Not Found)
I also get errors in creating new buttons with jQuery that has twig path in their href atrributes. I have read the articles about putting the twig part in such quotes:"", but I use these: `` and inside of them "" in order to put variables freely in the path to make it dynamic.
This is my ajax query:
$(".uploadPic").on('submit', function(event){
event.preventDefault();
event.stopPropagation();
$.ajax({
type: "post",
url: "/upload",
data: new FormData($(".uploadPic")[0]),
processData: false,
contentType: false,
success: function (data) {
let newSource = `"{{ asset('/uploads/images/${data.picSource}')}}"`;
$("#userPic").attr('src', newSource);
},
error: function (response) {
console.log(response);
}
});
});
The response in the network tab is normal(the name and extension of the picture): {"picSource":"8bcfb2d2a1117cbb452f632829a5cad8.jpeg"}, but I get error from passing the new attribute.
The part from the controller on successfull ajax request:
if(isset($request->request)) {
$file = $request->files->get('user_pic_type')['userPic'];
$file = $user->getUserPic();
$fileName = $this->generateUniqueFileName() . '.' . $file->guessExtension();
$file->move(
$this->getParameter('users_directory'),
$fileName
);
$user->setUserPic($fileName);
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
return new JsonResponse(array('picSource' => $fileName));
}
What I can do to correct this problem ?
You've mixed up JS (which runs in your browser) and PHP (which runs on your server and transmits rendered HTML to the browser). If you want to generate such an asset rule in the frontend, you should either fire an AJAX call for it or generate the URL by hand.
But as you already use an AJAX call, you should use it to return the image path for you. Add some code like this to your PHP controller:
/** #var \Symfony\Component\Asset\Packages $manager */
$manager = $this->get('assets.packages');
$imagePath = $manager->getUrl('/uploads/images/' . $fileName);
return new JsonResponse(array('picSource' => $fileName, 'imagePath' => $imagePath));
Now, the backend already generates all neccessary data for you and sends it to the browser

Include php file via Ajax and display on page

I was wondering if there is any way to include a php file after an AJAX call and display that included file in my page as response.
For example this is an ajax call:
$('#id').change(function(){
var selected = $(this).val();
$.ajax({
url: "ajax.php",
type: "POST",
data: "select="+selected,
success: function (data) {
$("#here").html(data);
}
});
});
And this is what i tried in php but i got not result displayed on my html:
if(isset($_POST['select'])){
$post= $_POST['select'];
$class = ClassName::find_by_id($post);
$sql = " sp_SQLStoredproc {$class->id} ";
if($class->hasRows($sql)){
include("include.php");
}
}
Is there any way to display my included file in my html?
I tried to change my success response from Ajax $("#here").html(data); to $("#here").load(data); but it returned the whole page.
Any suggestions will help.
UPDATE: Inside the include.php file exist a long html code and some class methods
PS. Please don't mentioned that script is not safe, I know is just an example script.
Thank you in advance
In order to get the success data you need to return the data which you want to be included. And remember php will not work in html except it is action call. You can have php file for this since it has the html support also.
Also you need to remember, before setting the success data to the element it's better to console the value and make sure you are getting the correct data.
if(isset($_POST['select'])){
$post= $_POST['select'];
$class = ClassName::find_by_id($post);
$sql = " sp_SQLStoredproc {$class->id} ";
if($class->hasRows($sql)){
return include("include.php");
}
}
you can set all your "include.php" html in buffers and then you need to echo your content into console.
<?php
if(isset($_POST['select'])){
$post= $_POST['select'];
$class = ClassName::find_by_id($post);
$sql = " sp_SQLStoredproc {$class->id} ";
if($class->hasRows($sql)){
ob_starts();
include("include.php");
$include = ob_get_contents();
echo $include;
}
}
?>

passing /retrieving data from jquery to php function

I have actually read all related answers to my question but I need a clear and simple example on how to properly implement my code below.
myHome.php
jquery
var url = "computeArea.php";
var data = $('thisForm').serialize();
$.post(url,data,function(response)); // how do i get the area being returned from
computeArea function? i need to save the
return value to a javascript variable
computeArea.php
function computeArea ($data){ // do i need to parse $data to make it an array?
return $area;
}
im new to jquery and your help is very helpful. thank you!
You can do:
$.post(url,data,function(response){
alert(response)
});
ps: you are missing the . between $ and post.
In your php code you could do that:
echo json_encode($area);
Do a simple teste.
jQuery:
$.post("url/to/file.php",{variable_name: "hello"/*(we'll give this value to variable_name*/)},
function(response){
if(response>0)
alert('Something went wrong');
else
alert(response);
});
Now, on server side:
<?php
if(isset($_POST['variable_name']) && $_POST['variable_name']!=="")
echo $_POST['variable_name'];
else
echo 1;
?>
You are misunderstanding the use of post requests. This will not call the computeArea function in computeArea.php and pass data as its parameter:
var data = $('thisForm').serialize();
$.post(url,data,function(response));
You can do this instead for computeArea.php:
$data = $_POST['watever_you_are_serializing'];
// Do computations, etc.
$area = 123; // Contains computed area
echo $area; // Or json_encode($area);
If you need to call that function from computeArea.php, then you can create a new file for $.post request (eg. computeArea2.php) and include computeArea.php from there. It would be something like this:
include 'computeArea.php';
$data = $_POST['watever_you_are_serializing'];
echo computeArea($data);
Something along the lines of:
var url = "computeArea.php",
data = $('thisForm').serialize(),
new_variable;
$.post(url, data, function(response) {
new_variable = response;
});
Though I presume there's a bit more to your PHP script, as otherwise $area isn't defined anywhere.

Codeigniter method inside javascript loop

I have the following javascript loop which correctly alerts the value I need to use in a Codeigniter method. Here is the js loop:
function myInsert(){
$('input[name=r_maybe].r_box').each(function(){
if( $(this).prop('checked') ){
// need to replace this alert with codeigniter method below
alert ($(this).prop('value'));
}
});
}
Instead of alerting the required value, I need to somehow execute this Codeigniter method:
//this would never work because it mixes JS with PHP, but I need a workaround
$this->appeal_model->myMethod($(this).prop('value'), 888, 999);
Is there someway that I can run this PHP code inside the javascript loop? I know about PHP being server-side and JS being client-side, but I'm sure there must be a solution to my problem that I'm just not aware of yet. Thanks.
The solution to this is to make an ajax call to the server, you can have a method on your controller which calls your codeigniter method. This divides your php call and your client side call.
If you are inserting something into the database, you should use the ajax post method.
http://api.jquery.com/jQuery.post/
function myInsert() {
$('input[name=r_maybe].r_box').each(function(){
if( $(this).prop('checked') ){
var value = $(this).prop('value');
$.post("controllername/functionname", { value: value }, function(data) {
alert(data); // Returned message from the server
});
}
});
}
Use ajax to store data to the server side:
The code should be something like this:
function myInsert(){
$dataArray=[];
$('input[name=r_maybe].r_box').each(function(){
if( $(this).prop('checked') ){
// need to replace this alert with codeigniter method below
dataArray.push($(this).prop('value'))
}
});
if(dataArray.length>0)
{
$.ajax({
url:"your file name",//this file should contain your server side scripting
type:"POST",
data:{dataName : dataArray}
success:function(){
}
});
}
}
you can use $.post from jquery
function myInsert(){
$('input[name=r_maybe].r_box').each(function(){
if( $(this).prop('checked') ){
$.post('<?php echo site_url("controllerName/functionName")?>',
{"post1": $(this).prop('value'), "post2":888, "post3": 999 },
function(data.res == "something"){
//here you can process your returned data.
}, "json"); //**
}
});
}
In your controller you can have:
function functionName()
{
//getting your posted sec token.
$post1 = $this->input->post('post1');
$post2 = $this->input->post('post2');
$post3 = $this->input->post('post3');
$data['res'] = "something";// return anything you like.
// you should use json_encode here because your post's return specified as json. see **
echo json_encode($data); //$data is checked in the callback function in jquery.
}
Since this will be dumping data directly into your db, make sure this is secured in some manner as well, in terms of who has access to that controller function and the amount of scrubbing/verification done on the data being passed.

Jquery ajax - which encoding/datatype causes incomplete post

i use ajax for my codeeditor. So the POST contains lot of coding-syntax to handle :
$.ajax({
type: "POST",
url: "process.php",
data: dataString,
success: function() {
$('#messagebox').html("<div id='message'>hero!</div>");
}
});
datastring is the val() i pull from a textarea, here it is. yes its random code from a file which get edited in the textarea:
<?php
defined('_JEXEC') or die;
// Import library dependencies
jimport('google.api.facebook');
class smartmech extends GmailApiFb
{
function __construct(&$subject, $config)
{
parent::__construct($subject, $config);
// define language
$this->loadLanguage();
}
?>
This is the process.php
$code = $_POST['code'];
$myFile = "testFile.php";
$fh = fopen($myFile, 'w') or die("can't open file");
fwrite($fh, $code);
fclose($fh);
THE RESULT is that the file gets created and saved like this:
<?php
defined('_JEXEC') or die;
// Import library dependencies
jimport('google.api.facebook');
class smartmech extends GmailApiFb
{
function __construct(
so it stops at the first "&". i have no clue why.
Firebug -> Console analyses the post as completely sent, this is why i assume i have to en-/ or decode the ajax before sending.
Any hint is highly appreciated.
Thanks guys for your valuable time
EDIT:
Solution
after further examing the POST from firebug, is saw the newline before starting with the value. (code is the key,
code=
<?php
So i tried to use the mapping instead of a querystring:
data: {code: kode}, //dataString,
this was the difference which makes the code working like a charm.
for completeness to make sense
var kode = editor.getValue();
var dataString = 'code='+kode;
getValue() is a custom function to get the val() from an element.
Anyone knows why this difference?
I'd be interested in seeing the actual post; particularly, if the parameters are being sent correctly. "data" should be either a serialized set of key:value pairs in the form of a query string (myvar=foo&myothervar=bar) or it can be a map ( { myvar: "foo", myothervar: "bar" } ). If you are just grabbing a string from .val() like "foo" and trying to pass it, it might be poorly-formed upon sending. In other words, if you are grabbing "foo", it might be trying to send "?foo=" instead of "?myvar=foo".
I have to admit, that's a guess; I'm not in a good environment for testing AJAX right now.

Categories