Witam, chcąc zrealizować upload zdjęć na stronie wykorzystałem wtyczkę dropzone.js http://www.dropzonejs.com/ cały projekt jest oparty na Laravelu. wszystko udało mi się elegancko skonfigurować, pomagałem sobie jakimś kursem. Problem pojawił się w momencie przekazania w GET dodatkowego id które później umieszczam w tabeli ze zdjęciami. Działa to trochę na takiej zasadzie
dodaję dane posta -> zapisuję je tabeli "post" -> getem przekazuję id danego postu na stronę dodawania zdjęć
->dodaję zdjęcie do bazy łącznie z id posta do którego będą przypisane
i to by wszystko świetnie działało, problem pojawia się kiedy chcę usunąć zdjęcie, zdjęcia po prostu nie usuwają się ani z serwera ani ścieżka do nich z bazy danych, mógłby ktoś spojrzeć na kod i pomóc znaleźć rozwiązanie? Z góry dzięki, poniżej kod
kod widoku:
@extends('layouts.app')
@section('title', 'Dodaj zdjęcia produktu')
@section('my-scripts')
<script src="{{ asset('js/dropzone.js') }}"></script>
<script src="{{ asset('js/config-dropzone.js') }}"></script>
@stop
@section('content')
<div class="row">
<div class="col-md-offset-1 col-md-10">
<div class="jumbotron how-to-create" >
<h3>Dodanych zdjęć<span id="photoCounter"></span></h3>
<br />
{!! Form::open(['url' => route('upload-post'), 'class' => 'dropzone', 'files'=>true, 'id'=>'real-dropzone']) !!}
<div class="dz-message">
</div>
<input type="hidden" value="{{ $id }}" name="id_product"/>
<div class="fallback">
<input name="file" type="file" multiple />
</div>
<div class="dropzone-previews" id="dropzonePreview"></div>
<h4 style="text-align: center;color:#428bca;">Dodaj zdjęcia produktu<span class="glyphicon glyphicon-hand-down"></span></h4>
{!! Form::close() !!}
</div>
<div class="jumbotron how-to-create">
<ul>
<li>Images are uploaded as soon as you drop them</li>
<li>Maximum allowed size of image is 8MB</li>
</ul>
</div>
</div>
</div>
<!-- Dropzone Preview Template -->
<div id="preview-template" style="display: none;">
<div class="dz-preview dz-file-preview">
<div class="dz-image"><img data-dz-thumbnail=""></div>
<input type="hidden" class="serverfilename"/>
<div class="dz-details">
<div class="dz-size"><span data-dz-size=""></span></div>
<div class="dz-filename"><span data-dz-name=""></span></div>
</div>
<div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress=""></span></div>
<div class="dz-error-message"><span data-dz-errormessage=""></span></div>
</div>
</div>
<!-- End Dropzone Preview Template -->
{!! Form::hidden('csrf-token', csrf_token(), ['id' => 'csrf-token']) !!}
@stop
kod kontrolera
<?php
namespace App\Http\Controllers;
use App\Logic\Image\ImageRepository;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Input;
use App\Models\Image;
class ImageController extends Controller
{
protected $image;
public function __construct(ImageRepository $imageRepository)
{
$this->image = $imageRepository;
}
public function getUpload($id)
{
return view('upload', compact('id'));
}
public function getUpload3()
{
return view('pages.upload3');
}
public function postUpload()
{
$photo = Input::all();
$response = $this->image->upload($photo);
return $response;
}
public function deleteUpload()
{
$filename = Input::get('id');
if(!$filename)
{
return 0;
}
$response = $this->image->delete( $filename );
return $response;
}
}
kod pliku konfiguracyjnego.js
var photo_counter = 0;
Dropzone.options.realDropzone = {
uploadMultiple: false,
parallelUploads: 100,
maxFilesize: 8,
previewsContainer: '#dropzonePreview',
previewTemplate: document.querySelector('#preview-template').innerHTML,
addRemoveLinks: true,
dictRemoveFile: 'Usuń',
dictFileTooBig: 'Image is bigger than 8MB',
dictRemoveFileConfirmation: "Czy na pewno chcesz usunąć to zdjęcie?",
// The setting up of the dropzone
init:function() {
// Add server images
var myDropzone = this;
$.get('/images', function(data) {
$.each(data.images, function (key, value) {
var file = {name: value.original, size: value.size};
myDropzone.options.addedfile.call(myDropzone, file);
myDropzone.createThumbnailFromUrl(file, 'images/' + value.server);
myDropzone.emit("complete", file);
$('.serverfilename', file.previewElement).val(value.server);
photo_counter++;
$("#photoCounter").text( "(" + photo_counter + ")");
});
});
this.on("removedfile", function(file) {
$.ajax({
type: 'POST',
url: 'upload/delete',
data: {id: $('.serverfilename', file.previewElement).val() , _token: $('#csrf-token').val()},
dataType: 'html',
success: function(data){
var rep = JSON.parse(data);
if(rep.code == 200)
{
photo_counter--;
$("#photoCounter").text( "(" + photo_counter + ")");
}
}
});
} );
},
error: function(file, response) {
if($.type(response) === "string")
var message = response; //dropzone sends it's own error messages in string
else
var message = response.message;
file.previewElement.classList.add("dz-error");
_ref = file.previewElement.querySelectorAll("[data-dz-errormessage]");
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
node = _ref[_i];
_results.push(node.textContent = message);
}
return _results;
},
success: function(file,response) {
$('.serverfilename', file.previewElement).val(response.filename);
photo_counter++;
$("#photoCounter").text( "(" + photo_counter + ")");
}
}
routinng
Route::get('/upload-image/{id}', ['as' => 'upload', 'uses' => 'ImageController@getUpload']);
Route::post('upload', ['as' => 'upload-post', 'uses' =>'ImageController@postUpload']);
Route::post('upload/delete', ['as' => 'upload-remove', 'uses' =>'ImageController@deleteUpload']);
kod ImageRepository
<?php
namespace App\Logic\Image;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\File;
use Intervention\Image\ImageManager;
use App\Models\Image;
class ImageRepository
{
public function upload( $form_data )
{
$validator = Validator::make($form_data, Image::$rules, Image::$messages);
if ($validator->fails()) {
return Response::json([
'error' => true,
'message' => $validator->messages()->first(),
'code' => 400
], 400);
}
$photo = $form_data['file'];
$id_product = $form_data['id_product'];
$originalName = $photo->getClientOriginalName();
$extension = $photo->getClientOriginalExtension();
$originalNameWithoutExt = substr($originalName, 0, strlen($originalName) - strlen($extension) - 1);
$filename = $this->sanitize($originalNameWithoutExt);
$allowed_filename = $this->createUniqueFilename( $filename, $extension );
$uploadSuccess1 = $this->original( $photo, $allowed_filename );
$uploadSuccess2 = $this->icon( $photo, $allowed_filename );
if( !$uploadSuccess1 || !$uploadSuccess2 ) {
return Response::json([
'error' => true,
'message' => 'Błąd serwera podczas przesyłania',
'code' => 500
], 500);
}
$sessionImage = new Image;
$sessionImage->id_product = $id_product;
$sessionImage->filename = $allowed_filename;
$sessionImage->original_name = $originalName;
$sessionImage->save();
return Response::json([
'error' => false,
'code' => 200,
'filename' => $allowed_filename
], 200);
}
public function createUniqueFilename( $filename, $extension )
{
$full_size_dir = Config::get('images');
$full_image_path = $full_size_dir . $filename . '.' . $extension;
if ( File::exists( $full_image_path ) )
{
// Generate token for image
$imageToken = substr(sha1(mt_rand()), 0, 5);
return $filename . '-' . $imageToken . '.' . $extension;
}
return $filename . '.' . $extension;
}
/**
* Optimize Original Image
*/
public function original( $photo, $filename )
{
$manager = new ImageManager();
$image = $manager->make( $photo )->save(Config::get('uploads') . $filename );
return $image;
}
/**
* Create Icon From Original
*/
public function icon( $photo, $filename )
{
$manager = new ImageManager();
$image = $manager->make( $photo )->resize(200, null, function ($constraint) {
$constraint->aspectRatio();
})
->save( Config::get('uploads') . $filename );
return $image;
}
/**
* Delete Image From Session folder, based on server created filename
*/
public function delete( $filename )
{
$full_size_dir = Config::get('images');
$icon_size_dir = Config::get('images');
$sessionImage = Image::where('filename', 'like', $filename)->first();
if(empty($sessionImage))
{
return Response::json([
'error' => true,
'code' => 400
], 400);
}
$full_path1 = $full_size_dir . $sessionImage->filename;
$full_path2 = $icon_size_dir . $sessionImage->filename;
if ( File::exists( $full_path1 ) )
{
File::delete( $full_path1 );
}
if ( File::exists( $full_path2 ) )
{
File::delete( $full_path2 );
}
if( !empty($sessionImage))
{
$sessionImage->delete();
}
return Response::json([
'error' => false,
'code' => 200
], 200);
}
function sanitize($string, $force_lowercase = true, $anal = false)
{
$strip = array("~", "`", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "_", "=", "+", "[", "{", "]",
"}", "\\", "|", ";", ":", "\"", "'", "‘", "’", "“", "”", "–", "—",
"—", "–", ",", "<", ".", ">", "/", "?");
$clean = trim(str_replace($strip, "", strip_tags($string)));
$clean = preg_replace('/\s+/', "-", $clean);
$clean = ($anal) ? preg_replace("/[^a-zA-Z0-9]/", "", $clean) : $clean ;
return ($force_lowercase) ?
(function_exists('mb_strtolower')) ?
mb_strtolower($clean, 'UTF-8') :
strtolower($clean) :
$clean;
}
}
to już chyba wszystkie ważne pliki które są za to odpowiedzialne