Angular + Laravel Delete File - angularjs

I'm building a REST-full web-app using Laravel 5.2 (for the back-end) and AngularJS for the font-end. I connect to the Laravel back-end by the use of an API. Now I have stumbled upon the following problem: I can properly upload an image, but deleting it again is not working.
The files are uploaded into the Larvel public/images/uploaded/ folder.
This is my Angular Service (the http request fired when clicking the 'delete' button) where the variable imageToDelete is the relative path to the image.. So Far so good, the request is firing and the imageToDelete variable is populated.
function deleteProfileImage(imageToDelete) {
return $http({
method: 'DELETE',
url: '/api/pictures/' + imageToDelete
})
.then(deleteProfileImageSuccess)
.catch(deleteProfileImageError);
function deleteProfileImageSuccess(response) {
$log.info('Deleting profile picture Success.');
console.log(response);
return response;
}
function deleteProfileImageError(error) {
$log.info('Deleting profile picture failed because: ' + error.data);
return error;
}
}
This angular HTTP request fires a DELETE request to the following function in my Laravel Controller.
public function destroy($imageToDelete)
{
if(Storage::delete($imageToDelete)) {
return response()->json(['success' => 'success', 'message' => 'File Deleted']);
} else {
return response()->json(['error' => 'Deleting Image failed.'])
->setStatusCode(Response::HTTP_BAD_REQUEST);
}
}
And here, the Storage::delete($imageToDelete) does nothing. It does not delete the file provided with the Angular DELETE request.
Some things I have already tried:
Working with File::delete() instead of Storage::delete()
Working with unlink() instead op the Laravel Facades;
Sending the imageToDelete as data with the HTTP DELETE request (so not in the URL).
But all without success.
How can I make Laravel (PHP) delete the image?
Thank you for helping!

You can try
$storage = Storage::find($imageToDelete);
if($storage->delete()) {
return response()->json(['success' => 'success', 'message' => 'File Deleted']);
}
or
if(Storage::destroy($imageToDelete)) {
return response()->json(['success' => 'success', 'message' => 'File Deleted']);
}
or
$deleteImage = Storage::where('id', $imageToDelete)->delete();
if($deleteImage){
return response()->json(['success' => 'success', 'message' => 'File Deleted']);
}

You might need to check your image path. When you use laravel storage or file facde your file path should be absolute path for example public_path($imageToDelete)

Related

Laravel Http::fake response with file

I am trying to mock/test an Http request in a feature test to mock the whatsapp APIs, using Http::fake() in the setUp as follow:
Http::fake([
'https://www.test-whatsapp.com/upload/image' => Http::response(UploadedFile::fake()->image('TestWhatsapp.jpg')->get()),
'https://www.test-whatsapp.com/*' => Http::response(),
]);
I'd like to mock that when my app calls https://www.test-whatsapp.com/upload/image i get the file content but it seems that it never get sent. This is my actual test:
public function test_ask_attachment_image()
{
$this->receivedMessage(['type' => 'TEXT', 'text' => 'ask-attachment']);
$this->receivedMessage(['type' => 'IMAGE', 'caption' => 'some text', 'url' => '"https://www.test-whatsapp.com/upload/image']);
Http::assertSent(function (Request $request){
Log::debug($request->url(), [$request->body()]);
return true;
});
}
But the log gives an empty body.
I tried to print_r the whole response but still no sign of the file.
In the end I tried with an existing file using file_get_content but i got the same result.
I have logged the faked file and it get the content right.
How can i fake an endpoint to return me a file content? Thank you for any suggestions!
Edit
After debugging more i found out that the problem is not when i'm trying to create an image but a generic file using the method UploadedFile::fake()->create('TestWhatsapp.mp4', 1000). I get the size and the mimetype right but the file is still empty.

laravel reactjs pusher: presence channel response is 302

I'm trying to make a reactjs application where an user can only login to one device at the time with the same user credentials. Unfortunately it isn't working.
I'm trying to authenticate a presence channel with reactjs to laravel but I get a 302 response.
reactjs:
Pusher.logToConsole = true;
var pusher = new Pusher("9028d58568392772df59", {
cluster: "eu",
forceTLS: true,
authEndpoint: '/broadcasting/auth',
auth: {
headers: {
'X-CSRF-Token': csrf_token
}
}
});
var channel = pusher.subscribe("presence-HandleCredentials");
channel.bind("sameCredentials", function(data) {
console.log(data);
alert(JSON.stringify(data));
});
channel:
Broadcast::channel('App.User', function ($user, $id = 1) {
return (int) $user->id === (int) $id;
});
broadcast:
public function boot()
{
Broadcast::routes(['middleware' => ['auth:web']]);
require base_path('routes/channels.php');
}
When I added this ['middleware' => ['auth:web']] I got the error. Before I added that I got a 403 error.
in the config\app.php I uncommented App\Providers\BroadcastServiceProvider::class,
Are there any tutorials out there that are build with laravel and reactjs for a presence channel?
does anyone know how to get past this 302 redirect?
Recently had the same issue with my laravel-websockets and laravel echo.
In my case I was unable to solve the 302, as Broadcast was unable to authenticate my logged in user. I was trying to subscribe to my private channel. So the workaround i found was that i manually created a POST route in web.php as "/broadcasting/auth". This is what my front-end requests to. So The updated code in web.php is as follows.
Route::post('/broadcasting/auth', function(Request $request){
$pusher = new Pusher\Pusher(
env('PUSHER_APP_KEY'),
env('PUSHER_APP_SECRET'),
env('PUSHER_APP_ID'),
array(
'cluster' => env('PUSHER_APP_CLUSTER'),
'useTLS' => false,
'host' => env('APP_URL'),
'port' => 6001,
'scheme' => 'http',
)
);
return $pusher->socket_auth($request->request->get('channel_name'),$request->request->get('socket_id'));
});
I was creating my own websocket that is why i had to mention the host & port within the options, you don't need to use it if you are Using Pusher. You can also add other middlewares to the routes if needed.
You have to comment out the following line in app/providers/BroadcastServiceProvider:
public function boot()
{
// Broadcast::routes();
require base_path('routes/channels.php');
}
so that the request can reach my broadcasting/auth route in web.php.
Try this. now this should return a 200 when the broadcasting/auth is requested by your client end with response of an auth code. Do let me know if this solves your problem.

Axios doesn't delete data from database - empyt array Vuejs and Laravel

I Have an issue with my code. My axios delete request doesn't delete data from database. I get response 200 but it's all.
Component
deleteComment(index){
axios.delete(this.uri + this.comments[index].id)
.catch(error=>{
console.log(error)
});
}
Controller
public function destroy(BlogComments $cid){
$comments->delete();
return response()->json([
'comments'=> $id,
'Message'=> "OK!"
]);
}
Console -> Network
Request URL: http://127.0.0.1:8000/api/blog-comments/4
Request Method: DELETE
Status Code: 200 OK
Remote Address: 127.0.0.1:8000
Referrer Policy: no-referrer-when-downgrade
When I make response form controller, I have only empty arrays
comments[]
UPDATE
I fixed it.
I replaced
Route::resources('/blog-comments', 'DashboardBlogCommentsController');
By
Route::delete('/blog-comments/{id}', 'DashboardBlogCommentsController#destroy');
Why resources doesn't work ? I used the same method in my other page and it's worked
Route::resource('/advantages', 'DashboardAdvantagesController');
public function destroy(HomepageAdvantages $advantage){
$advantage->delete();
return response()->json([
'advantage'=>$advantage,
'message'=> 'task created'
]);
}
Maybe a answer for:
Why resources doesn't work ?
Route
This is maybe a typo in your edit and not in your code, but is not resources:
Route::resources('/blog-comments', 'DashboardBlogCommentsController');
is resource:
Route::resource('/blog-comments', 'DashboardBlogCommentsController');
And based on the code before the UPDATE of your question:
Controller DashboardBlogCommentsController
public function destroy(BlogComments $comment){
// use delete() on the variable where you assigned the object
$comment->delete();
return response()->json([
// 'comments'=> $id, this no needed, the comment doesn't exist anymore
'message' => 'OK!' ], 202);
}
Hope it's helps

Laravel Excel giving CORS error only dev server

The problem:
I am making a get request to my Laravel API and getting the following error
Cross-Origin Request Blocked: The Same Origin Policy disallows reading
the remote resource at http://www.example.com/exceptions-company-reports.
(Reason: CORS header 'Access-Control-Allow-Origin' missing)
I have followed these instructions on local and then on dev server, but I cannot figure out why Im getting this problem only on the dev server. I have even confirmed that php_zip and php_xml are enabled.
I am not getting errors in my logs.
Client side Angular code
getExceptionsReport: function getExceptionsReport() {
var apiBase = apiUrl + 'exceptions-company-reports';
var config = {
responseType: 'blob'
};
return $http.get(apiBase, config);
}
Server side:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests\PublishCompanyreportingRequest;
use DB;
use Auth;
use Excel;
class CompanyreportingController extends Controller {
public function __construct() {
$this->middleware( 'jwt.auth' );
$this->middleware( 'role:company-reports' );
}
public function exceptionsCompanyReports( PublishCompanyreportingRequest $requestData ) {
$list = DB::table( 'exceptions_reports' )->select('created_at','account_number','customer_name','fp','seriel_number','comment','grade','item_number','description')->get();
$rows = array();
foreach($list as $item) {
$rows[] = array(
"Received" => $item->created_at,
"Account Number"=> $item->account_number,
"Customer Name" => $item->customer_name,
"FP"=> $item->fp,
"Serial Number" => $item->seriel_number,
"Comment" => $item->comment,
"Grade" => $item->grade,
"Item Number" => $item->item_number,
"Description" => $item->description,
);
}
Excel::create('Filename2', function($excel) use($rows) {
// Set the title
$excel->setTitle('Company| Company Report');
// Chain the setters
$excel->setCreator('Company')
->setCompany('Company');
$excel->sheet('Exceptions Report', function($sheet) use($rows) {
$sheet->fromArray($rows);
$sheet->row(1, function($row) {
// call cell manipulation methods
$row->setBackground('#DDDDDD');
$row->setFontFamily('Calibri');
$row->setFontSize(14);
});
$sheet->setStyle(array(
'font' => array(
'name' => 'Calibri',
'size' => 14
)
));
});
// Call them separately
$excel->setDescription('A demonstration to change the file properties');
})->download('xlsx');
}
}
Laravel-Excel will not add the headers for you. So, in order to avoid CORS issues, add this header:
Excel::create('Contactos', function($excel) use ($results) {
...
})->export('xlsx', ['Access-Control-Allow-Origin'=>'*']);
I came up with a work around of sorts, I guess a little better than a workaround as there is nothing wrong with the code.
I decided to save the file to the server instead and then send that file as a response instead of relying on the extension to do it. Still quite frustrating because I will never really know what the error was. What makes it more frustrating is that I know it can work as it does on my local. I wont mark this answer as correct until in case someone has a better one.
Excel::create('Filename2', function($excel) use($rows) {
// other code
})->save('xlsx');
return response()->file(storage_path().'/exports/Filename2.xlsx');
I am also deleting the file immediately after with a DELETE request
public function destroy( $id ) {
\File::Delete(storage_path().'/exports/Filename2.xlsx');
return response()->json( [ 'success' => 'Report has been removed from server' ], 200 );
}
In my case it happened because it did not have a zip extension installed.
It was showing me Cross-Origin Request Blocked but that was not the error

Wordpress wp rest api v2 error 400 (Bad Request)" Object {code: "rest_invalid_param", message: "Invalid parameter(s): id", data: Object}

On local host request to my WordPress app that is using the "wp rest api v2" is working as expected with no issues. Here is an example of my local host post request:
POST "http://127.0.0.1/plugin namespace/plugin-name/wp-json/plugin namespace/rest of the api url"
But on my hosted site the request is returning an error, similar request to my hosted site:
POST "http://my-domain.com/plugin-name/wp-json/plugin namespace/rest of the api url"
And I get on chrome console "400 (Bad Request)"
Object {code: "rest_invalid_param", message: "Invalid parameter(s): id", data: Object}
Another note the payload is identical in both requests:
$http.post(url, { id : 1, shortMessage:"a b c"}, {headers: {'X-WP-Nonce': "my nonce value"}}); // I am using angular $http to make the post request
I wrote how the url's look like above.
In my plugin php code I wrote:
function myplugin_register_endpoints(){
register_rest_route(
'plugin namespace',
'/rest of the api url',
array(
'methods' => 'POST',
'callback' => 'my_end_point',
'args' => array(
'id' => array(
'required' => true,
'validate_callback' => function($param, $request, $key) {
return is_numeric( $param ) and ! is_null(get_post($param));//numeric post id value and there is valid post for this id
},
'sanitize_calback' => 'absint'
)
),
'permission_callback' => function (WP_REST_Request $request) {
if(!is_user_logged_in()){
return new WP_Error('login error',__('You are not logged in','blabla'));
}
return true;
}
)
);
}
add_action('rest_api_init','myplugin_register_endpoints');
function my_end_point(WP_REST_Request $request) {
global $current_user;
$current_user = wp_get_current_user();
if($my_var){
return array('message' => $message,'items' => $items,'item'=>$item);
} else {
return new WP_Error('add friend error',__('message'),$request['id']);
}
}
I need to understand why the request is failing on my hosted site.
Thanks
K
I found my mistake.
it was on this line:
return is_numeric( $param ) and ! is_null(get_post($param));//numeric post id value and there is valid post for this id
I changed it to:
return is_numeric( $param );
It happened because I copy paste the register_rest_route(...){...} part without modifying the 'validate_callback' logic.
the param in this 'validate_callback' is user ID not post ID. so the part checking if the param is a post ID( ... and ! is_null(get_post($param)); ... ) is not relevant for this end point.
Therefore after omitting this check the end point passed the 'validate_callback' and stopped returning an error.

Resources