I have this function on my controller
public function get_images(Request $request){
$images = inventory_images::where('item_id',$request->id)->get();
$path = Storage::disk('local')->getDriver()->getAdapter()->getPathPrefix();
return response()->json([ 'success' => true, 'images' => $images, 'id' => $request->id, 'path' => $path ]);
}
so the '$path' contains the storage path, my images stored on the 'storage' folder and the '$images' contains the file name and then in my front end side (rendering the image)
$.each(e.images,function(index,value){
$("#notification_dialog #gallery-items-container").append(' <figure> <img src="'+e.path+value.image_name+'"> </figure>');
});
in the image 'src' I have this path
C:\wamp\www\Clinic and Inventory
System\storage\app\public\items_gallery\10014589_974440645904700_5867266076580720168_n.jpg
In the console, I have this error
:1 Not allowed to load local resource:
file:///C:/wamp/www/Clinic%20and%20Inventory%20System/storage/app/public/items_gallery/10014589_974440645904700_5867266076580720168_n.jpg
The image did not render and If I paste the path unto the browser, I can see the image so it means that the path was correct and just the image is not rendering, any ideas, help please?
Put a data attribute on the tag holding the image:
data-image_path="{{ asset('uploads/*name of model this is being associated with/original/') }}"
Where asset points to your project's public directory.
Then retrieve the image name from the controller and append it to that path.
I have found a solution somewhere,
Route::get('/images/{image}', function($image = null)
{
$path = storage_path().'/app/public/items_gallery/' . $image;
if (file_exists($path)) {
return Response::download($path);
}
});
and its okay now.
Related
I am using vue-wysiwyg editor in my laravel-vue application. In this editor there is an option to upload images and through incomplete documentation of this package I am able to upload the image and get public url of the uploaded file. But this package works sometimes and does not work at all sometimes.
Here is how I am using this package
main.js
import wysiwyg from "vue-wysiwyg";
Vue.use(wysiwyg, {
forcePlainTextOnPaste: true,
image: {
uploadURL: "/api/save-support-files",
dropzoneOptions: {}
},
});
/api/save-support-files
public function uploadUserFile(Request $request)
{
$uploadedFile = $request->file('file');
if (false == $uploadedFile) {
return response()->api(false, 'Kindly upload a file');
}
$allowed_file_extentions = [
'jpeg',
'png',
'jpg',
'gif',
'svg'
];
if (false == in_array($uploadedFile->getClientOriginalExtension(), $allowed_file_extentions)) {
return response()->api(false,'Allowed file types are jpeg, png, jpg, gif, svg',null);
}
$file_url = Storage::disk('public')->putFileAs('/support-files',$uploadedFile,generateRandomString('5').'.'.$uploadedFile->getClientOriginalExtension());
// return response()->api(true,'File uploaded successfully',config('app.url').'/storage/'.$file_url);
return config('app.url').'/storage/'.$file_url;
}
Issues I am facing right now:
As soon as I select image from file browser, image is uploaded through api successfully but it is not showing in editor.
Unable to select already uploaded image, I have to refresh the page and then again select file to upload it again.
Is anyone having solution to this problem ? Kindly help me out.
my upload store function look like this:
public function store(Request $request)
{
$request->validate(['file' => 'required']);
$file = $request->file('file');
if ($file->isValid()) {
$path = $file->storePublicly(now()->format('Y' . DIRECTORY_SEPARATOR . 'm' . DIRECTORY_SEPARATOR . 'd'));
return response(Storage::disk('public')->url($path), Response::HTTP_CREATED)->withHeaders(
[
'content-type' => 'text/html'
]
);
}
abort(Response::HTTP_BAD_REQUEST);
}
make sure you have set APP_URL in .env to full url (http://my-site.com)
make sure you run php artisan storage:link
I want to load the PDF file dynamically and show on browser. PDF file is created on the fly when user clicks on button and the filename has timestamp in it. So i cannot give the PDF filename in the html code as shown below as it changes based on the timestamp(PDF file name is given along with the timestamp when it was created as shown in below spring controller).
Below is the code.
html code:
<div ng-controller="generatePDFController">
<button ng-click="generatePDF()">Re-Generate PDF</button>
<object data="C:/allFiles/PDFFiles/spreadDetails.pdf" type="application/pdf" width="100%" height="100%">
<iframe src="C:/allFiles/PDFFiles/spreadDetails.pdf" width="100%" height="100%" style="border: none;">
This browser does not support PDFs.
Download PDF
</iframe>
</object>
</div>
js code:
app.controller('generatePDFController', function($scope, MyService) {
$scope.generatePDF = function() {
MyService.createPDF().then(
function(response) {
$scope.pdf = response;
},
function(errResponse) {
});
}
});
//service call
_myService.createPDF = function() {
var deferred = $q.defer();
var repUrl = sURL + '/allDataGeneration/generatePDF.form';
$http.get(repUrl)
.then(
function(response) {
deferred.resolve(response.data);
},
function(errResponse) {});
return deferred.promise;
}
spring controller:
#RequestMapping(value = "/generatePDF", method = RequestMethod.GET)
public# ResponseBody List < MyDTO > generatePDF() {
List < MyDTO > response = service.getAllData();
//create PDF and write the response in it
createPDFFile(response);
return response;
}
void createPDFFile(List < MyDTO > res) {
String FILE_PATH = "C:\\allFiles\\PDFFiles\\spreadDetails";
String FILE_EXTENSION = "pdf";
DateFormat df = new SimpleDateFormat("MM-dd-yyyy hh-mm-ssa");
String filename = null;
try {
filename = FILE_PATH + df.format(new Date()) + "." + FILE_EXTENSION;
} catch (Exception e) {
e.printStackTrace();
}
File file = new File(filename);
System.out.println("-----filename------------ " + filename); //PDF file is created successfully
//spreadDetails07-13-2017 02-59-51PM ,when user clicks on GeneratePDF in UI, it hits this controller and generates the PDF
//logic to write the data inside PDF file
}
The above shown code is the complete flow of my sample application. Now when user clicks on Re-Generate PDF button, it comes to above mentioned spring controller creates a file with timestamp and writes the data in it.How to pass the newly created pdf filename to the html code <object data="C:/allFiles/PDFFiles/spreadDetails.pdf" .. so that when pdf file is created it dynamically loads and show on UI.
---EDITED---
Please see the above edited code. createPDF(List<MyDTO>) is a new method in which i'm creating a pdf file and writing the content. I will be reusing this method.
Try to follow these steps :
Change the signature of the Java method generatePDF() in order to return a String representing the name of your file. This gives you the possibility to pass the name of the file to your JavaScript ;
In your controller, do $scope.pdfName = response. This way the name of the file is store the variable $scope.pdfName ;
Last step, replace <object data="C:/allFiles/PDFFiles/spreadDetails.pdf" ...> by <object data="{$scope.pdfName}" ...>
This should work.
Marine
EDIT given your own edit :
Your method generatePdf() is incorrect : you wrote that it must return a List<MyDto> but the keyword return is nowhere.
Do you really need to return he object List<MyDto> ? In any case, you need to return the name of the file to be able to use it in your JavaScript. So, you have two solutions : either this method only returns a String representing the name of the PDF, or it returns an object with two fields, one String and one List<MyDto>. In this second cas, you will need to do
$scope.pdfName = response.fieldContainingTheNameOfTheFile.
I have an app where frontend is developed in angularjs and backend with symfony.
I need to have a route like: http://example.com/api/invoices/file?file=foo
So I have this inside my FileController:
/**
* Matches /invoices/file/{filename} exactly
*
* #Route("/invoices/file/{filename}", name="get_invoice_file")
*/
public function getInvoiceFileAction(string $filename, Request $request)
{
$path = $this->get('kernel')->getRootDir() . '/../web/uploads/invoices/' . $filename;
if (!file_exists($path)) {
return new Response('file not found', 404);
}
$file = file_get_contents($path);
$headers = [
'Content-Type' => 'application/pdf',
'Conteng-Length' => filesize($path)
];
return new Response($file, 200, $headers);
}
Inside my angularjs app I have this to get the response inside my frontend controller:
vm.getInvoices = function() {
vm.loading = true;
apiResolver.resolve('invoices.documents.file#get', { "file": vm.searchFile }).then(function(response) {
vm.loading = false;
var file = new Blob([response], {type: 'application/pdf'});
var fileURL = URL.createObjectURL(file);
vm.file = $sce.trustAsResourceUrl(fileURL);
});
};
Into my html I have this:
<embed ng-src="{{vm.file}}" style="width:200px;height:200px;"></embed>
When I render the page I see a 200response so the file exist but into the html I have an empty space instead of pdf file.
Inside embed tag there is this:
<embed style="width:200px;height:200px;" ng-src="blob:http://localhost:3000/d32d87d1-6582-42e3-85ae-dc174ca5a473" src="blob:http://localhost:3000/d32d87d1-6582-42e3-85ae-dc174ca5a473">
If I copy url inside a browser returns me that can't load file.
Backend and frontend are in different folder and the pdf CAN'T be viewed by a public link infact these pages are protected with jwt system.
How can I show inside my page the pdf?
What I'm doing wrong?
Make sure that JWT Authorization Token is passed in the request . If not , pass it in the Blob object.
If token is passed try replacing embed to object as mentioned below :
<object data="{{vm.file}}" style="width:200px;height:200px;" type="application/pdf"></object>
I'm using the cropit jquery plugin to manage image cropping on my website. The way I have it setup is that cropit will give me a base 64 string that I'll pass to PHP which will decode it and place it in the folder. The issue is that when I decode the string it will only make about 1/10 of the image, the rest will just be white / transparent. My code is as follows:
jQuery:
var username = "<?php echo $userData['username']; ?>";
$('#image-cropper').cropit({
imageState:{
src:'users/'+username+'/profile_picture.jpg'
},
});
$('#image-cropper').cropit('previewSize', {width:500, height:500});
$('.export').click(function() {
var imageData = $('#image-cropper').cropit('export');
//$("#code").val(imageData);
window.open(imageData);
});
PHP:
function decode ($base64) {
list($type, $base64) = explode(';', $base64);
list(, $base64) = explode(',', $base64);
$code = base64_decode($base64);
echo $userData['username'];
file_put_contents('users/' . $userData['username'] . '/profile_picture.png', $base64);
}
The code I have here was working when I had the width/height of $('#image-cropper').cropit('previewSize', {width:500, height:500}); set to 250. I had to change it because without a larger width/height it would save a very low resolution image which is still an issue but not as major. Any help would be great. Thanks!
base64 viewed in browser:
base64 when decoded with PHP:
The data URI scheme that the export function is using as size limitations (depending on the browser).
As the cropit export function allows to tweak the image format and compression factor, you could try to save in jpeg and adjust the quality for best results inside the data URI limits:
// Returns the cropped image in Data URI format.
// The second argument `options` takes the following keys:
// - [type='image/png'] exported image type.
// - [quality=.75] exported image quality, only works when type is
// 'image/jpeg' or 'image/webp'.
// - [originalSize=false] when set to true, export cropped part in
// original size, overriding exportZoom.
// - [fillBg='#fff'] if `type` is 'image/jpeg', this color will be
// filled as the background of the exported image.
$imageCropper.cropit('export', {
type: 'image/jpeg',
quality: .9,
originalSize: true
});
function decode ($base64) {
$explodeBase64 = explode(";base64,", $base64);
$code = base64_decode($explodeBase64[0]);
file_put_contents('users/' . $userData['username'] . '/profile_picture.'.basename(#$explodeBase64[0]), $code);
}
Use the above function to create an image using base64 encoded values, here you need to pass a parameter to function decode('YOUR_IMAGE_ENCODED_STRING')
My output:
I am using Froala editor for my website. This editor have built in image upload function - image upload is working fine, but I am having trouble with response.
This is from the documentation:
The server processes the HTTP request.
The server has to process the upload request, save the image and return a hashmap containing a link to the uploaded image. The returned hashmap needs to look like: { link: 'path_to_uploaded_file/file.png' }
This is my function for returning link:
public function froala_upload()
{
header('Content-type: application/json');
$folder = 'public/img/media';
$slika = $this->site->single_upload($folder, 'jpg|jpeg|png|bmp|JPG|JPEG|PNG|BMP');
$link = array("link" => $slika);
echo json_encode($link);
}
This is JS code:
$('textarea').editable({
inlineMode: false,
imageUploadParam: "userfile",
imageUploadURL: "<?php echo base_url() ?>admin/froala_upload",
// Set the image error callback.
imageErrorCallback: function (data) {
// Bad link.
if (data.errorCode == 1) {
console.log(data);
}
// No link in upload response.
else if (data.errorCode == 2) {
console.log(data);
}
// Error during file upload.
else if (data.errorCode == 3) {
console.log(data);
}
}
});
When I upload image I get following error:
Object { errorCode=1, errorStatus="Bad link."}
And this is response that I get:
{"link":"7d59d61.jpg"}
What seem to be a problem?
Froala image upload documentation
You must return the absolute image path :
$link = array("link" => '/img/media/'.$slika);
Because Froala looks for it to http://example.com/7d59d61.jpg
The problem is that the image cannot be loaded from the returned link. You'd have to make sure that the image can be accessed from it. Froala Editor uses the link you return for src attribute from img tag. I think you'd have to do something like:
$link = array("link" => $slika . 'public/img/media');