Search code examples
phpfilemagento

Check if file exists before displaying in Magento PHP?


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.


Solution

  • 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).