1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

getimagesize and XenForo_Image_Abstract::createFromFile failing

Discussion in 'XenForo Development Discussions' started by chrisj, Jul 24, 2012.

  1. chrisj

    chrisj Active Member

    I followed Jaxel's code from 2010: http://xenforo.com/community/threads/how-does-the-image-parser-work.7783/

    This is run as part of a cron and the page returns blank. I tried turning on php error reporting but it doesn't make a difference. I decided to log everything in a file and I was able to track the problem to getimagesize and XenForo_Image_Abstract::createFromFile. It seems it either one can fail.

    All the url's I pass are always valid image urls. They are also all png format.

    Here is the code I am using.

    PHP:
    protected function saveThumbnail($imageUrl$type$id$width){
            
    XenForo_Helper_File::log(
                
    'psnleaderboard-test',
                
    sprintf("saveThumbnail - %s\n%s\t%s\t%s\n",
                
    $imageUrl$type$id$width)
            );
         
            echo 
    "<br/>saveThumbnail($imageUrl$type$id$width)<br/>";
         
            
    // get extension of image
                
    $extension XenForo_Helper_File::getFileExtension($imageUrl);
             
                
    XenForo_Helper_File::log(
                    
    'psnleaderboard-test',
                    
    sprintf("got extension: %s\n"$extension)
                );
     
                
    // get width, height and type of image
                
    $imageInfo = @getimagesize($imageUrl); // This sometimes fails
                
    if (!$imageInfo)
                {
                    
    XenForo_Helper_File::log(
                        
    'psnleaderboard-test',
                        
    sprintf("image info failed\n")
                    );
                    echo 
    "image info failed<br/>";
                    return 
    false;
                }
             
                
    XenForo_Helper_File::log(
                    
    'psnleaderboard-test',
                    
    sprintf("imageInfo[2] - %s\n"$imageInfo[2])
                );
     
                
    // set target save location
                
    $filePath XenForo_Helper_File::getExternalDataPath().'/psnleaderboards/images/'.$type.'/s/'.$id.'.'.$extension;
             
                
    XenForo_Helper_File::log(
                    
    'psnleaderboard-test',
                    
    sprintf("filepath created\n")
                );
     
                
    // create image object from existing image
                
    if ($image XenForo_Image_Abstract::createFromFile($imageUrl$imageInfo[2])) // this also can fail
                
    {
                    
    XenForo_Helper_File::log(
                        
    'psnleaderboard-test',
                        
    sprintf("image created\n")
                    );
                 
                    
    // resize image object to 160 width
                    
    $image->thumbnail($width);
                    
    print_r($imageInfo);
     
                    
    // save thumbnail image to target location
                    
    $directory dirname($filePath);
                    if (
    XenForo_Helper_File::createDirectory($directorytrue) && is_writable($directory))
                    {
                        if (
    file_exists($filePath))
                        {
                            
    unlink($filePath);
                        }
                 
                        
    $image->output($imageInfo[2], $filePath);
                     
                        
    XenForo_Helper_File::log(
                            
    'psnleaderboard-test',
                            
    sprintf("succeeded saving Thumbnail\n")
                        );
                     
                        return 
    true;
                    }
                }
                
    XenForo_Helper_File::log(
                    
    'psnleaderboard-test',
                    
    sprintf("failed saving Thumbnail\n")
                );
            return 
    false;
        }
     
  2. Naatan

    Naatan Well-Known Member

    Just to get the obvious out of the way, does your webserver have read permission on the image file?
     
  3. chrisj

    chrisj Active Member

    Yes, this is running on MAMP and also it works the majority of the time.
     
  4. Naatan

    Naatan Well-Known Member

    Neither the fact that it runs on MAMP nor that it works "most of the time" answers the question of "whether your webserver has permission to read the image file" though.

    Run is_readable on your file and see what it says.
     
  5. chrisj

    chrisj Active Member

    By image file, do you mean image on the remote website? I tried is_readable on the url and that fails every time. If you are talking about the image file I am trying to create, I don't see how I can try and read what hasn't been created. I do check to see if I have write permission.
     
  6. Naatan

    Naatan Well-Known Member


    There's your problem, you're passing in a remote image (presumably a http address), although this can work with getimagesize, it does not work with XenForo's image library. Furthermore it is bad practice to do this even if it would work, as you have no control what so ever over it's method of retrieval and are limited in exception handling.

    The better way of doing this is to first download the image (with cUrl or otherwise) and then perform your image manipulations on your local file. Afterwards you just delete whatever files you don't need anymore. Save downloaded images to
    sys_get_temp_dir() to ensure files will always get cleaned up even if your script failed (unless you don't want them deleted of course).
     
    chrisj likes this.
  7. chrisj

    chrisj Active Member

    Thank you, it seems to be working perfectly now. For those curious, this is the working code:
    PHP:
    /*
    Creates a local image for a url and compresses it
     
    @param string imageUrl, string type, string id, string width
     
    @return true if image is successfully created
    */
    protected function saveThumbnail($imageUrl$type$id$width){
     
            
    // create file with random name in system temp dir
            
    $temp_file tempnam(sys_get_temp_dir(), 'Psi');
            
    $fp fopen($temp_file'w');
     
            
    // write image to file
            
    $ch curl_init($imageUrl);
            
    curl_setopt($chCURLOPT_FILE$fp);
            
    $data curl_exec($ch);
     
            
    curl_close($ch);
            
    fclose($fp);
     
     
            if (
    $temp_file && !is_readable($temp_file))
            {
                throw new 
    XenForo_Exception('The temporary file for the image can not be read.');
            }
     
     
                
    // get extension of image
                
    $extension XenForo_Helper_File::getFileExtension($imageUrl);
     
                
    // get width, height and type of image
                
    $imageInfo = @getimagesize($temp_file);
                if (!
    $imageInfo)
                {
                    return 
    false;
                }
     
                
    // set target save location
                
    $filePath XenForo_Helper_File::getExternalDataPath().'/psnleaderboards/images/'.$type.'/s/'.$id.'.'.$extension;
     
                
    // create image object from existing image
                
    if ($image XenForo_Image_Abstract::createFromFile($temp_file$imageInfo[2]))
                {
                    
    // delete temporary file
                    
    if (file_exists($temp_file))
                    {
                        
    unlink($temp_file);
                    }
           
                    
    // resize image object to 160 width
                    
    $image->thumbnail($width);
                    
    print_r($imageInfo);
     
                    
    // save thumbnail image to target location
                    
    $directory dirname($filePath);
                    if (
    XenForo_Helper_File::createDirectory($directorytrue) && is_writable($directory))
                    {
                        if (
    file_exists($filePath))
                        {
                            
    unlink($filePath);
                        }
           
                        
    $image->output($imageInfo[2], $filePath);
     
                        return 
    true;
                    }
                }
     
            return 
    false;
        }
     

Share This Page