Since it's not a large number of images that my db will take, i'm uploading them directly to database. However, i'm having problems displaying them, i don't want to download them, i want to see them on the page. I'm trying to display with the following code but it's not working:
function display() of MyFiles Controller:
function display($id)
{
$file = $this->MyFile->findById($id);
$this->set('image',$file['MyFile']['data']);
}
MyFile Model:
<?php
class MyFile extends AppModel {
var $name = 'MyFile';
}
?>
function add() of MyFilesController
function add() {
if (!empty($this->data) &&
is_uploaded_file($this->data['MyFile']['File']['tmp_name'])) {
$fileData = fread(fopen($this->data['MyFile']['File']['tmp_name'], "r"),
$this->data['MyFile']['File']['size']);
$this->request->data['MyFile']['name'] = $this->data['MyFile']['File']['name'];
$this->request->data['MyFile']['type'] = $this->data['MyFile']['File']['type'];
$this->request->data['MyFile']['size'] = $this->data['MyFile']['File']['size'];
$this->request->data['MyFile']['data'] = $fileData;
$this->MyFile->save($this->request->data);
$this->redirect(array('controller'=>'posts','action'=>'index'));
}
}
EDIT:
display.ctp of MyFiles View
<?php
echo '<img src="/MyFilesController/display/4" />';
?>
Saving images in a database is generally not a good idea.
You are far better off (and I assume you have done this for 'security') saving the files in a folder that is not web accessible and using Media Views to render them. This way you can still keep your security checks as you are using a controller to render the image.
Cakes media views are designed for streaming files to the browser and can easily be configured for images.
2.3 has a new feature for this
If you are not doing this for security reasons just save your self the problems and put them in webroot.
Related
i am trying to create a chart in PHP through pChart 2.3 class.
My doubt is on this function:
function autoOutput(string $FileName = "output.png", int $Compression = 6, $Filters = PNG_NO_FILTER)
{
if (php_sapi_name() == "cli") {
$this->Render($FileName, $Compression, $Filters);
} else {
$this->Stroke(TRUE, $Compression, $Filters);
}
}
Html Code:
<div id="filtri">
<?php include($_SERVER['DOCUMENT_ROOT'] . "/reportingBug/generaGrafico1.php");?>
<?php include($_SERVER['DOCUMENT_ROOT'] . "/reportingBug/recuperaTempiMediLavBug.php");?>
<?php include($_SERVER['DOCUMENT_ROOT'] . "/reportingBug/recuperaTempiMediBug.php");?>
<img src="temp/example.drawBarChart.spacing.png">
</div>
Php Script:
/* Render the picture (choose the best way) */
$myPicture->autoOutput("temp/example.drawBarChart.spacing.png");
?>
If i force the code in order to follow the if branch with Render function everything is working right
because it creates a PNG image in root folder and i can retrieve it from HTML.
but it goes through the else branch, so the stroke function is called.
In the case, i have two problems:
i don't know how to retrieve the PNG from HTML
i have a problem because the browser shows following:
I tried to use a phisical image (PNG file create on the server folder) but i think it's not correct because many user will access the application concurrently.
I need to send an image to server via an ajax request and it gets through just fine
and in my controller I can just use $_FILES["image"] to do stuff to it.
But I need to validate the image before I save it.
And in the Yii this can be achieved by doing something like this
$file = CUploadedFile::getInstance($model,'image');
if($model->validated(array('image'))){
$model->image->saveAs(Yii::getPathOfAlias('webroot') . '/upload/user_thumb/' . $model->username.'.'.$model->photo->extensionName);
}
But the problem is I don't have a $model, all I have is $_FILES["image"], now what should I put instead of the $model???
is there any other way where I can validate and save files without creating a model and just by Using $_FILES["image"]?
thanks for this awesome community... :)
Exists many ways how you can do upload. I want offer to you one of them.
1.You need to create model for your images.
class Image extends CActiveRecord {
//method where need to specify validation rules
public function rules()
{
return [
['filename', 'length', 'max' => 40],
//other rules
];
}
//this function allow to upload file
public function doUpload($insName)
{
$file = CUploadedFile::getInstanceByName($insName);
if ($file) {
$file->saveAs(Yii::getPathOfAlias('webroot').'/upload/user_thumb/'.$this->filename.$file->getExtensionName());
} else {
$this->addError('Please, select at least one file'); // for example
}
}
}
2.Now, need to create controller, where you will do all actions.
class ImageController extends CController {
public function actionUpload()
{
$model = new Image();
if (Yii::app()->request->getPost('upload')) {
$model->filename = 'set filename';
$insName = 'image'; //if you try to upload from $_FILES['image']
if ($model->validate() && $model->doUpload($insName)) {
//upload is successful
} else {
//do something with errors
$errors = $model->getErrors();
}
}
}
}
Creating a model might be overkill in some instances.
The $_FILE supervariable is part of the HTTP mechanism.
You can handle the copy by using the native PHP function move_uploaded_file()
$fileName = "/uploads/".myimage.jpg";
unlink($fileName);
move_uploaded_file($_FILES['Filedata']['tmp_name'], $fileName);
However, you lose the niceties of using a library that provides additional functionality and checks (eg file type and file size limitations).
I'm using a plugin called jQuery file upload to upload images to a page. Currently it uploads with the original image name as the file name (IMG_1234). I need a specific format for the image name on the server (eg 1.123456.jpg)
I found this PHP code that works for changing the image name:
class CustomUploadHandler extends UploadHandler
{
protected function trim_file_name($name, $type) {
$name = time()."_1";
$name = parent::trim_file_name($name, $type);
return $name;
}
}
When I upload an image, it is named correctly, but the link for the image preview is undefined. This prevents me from deleting the image via the plugin.
The variable data.url is undefined... If I go back to the original code that doesn't rename the image, everything works fine.
Has anyone had any experience with this plugin that could help? Thanks!
EDIT:
I've found part of the problem at least...the function to return the download link (which is also used for deletion) is giving the original file name, not the updated one. I am really new to PHP classes, so I'm not sure where the variable originates and how to fix it. I'd really appreciate any help I can get!
Here's the PHP code for that function:
protected function get_download_url($file_name, $version = null, $direct = false) {
if (!$direct && $this->options['download_via_php']) {
$url = $this->options['script_url']
.$this->get_query_separator($this->options['script_url'])
.'file='.rawurlencode($file_name);
// The `$file_name` variable is the original image name (`IMG_1234`), and not the renamed file.
if ($version) {
$url .= '&version='.rawurlencode($version);
}
return $url.'&download=1';
}
if (empty($version)) {
$version_path = '';
} else {
$version_url = #$this->options['image_versions'][$version]['upload_url'];
if ($version_url) {
return $version_url.$this->get_user_path().rawurlencode($file_name);
}
$version_path = rawurlencode($version).'/';
}
return $this->options['upload_url'].$this->get_user_path()
.$version_path.rawurlencode($file_name);
}
EDIT 2: I think it has something to do with 'param_name' => 'files', in the options. Anyone know what that does?
Fixed it by editing the trim_file_name function inside UploadHandler.php instead of extending the class in index.php.
Very nasty problem, I made a very long investigation to find out what was the origin of the bug. I made an original post for this, but I deleted it to create a new fresh post. So let's start by the start. Thank you in advance for reading this until the end.
I have a View Helper Pub.php. This one display randomly an ad. $this->pub() is called in the layout.phtml and in the phtml view files. The Helper also increments the number of impression before displaying it.
Pub.php
Class My_View_Helper_Pub extends Zend_View_Helper_Abstract {
public function pub( $place, $format ) {
// Extract the active campaigns, then randomly select one
$campaigns = $model->getActiveCampaigns();
...
// Increase the number of view for this campaign (in MySQL)
$model->increasePrint($campaign->id);
// And display the banner
echo $this->generateHtml($campaign->filename);
}
public function generateHtml($filename){
// Generate the html according to the filename (image, flash, custom tag etc...)
return $code;
}
IncreasePrint()
public function increasePrint($id){
$table = $this->getTable();
$row = $table->find($id)->current();
$row->imp_made = $row->imp_made + 1;
return $row->save();
}
My layout.phtml is also simple :
<html>
<head>
<?= $this->pub(null, 'css') ?>
</head>
<body>
<?= $this->pub(null, 'big_banner' ?>
</body>
Problem : On some actions, ads in the layout are selectionned and incremented twice ! As if the helper was instancied again.
After some search, the problem seems to come from another View Helper : LogoEvent. This helper displays a logo/image by returning proper HTML code.
LogoEvent.php
class My_View_Helper_LogoEvent extends Zend_View_Helper_Abstract
{
public function logoEvent($image, $taille = null){
$image = trim($image);
if ($taille){
$width = "max-width: {$taille}px;";
} else {
$width = '';
}
if (!empty($image)){
return '<img src="/images/agenda/logos/'. $image .'" style="'. $width .'" alt="Logo" />';
} else {
return '<img src="/images/agenda/logos/no-logo.png" style="'. $width .'" alt="No Logo" />';
}
}
}
The double-incrementation happens when the file doesn't exist on my hard disk.
Really weird... I tried this :
echo $this->logoEvent( 'existing_image.jpg', '100');
// No problem, everything works fine.
echo $this->logoEvent( 'unexisting_image.jpg', '100');
// => problem.
But
echo htmlentities($this->logoEvent( 'unexisting_image.jpg', '100'));
// No problem, everything works fine.
Someone has better knowledge than me to find out what could be the problem or a way to find it...
Thank you !
I'm almost certain that your problem is from .htaccess, where, be default in ZF, is set to send all non-existing files (the -s condition) to index.php, thus your application will fire up again (possibly into the ErrorController, for 404).
Add this in .htaccess instead, see how it fits (it omits certain files to be routed to index.php):
RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php [NC,L]
I want to upload an image with Zend Framework version 1.9.6. The uploading itself works fine, but I want a couple of other things as well ... and I'm completely stuck.
Error messages for failing to upload an image won't show up.
If a user doesn't enter all the required fields but has uploaded an image then I want to display the uploaded image in my form. Either as an image or as a link to the image. Just some form of feedback to the user.
I want to use Zend_ Validate_ File_ IsImage. But it doesn't seem to do anything.
And lastly; is there some automatic renaming functionality?
All ideas and suggestions are very welcome. I've been struggling for two days now.
These are simplified code snippets:
myform.ini
method = "post"
elements.title.type = "text"
elements.title.options.label = "Title"
elements.title.options.attribs.size = 40
elements.title.options.required = true
elements.image.type = "file"
elements.image.options.label = "Image"
elements.image.options.validators.isimage.validator = "IsImage"
elements.submit.type = "submit"
elements.submit.options.label = "Save"
TestController
<?php
class Admin_TestController extends Zend_Controller_Action
{
public function testAction ()
{
$config = new Zend_Config_Ini(MY_SECRET_PATH . 'myform.ini');
$f = new Zend_Form($config);
if ($this->_request->isPost())
{
$data = $this->_request->getPost();
$imageElement = $f->getElement('image');
$imageElement->receive();
//$imageElement->getValue();
if ($f->isValid($data))
{
//save data
$this->_redirect('/admin');
}
else
{
$f->populate($data);
}
}
$this->view->form = $f;
}
}
?>
My view just echo's the 'form' variable.
First, put this at the start of your script:
error_reporting(E_ALL);//this should show all php errors
I think the error messages are missing from the form because you re-populate the form before you display it. I think that wipes out any error messages. To fix that, remove this part:
else
{
$f->populate($data);
}
To show the uploaded image in the form, just add a div to your view template, like this:
<div style="float:right"><?=$this->image?></div>
If the image uploaded ok, then populate $view->image with an img tag.
As for automatic re-naming, no, it's not built in, but it's very easy. I'll show you how below.
Here's how I handle my image uploads:
$form = new Zend_Form();
$form->setEnctype(Zend_Form::ENCTYPE_MULTIPART);
$image = new Zend_Form_Element_File('image');
$image->setLabel('Upload an image:')
->setDestination($config->paths->upload)
->setRequired(true)
->setMaxFileSize(10240000) // limits the filesize on the client side
->setDescription('Click Browse and click on the image file you would like to upload');
$image->addValidator('Count', false, 1); // ensure only 1 file
$image->addValidator('Size', false, 10240000); // limit to 10 meg
$image->addValidator('Extension', false, 'jpg,jpeg,png,gif');// only JPEG, PNG, and GIFs
$form->addElement($image);
$this->view->form = $form;
if($this->getRequest()->isPost())
{
if(!$form->isValid($this->getRequest()->getParams()))
{
return $this->render('add');
}
if(!$form->image->receive())
{
$this->view->message = '<div class="popup-warning">Errors Receiving File.</div>';
return $this->render('add');
}
if($form->image->isUploaded())
{
$values = $form->getValues();
$source = $form->image->getFileName();
//to re-name the image, all you need to do is save it with a new name, instead of the name they uploaded it with. Normally, I use the primary key of the database row where I'm storing the name of the image. For example, if it's an image of Person 1, I call it 1.jpg. The important thing is that you make sure the image name will be unique in whatever directory you save it to.
$new_image_name = 'someNameYouInvent';
//save image to database and filesystem here
$image_saved = move_uploaded_file($source, '/www/yoursite/images/'.$new_image_name);
if($image_saved)
{
$this->view->image = '<img src="/images/'.$new_image_name.'" />';
$form->reset();//only do this if it saved ok and you want to re-display the fresh empty form
}
}
}
First, have a look at the Quick Start tutorial. Note how it has an ErrorController.php that will display error messages for you. Also note how the application.ini has these lines to cause PHP to emit error messages, but make sure you're in the "development" environment to see them (which is set in public/.htaccess).
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
Second, ZF has a renaming filter for file uploads:
$upload_elt = new Zend_Form_Element_File('upload');
$upload_elt
->setRequired(true)
->setLabel('Select the file to upload:')
->setDestination($uploadDir)
->addValidator('Count', false, 1) // ensure only 1 file
->addValidator('Size', false, 2097152) // limit to 2MB
->addValidator('Extension', false, 'doc,txt')
->addValidator('MimeType', false,
array('application/msword',
'text/plain'))
->addFilter('Rename', implode('_',
array($this->_user_id,
$this->_upload_category,
date('YmdHis'))))
->addValidator('NotExists', false, $uploadDir)
;
Some of the interesting things above:
mark the upload as required (which your .ini doesn't seem to do)
put all the uploads in a special directory
limit file size and acceptable mime types
rename upload to myuser_category_timestamp
don't overwrite an existing file (unlikely, given our timestamp scheme, but let's make sure anyway)
So, the above goes in your form. In the controller/action that receives the upload, you could do this:
$original_filename = $form->upload->getFileName(null, false);
if ($form->upload->receive()) {
$model->saveUpload(
$this->_identity, $form->upload->getFileName(null, false),
$original_filename
);
}
Note how we capture the $original_filename (if you need it) before doing receive(). After we receive(), we do getFileName() to get the thing that the rename filter picked as the new filename.
Finally, in the model->saveUpload method you could store whatever stuff to your database.
Make sure your view also outputs any error messages that you generate in the controller: loading errors, field validation, file validation. Renaming would be your job, as would other post processing such as by image-magick convert.
When following lo_fye's listing I experienced problems with custom decorators.
I do not have the default File Decorator set and got the following exception:
Warning: Exception caught by form: No file decorator found... unable to render file element Stack Trace:
The Answer to this is that one of your decrators must implement the empty interface Zend_Form_Decorator_Marker_File_Interface
Also sometimes it happens to bug when using an ajax request. Try it without an ajax request and don't forget the multipart form.