-  -

limiting dmMedia upload size in Diem

In Diem, dmMedia is a nice tool that helps a lot to get a good media management in a web site. However, I've noted that users are not so comfortable with naming conventions or image size constraints.
I've decided to hack the dmMedia plugin to help users conform with pictures management.

As a developer, I know about naming conventions and pictures processing. Something that usual users are not supposed to master and always don't care about.

I want to be sure that :

  • a file name like "Photo de l'été.JPG" will not becomes a 404 error because of bad encoding or OS misunderstanding (case sensitivity for example).
  • a file with 2400x1800 will not be inserted in my design an break it.

That's why I will hack the dmMedia component : to enforce naming convention and image size.

Limiting width and height

We'll intercept dmMedia image files during the upload process and with help of sfImageTransformPlugin (integratted in Diem), we'll resize our image to to proper size.

Adding setup variables in administrator System > settings

  • dmMedia_limit_pictures_size type : boolean default : 1
  • dmMedia_limit_width_max type : numeric default : 800
  • dmMedia_limit_height_max type : numeric default : 600

I've added some extra settings for default media author and licence.

  • dmMedia_default_author type : string default : John Doe
  • dmMedia_default_license type : string default : CC or whatever

All those setup are put in the Media group, this will make a new 'Media' tab in Tools > config panel.

Where to plug ?

Ideally, in the upload form validator. For this, we overwrite the original file validator by creating lib/form/doctrine/dmCorePlugin/DmMediaForm.class.php witch contains :

 /**  
    * fill author and licence values if not already set  
    * using default values setup under dmMedia_default_author  
    * and dmMedia_default_license keys  
    * @param array $values  
    */  
    protected function doUpdateObject($values)  
    {  
        if($values['author'] == "")  
        {  
            $values['author'] = dmConfig::get('dmMedia_default_author');  
        }  
 
        if($values['license'] == "")  
        {  
            $values['license'] = dmConfig::get('dmMedia_default_license');  
        }  
 
        parent::doUpdateObject($values);  
    }  
 
   /**  
    * resize pictures media and enforce naming convention  
    * @param sfValidatedFile $file  
    * @param array $values  
    * @return array  
    */  
    protected function handleValidatedFile(sfValidatedFile $file, array $values)  
    {  
        if( dmConfig::get('dmMedia_limit_pictures_size') == true )  
        {  
            $fileTempName = $file->getTempName();  
            $fileType     = $file->getType();  
            $mimeCats = $this->validatorSchema['file']->getOption('mime_categories');  
 
            if( isset( $mimeCats['web_images'] ) )  
            {  
                if( in_array( $fileType, $mimeCats['web_images'] ) )  
                {  
                    // renaming temp uploaded file from filename.tmp to filename with correct extension  
                    // Note that we use slugifyFileName method to ensure that  
                    // file name naming convention are respected  
                    $newFullPath     = myTools::slugifyFileName( $fileTempName . $file->getOriginalExtension() );  
                    $newOriginalName = myTools::slugifyFileName( $file->getOriginalName() );  
 
                    if( rename( $fileTempName, $newFullPath ) == true )  
                    {  
                        // have to override temp file name that is protected  
                        // so we replace the sfValidatedFile object with a new one  
                        $file = new sfValidatedFile( $newOriginalName, $fileType, $newFullPath, $file->getSize() );  
                        // using sfImageTransformPlugin  
                        $img = new sfImage( $newFullPath, $fileType );  
                        // using setup vars  
                        $maxWidth  = dmConfig::get('dmMedia_limit_width_max');  
                        $maxHeight = dmConfig::get('dmMedia_limit_height_max');  
                        // resize if necessary  
                        if( $img->getWidth() > $maxWidth || $img->getHeight() > $maxHeight )  
                        {  
                            $img->thumbnail( $maxWidth, $maxHeight, 'scale' );  
                        }  
                        $img->saveAs( $newFullPath );  
                    }  
                    else  
                    {  
                        throw new Exception(sprintf('Unable to rename "%s" to "%s".', $fileTempName, $newFullPath));  
                    }  
                }  
            }  
        }  
 
        parent::handleValidatedFile( $file, $values );  
        return $values;  
    }  

Note that this method use a custom slugifyFileName function that can be found in lib/myTools.php

class myTools  
{  
    /**  
     * help enforce file naming convention [a-z0-9-] for file name and extension  
     * leave any path unchanged  
     * @param string $fileName can be a full path (folder/folder/filename.ext)  
     * @return string  
     */  
    public static function slugifyFileName($fileName)  
    {  
        $i = pathinfo( $fileName );  
        $path = $i['dirname'] != "." ? $i['dirname'] . '/' : '';  
        $extension = $i['extension'] ? '.' . self::slugify($i['extension']) : '';  
        $newFileName = $path . self::slugify($i['filename']) . $extension;  
        return $newFileName;  
    }  
 
    /**  
     * slugify a string to enforce [a-z0-9-]  
     * inspired by symfony jobeet tutorial  
     * @see http://www.symfony-project.org/jobeet/1_4/Doctrine/en/05  
     * @param string $originalString  
     * @return string  
     */  
    public static function slugify( $originalString )  
    {  
      // replace non letter or digits by -  
      $newString = preg_replace('~[^\\pL\d]+~u', '-', $originalString);  
      // trim  
      $newString = trim($newString, '-');  
      // transliterate  
      if (function_exists('iconv'))  
      {  
        $fileName = iconv('utf-8', 'us-ascii//TRANSLIT', $newString);  
      }  
      // lowercase  
      $newString = strtolower($newString);  
      // remove unwanted characters  
      $newString = preg_replace('~[^-\w]+~', '', $newString);  
      return $newString;  
    }  
}  

Finish with a

sudo symfony dm:setup  

Et voilà ! No more huge useless pictures on your site.
Next step can be to integrate this in Diem core ?

Leave a comment

Your email will never be published

Comments for this post

No comment yet.