I have blob data in my database and they are images that I want to display as a basic gallery.
I have a method that I have written to display the images, but I'm getting an error, saying that it is a string, rather than blob data being returned:
public function getFilenamePath()
{
$file_src = false;
if (null !== $fp = $this->getFilename())
{
$file = stream_get_contents($fp);
$file_src = '/uploads/gallery/'.$this->getId().'.jpg';
}
return $file_src;
}
where getFilename() is my blob column.
action:
public function executeSingle(sfWebRequest $request)
{
$application_id = $this->getRequestParameter('id');
$c = new Criteria();
$c->addJoin(GalleryPeer::APPLICATION_ID, ApplicationPeer::ID);
$c->addJoin(GalleryImagePeer::GALLERY_ID, GalleryPeer::ID);
$c->add(GalleryPeer::APPLICATION_ID, $application_id);
$this->galleries = GalleryImagePeer::doSelect ( $c );
}
template:
foreach($galleries as $gallery)
{
$path = $gallery->getFilenamePath();
if($path)
{
echo '<img src="'.$path.'" />';
}
}
The error I get is that stream_get_contents seems to be returning a string.
Is there anyway, I can get the blob data, or rather than use a model method, use an action to return all the images attached to the application?
Thanks
If you store images in the database, you have (basically) two options to show them on the client:
First solution: Get file content and encode it with base64 encoding. You can find a working example here:
http://www.php.net/manual/en/function.base64-encode.php#99842
This method is not the best as if you do it like that, the client won't be able to cache these images, that means more traffic, more processing time, more database connection, slower page loading etc.
Second solution: You create an image loading action in Symfony. The routing is like:
mapimage:
url: /myimage/:image_id.png
param: { module: myimagemodul, action: myimageaction }
You have to create a controller action myimageaction and there you can get the image ID like
$request->getParameter('image_id');
And get the blob data from the database and return it as binary with specific http headers. You can find working examples with simple Googleing, one example:
$this->image = ImagePeer::retrieveByPk ($request->getParameter('image_id'));
$response = $this->getResponse();
$response->clearHttpHeaders();
$response->setContentType ($this->image->getMimeType());
$response->setHttpHeader ('Content-Disposition', 'inline;filename='.$filename);
$content = $this->image->getData();
$response->setContent (stream_get_contents ($content));
$this->setLayout (false);
return sfView::NONE;
So in the template you can do like:
<img src='<?= url_for ('route_to_action_above', array ('image_id' => $image->getId()) ?>'/>
I have found this one at
http://forum.symfony-project.org/viewtopic.php?f=22&t=31207#p109705
This code doesn't make any sense.
Why do you feed binary(read string) data from ->getFilename() to stream_get_contents() which operates ONLY on resource data type? Of course it will complain.
Outputing blob to a browser is as simple as:
$this->getResponse->setContentType('image/jpeg');
echo $data->getFilename(); // assuming filename column is your blob column
try switching your getFilenamePath function to this.
public function getFilenamePath() {
$file_src = '/uploads/gallery/'.$this->getId().'.jpg';
if (file_exists($file_src ) {
return $file_src;
} else {
return false;
}
}
$profile_picture = base64_encode(stream_get_contents($image->getContent()));
echo '<img src="data:image/jpeg;base64,'.$profile_picture.'" />';
Related
I'm new in Laravel, and I'm doing a project for my university, and I've two problems when I try to delete:
First error: When I try to delete the records, only the first one (with ID 1) doesn't delete from the table, but the other if deleted from the table and I've already tried some things to fix the error, but I couldn't:
Controller.php:
public function destroy_int($inst_id)
{
$inst = InstitucionEntidadInt::where('id', $inst_id);
$inst->delete();
return redirect('/activities/cons_instituciones_int');
}
Web.php:
Route::delete('/delete_inst_int/{inst_id}', [InstEntController::class, 'destroy_int'])
->name('institucion_int.destroy');
Second error: In some forms, it's necessary to upload and save files in a database (so I save just the name in the database and the files are saved in the public path). And some of this input files are multiple, so I save the names in the database like a JSON (using the json_encode method):
//This is the way that I save the files
$files = [];
if ($request->hasFile('inst_docsoporteNac')) {
foreach ($request->file('inst_docsoporteNac') as $file) {
$name = time() . "_" . $file->getClientOriginalName();
$file->move(public_path('files/institucionesNac'), $name);
$files[] = $name;
}
}
$instentNact->docSoportes = json_encode($files);
So, I'm trying to implement the delete method and I need to delete the files from both places (from the DB and the public path), I don't know how I can do it and I've already tried some "solutions" that I read from some forums (like this).
Controller.php:
public function destroy_nac($inst_id)
{
$inst = InstEntNac::where('id', $inst_id);
$files = InstEntNac::where('id', $inst_id)->get('docSoportes');
foreach (json_decode($files) as $file) {
Storage::delete(public_path('files/institucionesNac/' . $file));
}
$inst->delete();
return redirect('/activities/cons_instituciones_nac');
}
This is the way that I'm using, but I'm getting an error "Object of class stdClass could not be converted to string".
I'll appreciate your solutions for these errors.
For the first error, you can add error handling using this code:
InstitucionEntidadInt::findOrFail($inst_id)->delete();
For the second error, json_decode returns by default stdClass object instead of array. You can tell the function to return array type with second boolean parameter setting it to true:
json_decode($files, true)
https://www.php.net/manual/en/function.json-decode.php
What I want to do is upload an image to my sql database using an html form and then retrieving it from the database to display it. I`ll show you some code so you can understand what I am trying to do.
1st EDIT: Just linking an image to show the database table I am uploading the image to. The row type is blob --> https://imgur.com/a/KBlNWWN in the code below I edited out the other rows of the DB table, but code for them is actually in.
This is the form that is uploading the image:
<form method="POST" action="/~gd339/ci/index.php/Add/postEvent/<?php echo $societyId ?>" enctype="multipart/form-data">
Event image: <input type="file" name="image"/> <br>
<input type="submit" name="POST" value="Post Event!" class = "unique"/>
What it does is that it posts the data to the postEvent controller:
public function postEvent($society_id) {
$this->load->model('Events_model');
$image = file_get_contents($_FILES['image']['tmp_name']);
$this->Events_model->addEvent($image);
}
Note that to get the image from the form, I am using $image = file_get_contents($_FILES['image']['tmp_name']); data retrieved using post is then sent to addEvent in my model:
public function addEvent ($image) {
$image1 = $this->db->escape($image);
$sql = "INSERT INTO events (event_image) VALUES ($image1)";
$query = $this->db->query($sql);
}
To retrieve the image I am using an image tag with a src that calls a function in the controller:
<img src="http://dragon.maple.as.re/~gd339/ci/index.php/add/getEventImage/<?php echo $row['event_id'] ?>">
public function getEventImage($event_id){
$this->load->model('Societies_model');
$image = $this->Societies_model->getEventImage($event_id);
header("Content-type: image/jpeg");
print($image);
}
code for getEventImage:
public function getEventImage($event_id) {
$data = '';
$sql = "SELECT event_image FROM events WHERE event_id = $event_id";
$query = $this->db->query($sql);
if ($query->num_rows()) {
$data = $query->row_array();
$data = $data['MA_PHOTO'];
$query->free_result();
}
return $data;
}
This results in the image just not showing up. I have been reading other examples here on stackoverflow and all of them, except for 1, use the CI upload library to do what I am trying to do. Is the library the only way to retrieve images using CI or is there something wrong in my code preventing the images to appear when called?
Thanks a lot to whoever will have the patience to go through my code. I know it is a lot but it is the first time I am using CI so im still learning.
I have done a similar process without using CI_Upload.
A useful debug is, using some db tool, save the blob to a file and try to display it (using mspaint, image viewer, etc...)
Before I save the image on database, I use the following function to resize (as I don't need it big) and convert(ensure) that it is a jpeg.
private function get_image_resized($data){
$data = smart_resize_image (
null,
$data,
250,
0,
true,
'return');
$temp_file = tempnam(sys_get_temp_dir(), 'ImageResize');
imagejpeg($data, $temp_file, 100);
$data = file_get_contents($temp_file);
unlink($temp_file);
return $data;
}
smart_resize_image can be found here:
To display the image
function imagem($cd_produto){
$im_produto = $this->produto_model->get_imagem ( $cd_produto );
header ( "Content-type:image/jpeg" );
echo $im_produto;
}
Hope it helps.
I'm using gridfs to store files in MongoDB. I'm facing a problem when I try to show the large pdf file in the browser, which is saved in gridfs. Large files don't show up in the browser, but small files does.
This is the service code
public function getIpFileByFileId() {
$request = $this->request;
$dm = $this->container->get('doctrine_mongodb')->getManager('patient');
$id = $request->get('fileId');
//get doc
$docIpMapping = $dm->getRepository('PatientDocumentsBundle:IPDocuments')->findOneBy([
'id' => $id
]);
$base64 = (base64_encode($docIpMapping->getFile()->getBytes()));
$response['data'] = $base64;
$response['msg'] = 'success';
return $response;
}
And this is the front end code
Ajax(path, data).success(function (result) {
$("#pdfDiv").html('<iframe style="width:100%;height:500px;" src="data:application/pdf;base64,' + result.data + '"></iframe>');
});
Does the code have any issues? How do I display large files in the front end?
Here is my suggestion, without open in new tab,
http://answerexpress.blogspot.com/2018/09/show-preview-of-pdf-file-saved-in.html
I am using Sonata Media Bundle to let users upload PDF files. I want to use Imagick to create a preview image of a pdf document. I have a $media object that holds information about my pdf.
When I do die(dump($media)), I see a media object that includes the following line:
#providerReference: "3c4460aae99b0084d08252065bf3eea1817842d9.pdf"
... and opening that file via:
open -a Preview ./data/storage/faq/0001/01/3c4460aae99b0084d08252065bf3eea1817842d9.pdf
... on my mac yields a fully legible PDF.
The problem is that I also see the following line in the browser:
#binaryContent: null
... which means that I can't dump the binary content into a temporary file for the purpose of having Imagick manipulate it.
How do I get a file path that I can hand off to Imagick?
Here is roughly what worked in order to get me a useful reference to a file, complete with valid binary content.
public function preUpdate(Document $document)
{
$media = $document->getMedia();
if ($media === null) {
return;
}
$mediaName = $media->getName();
if ($media->getContentType() !== 'application/pdf') {
return;
}
$context = $media->getContext();
$formats = $pool->getFormatNamesByContext($context);
if (null === $formats) {
return;
}
$provider = $this->getProvider($media->getProviderName());
$publicUrls = [];
$fullFilePath = $provider->getReferenceImage($media);
}
...
private function getPool()
{
return $this->container->get('sonata.media.pool');
}
...
private function getProvider($name)
{
return $this->container->get($name);
}
this might be a bit of a novice question and here is my situation:
i have a upload form for uploading images. and in my editAction i do:
if ($request->isPost()) {
if (isset($_POST['upload_picture']) && $formImageUpload->isValid($_POST)) {
//here i will add the picture name to my database and save the file to the disk.
}
}
$picVal = $this->getmainPic(); // here i do a simple fetch all and get the picture that was just uploaded
$this->view->imagepath = $picVal;
what happens is that the newly uploaded picture doesn't show. I checked the database and the dick and the file is there.
im thinking the problem might be the order of the requests or something similar.
any ideas?
edit: another thing is that in order to make the new image come up i have to do a SHIFT+F5 and not only press the browser refresh button
edit2: more code
i first call the upload to disk function then if that returns success addthe file to the database
$x = $this->uploadToDiskMulty($talentFolderPath, $filename)
if($x == 'success'){
$model->create($data);
}
the upload function
public function uploadToDiskMulty($talentFolderPath, $filename)
{
// create the transfer adapter
// note that setDestiation is deprecated, instead use the Rename filter
$adapter = new Zend_File_Transfer_Adapter_Http();
$adapter->addFilter('Rename', array(
'target' => $filename,
'overwrite' => true
));
// try to receive one file
if ($adapter->receive($talentFolderPath)) {
$message = "success";
} else {
$message = "fail";
}
return $message;
}
If the picture only appears when you do SHIFT+F5 that means it's a caching problem. Your browser doesn't fetch the image when you upload it. Do you use the same file name?