I'm trying to display a default image in cakePHP when the entry for the file path to the image stored in the DB is empty. What I'm finding is happening with the code below, is that if the DB entry is empty the default image is displayed, but it's also displayed if there is an entry in the DB.
So, for some reason if there is an entry in the DB $image is not being displayed. Appreciate the help.
Paul
<?php
$image = $this->Html->image(
$news['News']['imgPath'],
array('title' => $news['News']['alt_tag'], 'class' => 'left'),
array('escape' => false));
$default_image = "<img src=\"/FBCW_new2/files/uploads/default.jpg\" class=\"left\" alt=\"default image\"/>";
if(file_exists("$image")) $filename = $image;
else $filename = $default_image;
echo $filename;
?>
Resolution:
Since $image is an html string, I added a variable to first check if the file path was empty, and then set the $filename by it.
$photo = $news['News']['imgPath'];
$image = $this->Html->image(
$news['News']['imgPath'],
array('title' => $news['News']['alt_tag'], 'class' => 'left'),
array('escape' => false));
$default_image = "<img src=\"/FBCW_new2/files/uploads/default.jpg\" class=\"left\" alt=\"default image\"/>";
if(!empty($photo)) $filename = $image;
else $filename = $default_image;
echo $filename;
You're checking whether $image is a valid file path, but $image holds an HTML string; therefore, file_exists will almost invariably return false. You want to check if the file path is valid:
if(file_exists(APP . WEBROOT_DIR . '/' . $news['News']['imgPath'])){
// ...
}
Note: Depending on where you're storing these images (and how your storing their file paths), you'll likely need to use the APP constant (and others) to check the correct absolute file path.
You might want to create a helper that does image-replacement like this for you, see Helpers - CakePHP Cookbook 2.0.
Related
first of all to explain what I mean by my question, when I upload my files to the local storage I save them the following way:
$files = $request->file('files');
if ($request->hasFile('files')) {
foreach ($files as $file) {
//Get filename with the extension
$fileNameWithExt = $file->getClientOriginalName();
//Filename to store example: lead_4_document.pdf
$fileNameToStore = 'lead_' . $lead->id . '_' . $fileNameWithExt;
//Upload image
$path = $file->storeAs('/user_uploads', $fileNameToStore);
$lead->uploadFile()->create(array('filename' => $fileNameToStore, 'file_url' => $path, 'lead_id' => $lead->id));
}
}
So essentially I prepend lead_ the lead id and another _ to whatever the file is originally called during upload. The problem I face now is that I need to retrieve the associated files according to my lead ids. Here is my attempt so far:
$searchParam = 'lead_'.$lead->id.'_';
//$fileNames = File::glob('storage/user_uploads/'.$searchParam.'*');
//$files = File::get($fileNames);
$allFiles = Storage::files('user_uploads');
dd($allFiles);
Just to clarify, the 'File::glob' way seems to work, though it only outputs the names of the files not the actual files as object, which is what I need.
Okay, so I took a step back and went about this whole associated uploaded file to lead relationship a different way. Here is how I did it, just in case anyone stumbles across this and find themselves in the same boat as me.
The file upload now does a couple of things:
//check if file(s) is present in the request
if ($request->hasFile('files')) {
//checks if a directory already exists for a given lead (by id)
if (Storage::exists('/leads/'.$request->lead_id)) {
//if yes set the directory path to the existing folder
$directory = '/leads/'.$request->lead_id;
}
else {
//if not create a new directory with the lead id
Storage::makeDirectory('/leads/'.$request->lead_id);
$directory = '/leads/'.$request->lead_id;
}
foreach ($files as $file) {
//Get filename with the extension
$fileNameWithExt = $file->getClientOriginalName();
//Filename to store example: lead_4_document.pdf
$fileNameToStore = 'lead_' . $lead->id . '_' . $fileNameWithExt;
//Upload image
//'/user_uploads'
$file->storeAs($directory, $fileNameToStore);
//$lead->uploadFile()->create(array('filename' => $fileNameToStore, 'file_url' => $path, 'lead_id' => $lead->id));
}
}
So essentially, instead of trying to put all files into a single folder then checking the individual files for the 'lead_##' prepend, I instead create a folder with the id of the lead, this I then use the following way in my view function:
$directory = '/leads/'.$lead->id;
if (Storage::exists($directory)) {
$files = File::files('storage/'.$directory);
}
else {
$files = '';
}
Simply checking if the directory exists with the given lead ID, then if there are files uploaded either assign it the content, or set it blank (this is used for displaying an 'attachments' section on my page if not empty).
I have a site where there is member registration. All data will be saved but I get only this error:
Could not move the file "/tmp/phpa4pH3I" to "/home/sporter/public_html/someonect.org/uploads\membersImages/33921.jpg" ()
My code is like this
public function store(){
// dd(Input::all());
$validator = Validator::make(Input::all(), Members::$rules);
if($validator->passes()):
$first_name = Input::get('mem_firstName');
$last_name = Input::get('mem_lastName');
$email = Input::get('mem_email');
$image = Input::get('mem_image');
$phone = Input::get('mem_phone');
$occupation = Input::get('mem_occupation');
$citizen = Input::get('mem_citizen');
$address = Input::get('mem_address');
$destinationPathImage = str_replace('PROJECT\\', '', base_path().'\uploads\membersImages\\') ;
//Generating a random name
$randomName = rand(11111,99999);
//Renaming the image
$ImageName = $randomName.'.'.'jpg'; // renameing image
$imagePath = $destinationPathImage.$ImageName;
Members::create([
'first_name'=>$first_name,
'last_name'=>$last_name,
'email'=>$email,
'image'=>$imagePath,
'phone'=>$phone,
'occupation' => $occupation,
'citizen' => $citizen,
'address'=>$address
]);
...
I don't understrand clearly your str_replace part, but if you setup your url in config properly, you don't need this.
I'm using this kind of upload for an image:
if($request->hasFile('mem_image')) {
$file = $request->file('mem_image');
$ext = $request->file('mem_image')->getClientOriginalExtension();
$filename = rand(11111,99999). '.' . $ext;
$file->move('./uploads/', $filename);
$member->mem_image = '/uploads/' . $filename;
$member->save();
}
In case, your uploads directory is in your public folder.
If your script have permission for writing in target folder. The problem can be only in path. Check what contain in variable $destinationPathImage. It must be correct and exists path. In your error message I see problem with slashes.
also think that it's be cool to check exists of destination folder and file exists before save to database record with path of file.
You're not using the proper slashes.
Replace \uploads\membersImages\\ with /uploads/membersImages/.
If it still not working, please double check the permissions in that folder using the is_writable php function. However, have in mind that the is_writable function is not working properly on windows platforms.
I am able to get the web path to the file like so:
$filename = 'elephant.jpg';
$path_to_file = $this->getSkinUrl('manufacturertab');
$full_path = $path_to_file . '/' . $filename;
But if the file doesn't exist, then I end up with a broken image link.
I tried this:
if(!file_exists($full_path)) {
Mage::log('File doesn\'t exist.');
} else {
?><img src="<?php echo $full_path ?>" /><?php
}
Of course that didn't work because file_exists does not work on urls.
How do I solve this?
1.)
Can I translate between system paths and web urls in Magento?
e.g. something like (pseudocode):
$system_path = $this->getSystemPath('manufacturertab');
That looks symmetrical and portable.
or
2.)
Is there some PHP or Magento function for checking remote resource existence? But that seems a waste, since the resource is really local. It would be stupid for PHP to use an http method to check a local file, wouldn't it be?
Solution I am currently using:
$system_path = Mage::getBaseDir('skin') . '/frontend/default/mytheme/manufacturertab'; // portable, but not pretty
$file_path = $system_path . '/' . $filename;
I then check if file_exists and if it does, I display the img. But I don't like the asymmetry between having to hard-code part of the path for the system path, and using a method for the url path. It would be nice to have a method for both.
Function
$localPath = Mage::getSingleton( 'core/design_package' )->getFilename( 'manufacturertab/' . $filename, array( '_type' => 'skin', '_default' => false ) );
will return the same path as
$urlPath = $this->getSkinUrl( 'manufacturertab/' . $filename );
but on your local file system. You can omit the '_default' => false parameter and it will stil work (I left it there just because getSkinUrl also sets it internaly).
Note that the parameter for getSkinUrl and getFilename can be either a file or a directory but you should always use the entire path (with file name) so that the fallback mechanism will work correctly.
Consider the situation
skin/default/default/manufacturertab/a.jpg
skin/yourtheme/default/manufacturertab/b.jpg
In this case the call to getSkinUrl or getFilename would return the path to a.jpg and b.jpg in both cases if file name is provided as a parameter but for your case where you only set the folder name it would return skin/yourtheme/default/manufacturertab/ for both cases and when you would attach the file name and check for a.jpg the check would fail. That's why you shold always provide the entire path as the parameter.
You will still have to use your own function to check if the file exists as getFilename function returns default path if file doesn't exist (returns skin/default/default/manufacturertab/foo.jpg if manufacturertab/foo.jpg doesn't exist).
it help me:
$url = getimagesize($imagepath); //print_r($url); returns an array
if (!is_array($url))
{
//if file does not exists
$imagepath=Mage::getDesign()->getSkinUrl('default path to image');
}
$fileUrl = $this->getSkinUrl('images/elephant.jpg');
$filePath = str_replace( Mage::getBaseUrl(), Mage::getBaseDir() . '/', $fileUrl);
if (file_exists($filePath)) {
// display image ($fileUrl)
}
you can use
$thumb_image = file_get_contents($full_path) //if full path is url
//then check for empty
if (#$http_response_header == NULL) {
// run check
}
you can also use curl or try this link http://junal.wordpress.com/2008/07/22/checking-if-an-image-url-exist/
Mage::getBaseDir() is what you're asking for. For your scenario, getSkinBaseDir() will perform a better job.
$filename = 'elephant.jpg';
$full_path = Mage::getDesign()->getSkinBaseDir().'/manufacturertab/'.$filename;
$full_URL=$this->getSkinUrl('manufacturertab/').$filename;
if(!is_file($full_path)) {
Mage::log('File doesn\'t exist.');
} else {
?><img src="<?php echo $full_URL ?>" /><?php
}
Note that for the <img src> you'll need the URL, not the system path. ...
is_file(), rather than file_exists(), in this case, might be a good option if you're sure you're checking a file, not a dir.
You could use the following:
$file = 'http://mysite.co.za/files/image.jpg';
$file_exists = (#fopen($file, "r")) ? true : false;
Worked for me when trying to check if an image exists on the URL
I made Joomla admin component according to Joomla guide - http://docs.joomla.org/Developing_a_Model-View-Controller_Component/2.5/Developing_a_Basic_Component
In that i need to have file uploader which let user to upload single file.
In administrator\components\com_invoicemanager\models\forms\invoicemanager.xml i have defined
<field name="invoice" type="file"/>
In the controller administrator\components\com_invoicemanager\controllers\invoicemanager.php im trying to retrieve that file like below. But its not working (can't retrieve file)
Where am i doing it wrong ?
How can i get file and save it on disk ?
class InvoiceManagerControllerInvoiceManager extends JControllerForm
{
function save(){
$file = JRequest::getVar( 'invoice', '', 'files', 'array' );
var_dump($file);
exit(0);
}
}
make sure that you have included enctype="multipart/form-data" in the form that the file is being submitting. This is a common mistake
/// Get the file data array from the request.
$file = JRequest::getVar( 'Filedata', '', 'files', 'array' );
/// Make the file name safe.
jimport('joomla.filesystem.file');
$file['name'] = JFile::makeSafe($file['name']);
/// Move the uploaded file into a permanent location.
if (isset( $file['name'] )) {
/// Make sure that the full file path is safe.
$filepath = JPath::clean( $somepath.'/'.strtolower( $file['name'] ) );
/// Move the uploaded file.
JFile::upload( $file['tmp_name'], $filepath );}
Think i found the solution :)
$file = JRequest::getVar('jform', null, 'files', 'array');
Saving part is mentioned here - http://docs.joomla.org/Secure_coding_guidelines
For uploading the file from your component, you need to write your code in the controller file and you can extend the save() method. check the code given below -
public function save($data = array(), $key = 'id')
{
// Neccesary libraries and variables
jimport('joomla.filesystem.file');
//Debugging
ini_set("display_error" , 1);
error_reporting(E_ALL);
// Get input object
$jinput = JFactory::getApplication()->input;
// Get posted data
$data = $jinput->get('jform', null, 'raw');
$file = $jinput->files->get('jform');
// renaming the file
$file_ext=explode('.',JFile::makeSafe($file['invoice']['name'])); // invoice - file handler name
$filename = round(microtime(true)) . '.' . strtolower(end($file_ext));
// Move the uploaded file into a permanent location.
if ( $filename != '' ) {
// Make sure that the full file path is safe.
$filepath = JPath::clean( JPATH_ROOT."/media/your_component_name/files/". $filename );
// Move the uploaded file.
if (JFile::upload( $file['invoice']['tmp_name'], $filepath )) {
echo "success :)";
} else {
echo "failed :(";
}
$data['name'] = $filename ; // getting file name
$data['path'] = $filepath ; // getting file path
$data['size'] = $file['invoice']['size'] ; // getting file size
}
JRequest::setVar('jform', $data, 'post');
$return = parent::save($data);
return $return;
}
Joomla 2.5 & 3 style:
$app = JFactory::getApplication();
$input = $app->input;
$file= $input->files->get('file');
if(isset($file['name']))
{
jimport('joomla.filesystem.file');
$file['name'] = strtolower(JFile::makeSafe($file['name']));
$fileRelativePath = '/pathToTheRightFolder/'.$file['name'];
$fileAbsolutePath = JPath::clean( JPATH_ROOT.$fileRelativePath);
JFile::upload( $file['tmp_name'], $fileAbsolutePath );
}
http://docs.joomla.org/How_to_use_the_filesystem_package
has a full upload sample.
Little sample where admin choose the file type or all, enter the users to access the form upload. Folder to upload files in Joomla directory or with absolute path. Only selected users access the form upload.
I am trying to upload a picture. I have Form_Zend and I use:
$image = new Zend_Form_Element_File('image');
$image->setLabel('Upload an avatar:')
->setMaxFileSize(8388608)
// ->setDestination('./usersImages')
->setDescription('Click Browse and choose an image');
$image->addValidator('Count', false, 1);
$image->addValidator('Size', false, 8388608);
$image->addValidator('Extension', false, 'jpg,jpeg,png,gif');
$this->addElement($image, 'image');
My controller action code:
if ($form->image->isUploaded()) {
$values = $form->getValues();
$source = $form->image->getFileName();
$extention = substr($source, strrpos($source, '.', -1));
$date = date('mdYhisa', time());
$new_image_name = 'avatar_' . $date . '_' . $idUser . $extention;
$destination = "C:\\xampp\\tmp\\Srututututut.png";
$image_saved = move_uploaded_file($source, $destination);
if ($image_saved) {
$data = array(
'img' => $new_image_name,
);
$userDT->update($data, 'id=' . $idUser);
}
}
}
But this move_uploaded_file is not returning nothing :/
What I have done:
Checked if the file is uploading - yes it is in: C:\xampp\htdocs\Story\public\usersImages (if I set destination in this form element) or
C:\xampp\tmp (if I dont set it)
I was wondering about access to this folders but if it save there this images I think it has rights but I set in the apache:
<Directory "C:/xampp/htdocs/Story/public/usersImages">
Allow from All
</Directory>
I was even tried use this function only in C:\xampp\tmp folder:
$source: C:\xampp\tmp\database.png
$destination: C:\xampp\tmp\Srututututut.png
And still nothing :/
Do You have any suggestions?
I think that the problem is with $source = $form->image->getFileName();. The reason is that it will return a name of the file uploaded rather than where it was uploaded to (i.e. its temporary localization).
Thus, I think your source should be as follows:
$fileInfo = $mainForm->image->getTransferAdapter()->getFileInfo();
$source = $fileInfo['image']['tmp_name'];
// to check if the source really points to the uploaded file.
var_dump(file_exists($source));
Ok,
I have no idea why this function is not working. I have changed my idea to set the $form->image destination first in the controller and then rename it and it is working.
Thanks for help guys ;D