Save value Base64 to Image PNG use Intervention image Laravel Storage - php

How can I convert Base64 value to Image PNG using intervention image and laravel storage?
public function userLogout(Request $request) {
$data = $request->all();
if ($request->isMethod('post')) {
$poster = explode(";base64", $request->picture);
$image_type = explode("image/", $poster[0]);
$mime_type = '.'.$image_type[1];
$image_base = base64_decode($poster[1]);
$data['picture'] = Storage::disk('player-images')->put($image_base, file_get_contents($poster));
$path = public_path('storage/player-images/'.$image_base);
Image::make($poster)->save($path);
$data['picture'] = 'player-images/' . $image_base;
User::where('name', Auth::user()->name)->update($data);
}
return view('gallery');
}
i got an error message:
"file_get_contents() expects parameter 1 to be a valid path, array given"
and here is my ajax function
var canvas = document.getElementById('canvas');
var dataUrl = canvas.toDataURL('image/png');
$(document).ready(function(){
$('#save').click(function(e){
e.preventDefault();
$.ajax({
headers: {'X-CSRF-TOKEN': $('meta[name="csrf_token"]').attr('content')},
type: "POST",
url: "/gallery",
data: {
picture: dataUrl,
}
}).done(function(o) {
console.log("saved");
});
});
});
How can i save the base64 value to database like player-images/blabla.png and store image to path public/storage/player-images/
sorry, my English is bad.
thanks.

I solved it!. I changed the function in controller like this.
public function userLogout(Request $request)
{
$data = $request->all();
if ($request->isMethod('post')) {
if (preg_match('/^data:image\/(\w+);base64,/', $data['picture'])) {
$value = substr($data['picture'], strpos($data['picture'], ',') + 1);
$value = base64_decode($value);
$imageName = time() . '.png';
$val = Storage::disk('player-images')->put($imageName, $value);
$path = public_path('storage/player-images/'.$imageName);
Image::make($data['picture'])->resize(304, 277)->save($path);
$data['picture'] = 'player-images/' . $imageName;
User::where('name', Auth::user()->name)->update(['picture' => $data['picture']]);
}
}
return view('gallery');
}

I know that probably you solved your doubt, but I was looking for something similar and I didn't find it, so I will leave the following code for someone that may need it.
The goal of this code is to get an image from Pixabay using an URL.
My solution for something similar:
public function store(){
$url = json_decode(request('photo')); //Photo is the field that I fill in the view, that contain a URL to my image in pixabay;
$contents = file_get_contents($url);
$name = substr($url, strrpos($url, '/') + 1);
$blob = base64_encode($this->resizeImage($contents));
Photos::firstOrCreate(['photo' => $name,'thumb' => $blob]); //Photos is my model
}
private function resizeImage($contents) : string {
return (string) Image::make($contents)->resize(75, 75)->encode('data-url'); // Very important this cast to String, without it you can not save correctly the binary in your DB;
}
View:
For use the code in my view I put:
When I return to view the Model I use a 'for' to print all images, like that:
#foreach($photos as $element)
<img src="{{ base64_decode($element->thumb) }}" alt="" >
#endforeach
#Warning
Is very important you have a Blob field in your DB, so in your Schema on Laravel Migrate you have to put something as: $table->binary('thumb');
You can check my code on my git:
lucasfranson10/multisafepay

Related

Trying to get property of non-object while uploading to database

I have a script when user can clip video, then that video uploads to public folder, and now I want to upload all video data to database. But i get error like in title. Here's my code:
Controller:
public function clip($id)
{
$video = Video::where('id', $id)->first();
$oldId = $video->id;
$originalName = $video->original_name;
$newName = str_random(50) . '.' . 'mp4';
FFMpeg::fromDisk('public')
->open('/uploads/videos/' .$video->file_name)
->addFilter(function ($filters) {
$filters->clip(FFMpeg\Coordinate\TimeCode::fromSeconds(5), FFMpeg\Coordinate\TimeCode::fromSeconds(2));
})
->export()
->toDisk('public')
->inFormat(new \FFMpeg\Format\Video\X264)
->save('/uploads/videos/' . $newName);
$data = ['user_id'=>Auth::user()->id,
'file_name'=>$newName,
'original_name'=> $originalName,
'old_id' => $oldId,
];
$video = Video::edit($data);
}
Model:
public static function edit($request)
{
$video = new Video;
$video->user_id = $request->user_id;
$video->file_name = $request->file_name;
$video->original_name = $request->original_name;
$video->save();
$old = $file = Video::where('id', $request->old_id)->delete();
//$old_file = unlink($request->file('file'));
return $video;
}
What should I edit?
Since you're passing array, you need to use $request['user_id'] syntax instead $request->user_id. You're getting the error because you're trying to treat the array as an object.
But since you have prepared array here, just use create method:
public static function edit($data)
{
$this->destroy($data['old_id']);
return $this->create($data);;
}
Don't forget to add $fillable array to your model to make it work.

Inserts with Laravel 5.1 without page reloading

I've been using Dropzone for several days and I faced some issues. The idea is: the user selects his file, it uploads and goes in his file directory and some of the file's properties (size, name) go in the DB. I can't do it because when the user uploads the file, the page does not refresh and nothing goes in Input::file('file'). I just can't do it. Here is the code i'm using:
class UploadController extends Controller {
public function upload() {
if(Input::hasFile('file')){
$file = Input::file('file');
$user = Auth::id();
$file->move('uploads/'.$user, $file->getClientOriginalName());
}
else {
echo 'Please select a file first';
}
}
Here are the two functions in File.php model
public function getFileId(){
$fileName = Input::file('file')->getClientOriginalName();
$files = File::where('filename', $fileName)->get(); //$fileName
foreach ($files as $file) {
$fileid = $file->fileid;
echo $fileid.'<br>';
Input::file('file')->fileid = $file->fileid; // put fileid as an attribute to the object file for futher usage
}
}
public function incrementFileId(){
$files = File::orderBy('fileid', 'desc')->take(1)->get();
foreach($files as $file){
echo $file->fileid + 1 .' incremented file id<br>';
}
}
So how should my third model function look like to upload the file's properties? DropZone uses Ajax and I though that I should get the file attributes from there but could this be done?!
Use Request instead of Input:
public function upload(Request $request)
{
if ($request->hasFile('file'))
{
$file = $request->file('file');
$file->move('uploads/'.$user, $file->getClientOriginalName());
}

naming a file after submitting a form in Symfony

I am working on a form which accepts some user input and an image file, the submission part and the data getting entered into the database is working fine but I am stuck at how to name a file once it is uploaded, right now this is what i see as an image name in database C:\wamp2.5\tmp\phpF360.tmp which obviously is not correct.
This is what my controller looks like DefaultController.php
public function createBlogAction(Request $request)
{
$post = new Post();
$form = $this->createForm(new PostCreate(), $post);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$post->upload();
$post->setDate(date_create(date('Y-m-d H:i:s')));
$post->setAuthor('ClickTeck');
$em->persist($post);
$em->flush();
$this->get('session')->getFlashBag()->add(
'notice',
'Success'
);
}
return $this->render('BlogBundle:Default:blog-create.html.twig', array(
'form' => $form->createView()
)
);
}
This is what my upload() looks like inside Entity/Post.php which is uploading the file and moving it into the folder, the file name that I see in a folder is correct however now the one that goes into the database
public function upload()
{
if (null === $this->getImage()) {
return;
}
// I might be wrong, but I feel it is here that i need to name the file
$this->getImage()->move(
$this->getUploadRootDir(),
$this->getImage()->getClientOriginalName()
);
$this->path = $this->getUploadDir();
$this->file = null;
}
I will really appreciate if someone can push me in right direction, I just need to name the file, a name which gets assigned to the image in database and the file should get uploaded with the same name as well.
UPDATE
I managed to get it to work using the following function, not sure if this is the best practice but it did work, i would love to hear from others on this. please do not provide any links, if you can refine what has already been done that would be great.
public function upload()
{
// the file property can be empty if the field is not required
if (null === $this->getImage()) {
return;
}
$dirpath = $this->getUploadRootDir();
$image = $this->getImage()->getClientOriginalName();
$ext = $this->getImage()->guessExtension();
$name = substr($image, 0, - strlen($ext));
$i = 1;
while(file_exists($dirpath . '/' . $image)) {
$image = $name . '-' . $i .'.'. $ext;
$i++;
}
$this->getImage()->move($dirpath,$image);
$this->image = $image;
$this->path = $this->getUploadDir();
$this->file = null;
}
This topic from documentation may help you : http://symfony.com/doc/current/cookbook/doctrine/file_uploads.html
In addition, you should not put your upload function in the controller but rather use Doctrine events (Lifecycle callbacks) to call your function automatically.
as per suggestion of #theofabry you can check symfony2 documentation How to handle File Uploads with Doctrine, Controller must be thin as much as possible and try to do upload with Doctrine Events.
If you want to continue with your logic you may try following code, I have not tested yet...so please be careful.
// set the path property to the filename where you'ved saved the file
$this->path = $this->file->getClientOriginalName();
instead of
$this->path = $this->getUploadDir();

How to make a fast ajax live search

Hi, im trying to do a ajax live search. It work`s, but i want it to be fast. Currently i`m processing the html by php, but even if i change the processing to js and only get the data from php it only improves my search from 2.1 to 1.8 seconds (this is the request time, but it takes 4/5 seconds for the data to appear)
Heres my code:
$("#searchfield").change(function() {
term = $(this).val();
if (searchReq != false) {
searchReq.abort();
}
searchReq = $.get("/searchModal.php", {
term : term
}).done(function(data) {
$("#liveSearch").html(data);
});
});
EDIT:
php code:
search.php:
$files = filecontroller::search($term);
file controller:
public static function search($term, $by = false, $order = false) {
connection::connect();
$files = ($by && $order && validation::filesOrder($by, $order)) ? file::Search($term, $by, $order) : file::Search($term);
return $files;
}
File model:
public static function Search($term, $by = 'date', $order = 'DESC') {
$session_id = $_SESSION["user_id"];
$term = mysql_real_escape_string($term);
$query = mysql_query("SELECT * FROM files WHERE idUser = '$session_id' AND (name LIKE '%$term%' OR description LIKE '%$term%') ORDER BY $by $order");
$files = self::CreateFromDb($query);
return $files;
}
private static function CreateFromDb($query) {
GLOBAL $imgDir; // just get the img dir from a config file
GLOBAL $userDir; // same
$files = array();
while ($row = mysql_fetch_assoc($query)) {
$file = new File();
$file -> type = $row['type'];
$file -> idFile = $row['idFile'];
$file -> user = $row['idUser'];
$file -> gallery = $row['idGallery'];
$file -> name = htmlspecialchars($row['name']);
$file -> description = htmlspecialchars($row['description']);
$file -> date = $file -> timecheck($row['date']);
$file -> size['kb'] = $row['size'];
$file -> galleryName = Gallery::getName($file -> gallery);
$files[] = $file;
}
return $files;
}
Is there anyway to improve it? Im testing in local.
There are some issues with your code, but nothing obvious.
Some starting points:
The best way to find what's slow is probably to check profiling in PHP.
Another thing is that you're using LIKE "%x%" which will be slow if your user has lots of files (seems unlikely, but who knows). Check the MySQL slow query log.
You're also doing some disk access, but it shouldn't be this slow either - unless something strange is going on inside Gallery::getName or timecheck.
Note that the mysql extension has been deprecated. This has nothing to do with speed though, it's just outdated.
ANSWER
.change has a delay, for real time results its better to use .keyup. I cme up using a timeout to make the request only when user stop typing:
var searchTimeout;
var searchReq;
$("#searchfield").on('keyup', function() {
term = $(this).val();
if (searchTimeout) {
clearTimeout(searchTimeout);
}
if (searchReq) {
searchReq.abort();
}
searchTimeout = setTimeout(function(){
if (term.length > 2) {
searchController(term).then(function(data) {
$("#liveSearch").html(data);
});
}
else {
$("#liveSearch").html("");
}
},500);
});
function searchController(term) {
searchReq = $.ajax({
type : "GET",
url : "/searchModal.php",
data : {
term : term
},
async : true,
context : this,
beforeSend : function() {
},
complete : function() {
}
});
return searchReq;
}
Its still slow compared to facebook, and other big sites. I guess the only way to acess it fast would be with a great server or cached results (i tried to just echo an string without bd requests and its slow too).

How to call UploadHandler.php with PHP - blueimp jQuery File Upload

Does anyone know how to upload images using PHP and calling the UploadHandler.php?
I'm not sure what information needs to be passed and in what format.
Here's what I have so far:
$prop="test";
session_id($prop);
#session_start();
$url = 'http://christinewilson.ca/wp-content/uploads/2013/02/port_rhdefence.png';
$file_name[] = file_get_contents($url);
error_reporting(E_ALL | E_STRICT);
require('UploadHandler.php');
$upload_handler = new UploadHandler(array(
'user_dirs' => true
));
The response is contained within the UploadHandler class object and can be retrieved like shown below.
$upload_handler = new UploadHandler();
$response = $upload_handler->response;
$files = $response['files'];
$file_count = count($files);
for ($c = 0; $c < $file_count; $c++) {
if (isset($files[$c]->error))
continue;
$type = $files[$c]->type;
$name = $files[$c]->name;
$url = $files[$c]->url;
}
I could not find a way to get the file name via php so I had to do it myself.
First you need to add a public variable under UploadHandler.php
class UploadHandler
{
public $file_name;
protected $options;
and then add that to the function that creates the name
protected function get_file_name($name,
$type = null, $index = null, $content_range = null) {
$this->file_name = $this->get_unique_filename(
$this->trim_file_name($name, $type, $index, $content_range),
$type,
$index,
$content_range
);
return $this->file_name;
}
then under index.php you could do something like this
$upload_handler = new UploadHandler();
echo "\r\n [" . $upload_handler->fileName . "]\r\n";
I hope this help you or save someone some time :)
you can use the basic plugin:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>jQuery File Upload Example</title>
</head>
<body>
<input id="fileupload" type="file" name="files[]" data-url="server/php/" multiple>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="js/vendor/jquery.ui.widget.js"></script>
<script src="js/jquery.iframe-transport.js"></script>
<script src="js/jquery.fileupload.js"></script>
<script>
$(function () {
$('#fileupload').fileupload({
dataType: 'json',
done: function (e, data) {
$.each(data.result.files, function (index, file) {
$('<p/>').text(file.name).appendTo(document.body);
});
}
});
});
</script>
</body>
I ran into the same problem, where in the PHP I wanted to write all the URLS that UploadHandler.php had created to a mySQL database. If you look through the code, you'll see that
public function post($print_response = true)
actually returns the data structure from generate_response (which is a array with all the processed image metadata like image size, sanitized url, etc), but the call to $this->post() never does anything which it. So I add a variable
protected $upload_content = [];
to the class definition and changed the logic in function
protected function initialize()
to
case 'POST':
$this->upload_content = $this->post(false);
break;
to update this variable after the images have been processed (you would need to do something similar with the GET case if you are using that). Then, I add a public function to the class to get this variable
public function get_upload_content() {
return $this->upload_content;
}
and now the UploadHandler class can be called like this
$upload_handler = new UploadHandler();
$images = $upload_handler->get_upload_content();
// Call a function that writes the urls in $images array to a database
Hope this helps!
First of all you should create protected variable:
protected $options;
protected $uploaded_files = [];
then you should assign to this variable the response value in post() method:
$this->uploaded_files = $response;
return $this->generate_response($response, $print_response);
then you should create public method which would return that response:
public function get_uploaded_files() {
return $this->uploaded_files;
}
and finally you should initiate the class and call the method:
$uploadPicture = new UploadHandler();
$images = $uploadPicture->get_uploaded_files();
Hope this Helps !

Categories