HomeHelpTrac

Changeset 15512


Ignore:
Timestamp:
09/19/11 03:09:43 (8 months ago)
Author:
Alexander Trofimov
Message:

Images Transcoder

Location:
trunk
Files:
2 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/inc/classes/BxDolCronCmd.php

    r15452 r15512  
    121121        bx_import('BxDolStorage'); 
    122122        $iDeletedExpiredTokens = BxDolStorage::pruning(); 
     123 
     124        // clean outdated transcoded images 
     125        bx_import('BxDolImageTranscoder'); 
     126        $iDeletedTranscodedImages = BxDolImageTranscoder::pruning(); 
    123127 
    124128        echo "\n- Database cleaning -\n"; 
     
    132136        echo "Deleted comment votes: $iDeletedCommentVotes\n"; 
    133137        echo "Storage expired tokens: $iDeletedExpiredTokens\n"; 
     138        echo "Deleted outdated transcoded images: $iDeletedTranscodedImages\n"; 
    134139    } 
    135140 
  • trunk/inc/classes/BxDolImageResize.php

    r15211 r15512  
    88 
    99// Function error codes 
    10 define( 'IMAGE_ERROR_SUCCESS',                    0 ); 
    11 define( 'IMAGE_ERROR_SOURCE_NOT_EXISTS',        1 ); 
    12 define( 'IMAGE_ERROR_WRONG_TYPE',                2 ); 
    13 define( 'IMAGE_ERROR_FILE_OPEN_FAILED',            3 ); 
    14 define( 'IMAGE_ERROR_IMAGEMAGICK_ERROR',        4 ); 
    15 define( 'IMAGE_ERROR_GD_NOT_INSTALLED',            5 ); 
    16 define( 'IMAGE_ERROR_GD_TYPE_NOT_SUPPORTED',    6 ); 
    17 define( 'IMAGE_ERROR_GD_OPEN_FAILED',            7 ); 
    18 define( 'IMAGE_ERROR_GD_RESIZE_ERROR',            8 ); 
    19 define( 'IMAGE_ERROR_GD_MERGE_ERROR',            9 ); 
    20 define( 'IMAGE_ERROR_GD_WRITE_FAILED',            10 ); 
    21 define( 'IMAGE_ERROR_GD_TTF_NOT_SUPPORTED',        11 ); 
     10define( 'IMAGE_ERROR_SUCCESS',               0 ); 
     11define( 'IMAGE_ERROR_SOURCE_NOT_EXISTS',     1 ); 
     12define( 'IMAGE_ERROR_WRONG_TYPE',            2 ); 
     13define( 'IMAGE_ERROR_FILE_OPEN_FAILED',      3 ); 
     14define( 'IMAGE_ERROR_IMAGEMAGICK_ERROR',     4 ); 
     15define( 'IMAGE_ERROR_GD_NOT_INSTALLED',      5 ); 
     16define( 'IMAGE_ERROR_GD_TYPE_NOT_SUPPORTED', 6 ); 
     17define( 'IMAGE_ERROR_GD_OPEN_FAILED',        7 ); 
     18define( 'IMAGE_ERROR_GD_RESIZE_ERROR',       8 ); 
     19define( 'IMAGE_ERROR_GD_MERGE_ERROR',        9 ); 
     20define( 'IMAGE_ERROR_GD_WRITE_FAILED',       10 ); 
     21define( 'IMAGE_ERROR_GD_TTF_NOT_SUPPORTED',  11 ); 
     22define( 'IMAGE_ERROR_GD_FILTER_ERROR',       12 ); 
    2223 
    2324 
     
    103104    } 
    104105 
     106    function grayscale ($mixedImage, $sDstImage = '') { 
     107        if (is_array($mixedImage)) { 
     108            $aRet = array(); 
     109            foreach ($mixedImage as $s) { 
     110                $aRet[] = $this->_grayscale ($s, $s); 
     111            } 
     112            return $aRet; 
     113        } else { 
     114            return $this->_grayscale ($mixedImage, $sDstImage); 
     115        } 
     116    } 
     117 
    105118    function setSize ($w, $h) { 
    106119        $this->w = $w; 
     
    142155 
    143156    // private functions are below ------------------------------- 
     157 
     158    function _grayscale ($sSrcImage, $sDstImage = '') { 
     159        if (!file_exists($sSrcImage)) 
     160            return IMAGE_ERROR_SOURCE_NOT_EXISTS; 
     161 
     162        if (!$sDstImage) 
     163            $sDstImage = $sSrcImage; 
     164 
     165        if ($sDstImage == $sSrcImage) { 
     166            chmod($sDstImage, 0666); 
     167        } 
     168 
     169        return $this->_isUseGD ? $this->_grayscaleGD ($sSrcImage, $sDstImage) : $this->_grayscaleImageMagick ($sSrcImage, $sDstImage); 
     170    } 
     171 
     172    function _grayscaleGD ($sSrcImage, $sDstImage) { 
     173 
     174        $iErr = 0; 
     175        $src_im =& $this->_createGDImage($sSrcImage, $size, $iErr); 
     176        $sizeOrig = $size; 
     177 
     178        if ($iErr) 
     179            return $iErr; 
     180        if (!$src_im) 
     181            return IMAGE_ERROR_GD_OPEN_FAILED; 
     182 
     183        if (!imagefilter($src_im, IMG_FILTER_GRAYSCALE))  
     184            return IMAGE_ERROR_GD_FILTER_ERROR; 
     185 
     186        // if output always in JPG 
     187        if ( $this->_isForceJPGOutput ) 
     188        { 
     189            $writeResult = imagejpeg( $src_im, $sDstImage, $this->_iJpegQuality); 
     190        } 
     191        else // otherwise 
     192        { 
     193            switch ( $size[2] ) 
     194            { 
     195                case IMAGE_TYPE_GIF: 
     196                    $writeResult = imagegif( $src_im, $sDstImage ); 
     197                    break; 
     198                case IMAGE_TYPE_JPG: 
     199                    $writeResult = imagejpeg( $src_im, $sDstImage, $this->_iJpegQuality); 
     200                    break; 
     201                case IMAGE_TYPE_PNG: 
     202                    $writeResult = imagepng( $src_im, $sDstImage ); 
     203                    break; 
     204            } 
     205        } 
     206 
     207        // free memory 
     208        imagedestroy( $src_im ); 
     209 
     210        if ( $writeResult && file_exists($sDstImage) ) 
     211            return IMAGE_ERROR_SUCCESS; 
     212 
     213        return IMAGE_ERROR_GD_WRITE_FAILED; 
     214    } 
     215 
     216    function _grayscaleImageMagick ($sSrcImage, $sDstImage) { 
     217 
     218        $cmd = "{$GLOBALS['CONVERT']} \"$sSrcImage\" -type Grayscale -quantize Gray \"$sDstImage\""; 
     219        @exec( $cmd ); 
     220 
     221        if ( file_exists($sDstImage) ) 
     222            return IMAGE_ERROR_SUCCESS; 
     223 
     224        return IMAGE_ERROR_IMAGEMAGICK_ERROR; 
     225    } 
    144226 
    145227    function _resize ($sSrcImage, $sDstImage = '') { 
     
    266348 
    267349        // if output always in JPG 
    268         if ( $forceJPGOutput ) 
     350        if ( $this->_isForceJPGOutput ) 
    269351        { 
    270352            $writeResult = imagejpeg( $dst_im, $sDstImage, $this->_iJpegQuality); 
     
    445527        { 
    446528            case IMAGE_TYPE_GIF: 
    447                 if ( !$this->gdInfoArray['GIF Read Support'] || !$this->gdInfoArray['GIF Create Support'] ) 
     529                if (!isset($this->gdInfoArray['GIF Read Support']) || !$this->gdInfoArray['GIF Read Support'] || !isset($this->gdInfoArray['GIF Create Support']) || !$this->gdInfoArray['GIF Create Support']) 
    448530                    return ($iErr = IMAGE_ERROR_GD_TYPE_NOT_SUPPORTED); 
    449                 return imagecreatefromgif( $s ); 
     531                $r = imagecreatefromgif( $s ); 
     532                return $r; 
    450533            case IMAGE_TYPE_JPG: 
    451                 if ( !$this->gdInfoArray['JPG Support'] && !$this->gdInfoArray['JPEG Support'] ) 
     534                if ((!isset($this->gdInfoArray['JPG Support']) || !$this->gdInfoArray['JPG Support']) && (!isset($this->gdInfoArray['JPEG Support']) || !$this->gdInfoArray['JPEG Support'])) 
    452535                    return ($iErr = IMAGE_ERROR_GD_TYPE_NOT_SUPPORTED); 
    453                 return imagecreatefromjpeg( $s ); 
     536                $r = imagecreatefromjpeg( $s ); 
     537                return $r; 
    454538            case IMAGE_TYPE_PNG: 
    455                 if ( !$this->gdInfoArray['PNG Support'] ) 
     539                if (!isset($this->gdInfoArray['PNG Support']) || !$this->gdInfoArray['PNG Support']) 
    456540                    return ($iErr = IMAGE_ERROR_GD_TYPE_NOT_SUPPORTED); 
    457                 return imagecreatefrompng( $s ); 
     541                $r = imagecreatefrompng( $s ); 
     542                return $r; 
    458543            default: 
    459544                return ($iErr = IMAGE_ERROR_WRONG_TYPE); 
  • trunk/inc/classes/BxDolStorage.php

    r15500 r15512  
    205205        // create tmp file         
    206206         
    207         $sTmpFile = $temp_file = tempnam(sys_get_temp_dir(), 'bxdol');; 
     207        $sTmpFile = tempnam(realpath(sys_get_temp_dir()), 'bxdol'); 
    208208        if (!$oHelper->save($sTmpFile)) { 
    209209            $this->setErrorCode(BX_DOL_STORAGE_INVALID_FILE); 
     
    220220            unlink($sTmpFile); 
    221221            $this->setErrorCode(BX_DOL_STORAGE_ERR_ENGINE_ADD); 
     222            return false; 
    222223        } 
    223224        unlink($sTmpFile); 
     
    288289 
    289290    /** 
     291     * the same as storeFile, but it tries to do it directly from local file 
     292     */ 
     293    public function storeFileFromPath($sPath, $isPrivate = true, $iProfileId = 0) { 
     294        return $this->storeFile('Path', array('path' => $sPath), false, $isPrivate, $iProfileId); 
     295    } 
     296 
     297    /** 
    290298     * Delete file by file id. 
    291299     */ 
     
    574582        } 
    575583 
    576         $this->_oDb->deleteGhosts ($aFileInfo['id'], $aFileInfo['profile_id']); 
    577  
    578584        $this->setErrorCode(BX_DOL_STORAGE_ERR_OK); 
    579585        $bRet = true; 
     
    669675        fclose($input); 
    670676         
    671         if (false === $this->getSize() || $realSize != $this->getSize()) { 
    672             return false; 
    673         } 
     677        if (false === $this->getSize() || $realSize != $this->getSize()) 
     678            return false; 
    674679         
    675680        $target = fopen($path, "w");         
     
    677682        stream_copy_to_stream($temp, $target); 
    678683        fclose($target); 
    679          
     684        fclose($temp); 
     685 
    680686        return true; 
    681687    } 
     
    731737} 
    732738 
     739/** 
     740 * Store file from local file 
     741 */ 
     742class BxDolStorageHelperPath {  
     743 
     744    var $sPath; 
     745 
     746    function BxDolStorageHelperPath ($aParams) { 
     747        $this->sPath = $aParams['path']; 
     748    } 
     749 
     750    function getImmediateError() { 
     751 
     752        if (!file_exists($this->sPath)) 
     753            return BX_DOL_STORAGE_ERR_NO_FILE; 
     754 
     755        return BX_DOL_STORAGE_ERR_OK; 
     756    } 
     757 
     758    function save($path) { 
     759        if (!copy($this->sPath, $path)) { 
     760            return false; 
     761        } 
     762        return true; 
     763    } 
     764 
     765    function getName() { 
     766        return pathinfo($this->sPath, PATHINFO_BASENAME); 
     767    } 
     768 
     769    function getSize() { 
     770        return filesize($this->sPath); 
     771    } 
     772} 
  • trunk/inc/classes/BxDolStorageQuery.php

    r15500 r15512  
    105105     
    106106    public function modifyFilePrivate($iFileId, $isPrivate) { 
    107         $iTime = time(); 
    108         $sQuery = $this->prepare("UPDATE " . $this->_sTableFiles . " SET `modified` = ?, `private` = ? WHERE `id` = ?", $iTime, $isPrivate ? 1 : 0, $iFileId); 
     107        return $this->modifyCustomField($iFileId, 'private', $isPrivate ? 1 : 0); 
     108    } 
     109 
     110    public function modifyCustomField($iFileId, $sField, $sValue, $isUpdateModifiedField = true) {         
     111        $sAdd = ''; 
     112        if ($isUpdateModifiedField) { 
     113            $iTime = time(); 
     114            $sAdd = $this->prepare(", `modified` = ?", $iTime); 
     115        } 
     116        $sQuery = $this->prepare("UPDATE " . $this->_sTableFiles . " SET `{$sField}` = ? {$sAdd} WHERE `id` = ?", $sValue, $iFileId); 
    109117        return $this->query($sQuery); 
    110118    } 
    111119 
    112120    public function deleteFile($iFileId) { 
     121 
    113122        $sQuery = $this->prepare("DELETE FROM " . $this->_sTableFiles . " WHERE `id` = ?", $iFileId); 
    114         if ($this->query($sQuery)) 
    115             return true; 
    116         else 
    117             return false; 
     123        if (!$this->query($sQuery)) 
     124            return false; 
     125 
     126        $sQuery = $this->prepare("DELETE FROM `sys_storage_ghosts` WHERE `object` = ? AND `id` = ?", $this->_aObject['object'], $iFileId); 
     127        $this->query($sQuery); 
     128 
     129        return true; 
     130    } 
     131 
     132    public function getFileByFileName($sValue) { 
     133        return $this->_getFileBy('`file_name`', $sValue); 
    118134    } 
    119135 
     
    155171        $iCount = 0; 
    156172        foreach ($mixedFileIds as $iFileId) { 
    157             $sQuery = $this->prepare("INSERT INTO `sys_storage_ghosts` SET `id` = ?, `profile_id` = ?, `object` = ?, `created` = ?", $iFileId, $iProfileId, $this->_aObject['object'], $iTime); 
     173            $sQuery = $this->prepare("INSERT INTO `sys_storage_ghosts`  
     174                SET `id` = ?, `object` = ?, `profile_id` = ?, `created` = ?  
     175                ON DUPLICATE KEY UPDATE `profile_id` = ?, `created` = ?", $iFileId, $this->_aObject['object'], $iProfileId, $iTime, $iProfileId, $iTime); 
    158176            $iCount += $this->query($sQuery); 
    159177        } 
  • trunk/inc/classes/BxDolStorageS3.php

    r15491 r15512  
    157157        $sStorageClass = $this->_bReducedRedundancy ? S3::STORAGE_CLASS_RRS : S3::STORAGE_CLASS_STANDARD; 
    158158        $sACL = $isPrivate ? S3::ACL_AUTHENTICATED_READ : S3::ACL_PUBLIC_READ; 
    159         $aInputFile = $this->_s3->inputFile($sTmpFile);                         
     159        $aInputFile = $this->_s3->inputFile($sTmpFile); 
    160160        if (!$this->_s3->putObject($aInputFile, $this->_sBucket, $this->getObjectBaseDir($isPrivate) . $sRemoteNamePath, $sACL, $aMetaHeaders, $aRequestHeaders, $sStorageClass)) { 
    161161            $this->setErrorCode(BX_DOL_STORAGE_ERR_ENGINE_ADD); 
  • trunk/install/sql/v70.sql

    r15502 r15512  
    66 
    77SET NAMES 'utf8'; 
    8 DROP TABLE IF EXISTS `sys_account_custom_stat_elements`, `sys_admin_ban_list`, `sys_admin_dashboard`, `sys_menu_admin`, `sys_menu_admin_top`, `sys_menu_bottom`, `sys_albums`, `sys_albums_objects`,`sys_banners`, `sys_banners_clicks`, `sys_banners_shows`, `sys_block_list`, `sys_categories`, `sys_objects_categories`, `sys_objects_cmts`, `sys_cmts_profile`, `sys_cmts_track`, `sys_color_base`, `sys_countries`, `sys_email_templates`, `sys_menu_member`, `sys_friend_list`, `sys_options`, `sys_options_cats`, `sys_fave_list`, `sys_ip_list`, `sys_ip_members_visits`, `sys_localization_categories`, `sys_localization_keys`, `sys_localization_languages`, `sys_localization_string_params`, `sys_localization_strings`, `sys_acl_actions`, `sys_acl_actions_track`, `sys_acl_matrix`, `sys_acl_level_prices`, `sys_acl_levels`, `sys_messages`, `sys_page_compose`, `sys_page_compose_pages`, `sys_page_compose_privacy`, `sys_sessions`, `sys_stat_member`, `sys_pre_values`, `sys_profile_fields`, `sys_acl_levels_members`, `Profiles`, `sys_profile_views_track`, `sys_profiles_match`, `sys_profile_rating`, `sys_profile_voting_track`, `RayBoardCurrentUsers`, `RayBoardBoards`, `RayBoardUsers`, `RayChatCurrentUsers`, `RayChatMessages`, `RayChatProfiles`, `RayChatRooms`, `RayChatRoomsUsers`, `RayChatMembershipsSettings`, `RayChatMemberships`, `RayImContacts`, `RayImMessages`, `RayImPendings`, `RayImProfiles`, `RayMp3Files`, `RayMp3Tokens`, `RayShoutboxMessages`, `RayVideoFiles`, `RayVideoTokens`, `RayVideo_commentsFiles`, `RayVideo_commentsTokens`, `sys_objects_search`, `sys_shared_sites`, `sys_stat_site`, `sys_alerts`, `sys_alerts_handlers`, `sys_injections`, `sys_injections_admin`, `sys_modules`, `sys_modules_file_tracks`, `sys_permalinks`, `sys_privacy_actions`, `sys_privacy_defaults`, `sys_privacy_groups`, `sys_privacy_members`, `sys_tags`, `sys_objects_tag`, `sys_menu_top`, `sys_transactions`, `sys_objects_actions`, `sys_objects_auths`, `sys_greetings`, `sys_objects_vote`, `sys_objects_views`, `sys_box_download`, `sys_cron_jobs`, `sys_sbs_users`, `sys_sbs_entries`, `sys_sbs_types`, `sys_sbs_queue`, `sys_sbs_messages`, `sys_profiles_match_mails`, `sys_dnsbl_rules`, `sys_dnsbl_block_log`, `sys_dnsbluri_zones`, `sys_menu_mobile`, `sys_menu_mobile_pages`; 
     8DROP TABLE IF EXISTS `sys_account_custom_stat_elements`, `sys_admin_ban_list`, `sys_admin_dashboard`, `sys_menu_admin`, `sys_menu_admin_top`, `sys_menu_bottom`, `sys_albums`, `sys_albums_objects`,`sys_banners`, `sys_banners_clicks`, `sys_banners_shows`, `sys_block_list`, `sys_categories`, `sys_objects_categories`, `sys_objects_cmts`, `sys_cmts_profile`, `sys_cmts_track`, `sys_color_base`, `sys_countries`, `sys_email_templates`, `sys_menu_member`, `sys_friend_list`, `sys_options`, `sys_options_cats`, `sys_fave_list`, `sys_ip_list`, `sys_ip_members_visits`, `sys_localization_categories`, `sys_localization_keys`, `sys_localization_languages`, `sys_localization_string_params`, `sys_localization_strings`, `sys_acl_actions`, `sys_acl_actions_track`, `sys_acl_matrix`, `sys_acl_level_prices`, `sys_acl_levels`, `sys_messages`, `sys_page_compose`, `sys_page_compose_pages`, `sys_page_compose_privacy`, `sys_sessions`, `sys_stat_member`, `sys_pre_values`, `sys_profile_fields`, `sys_acl_levels_members`, `Profiles`, `sys_profile_views_track`, `sys_profiles_match`, `sys_profile_rating`, `sys_profile_voting_track`, `RayBoardCurrentUsers`, `RayBoardBoards`, `RayBoardUsers`, `RayChatCurrentUsers`, `RayChatMessages`, `RayChatProfiles`, `RayChatRooms`, `RayChatRoomsUsers`, `RayChatMembershipsSettings`, `RayChatMemberships`, `RayImContacts`, `RayImMessages`, `RayImPendings`, `RayImProfiles`, `RayMp3Files`, `RayMp3Tokens`, `RayShoutboxMessages`, `RayVideoFiles`, `RayVideoTokens`, `RayVideo_commentsFiles`, `RayVideo_commentsTokens`, `sys_objects_search`, `sys_shared_sites`, `sys_stat_site`, `sys_alerts`, `sys_alerts_handlers`, `sys_injections`, `sys_injections_admin`, `sys_modules`, `sys_modules_file_tracks`, `sys_permalinks`, `sys_privacy_actions`, `sys_privacy_defaults`, `sys_privacy_groups`, `sys_privacy_members`, `sys_tags`, `sys_objects_tag`, `sys_menu_top`, `sys_transactions`, `sys_objects_actions`, `sys_objects_auths`, `sys_greetings`, `sys_objects_vote`, `sys_objects_views`, `sys_box_download`, `sys_cron_jobs`, `sys_sbs_users`, `sys_sbs_entries`, `sys_sbs_types`, `sys_sbs_queue`, `sys_sbs_messages`, `sys_profiles_match_mails`, `sys_dnsbl_rules`, `sys_dnsbl_block_log`, `sys_dnsbluri_zones`, `sys_menu_mobile`, `sys_menu_mobile_pages`, `sys_objects_storage`, `sys_storage_user_quotas`, `sys_storage_tokens`, `sys_storage_ghosts`, `sys_storage_mime_types`, `sys_objects_transcoder_images`, `sys_transcoder_images_files`, `sys_transcoder_images_filters`; 
    99ALTER DATABASE DEFAULT CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci'; 
    1010 
     
    36713671  `max_file_size` int(11) NOT NULL, 
    36723672  `ts` int(11) NOT NULL, 
    3673   PRIMARY KEY (`id`) 
     3673  PRIMARY KEY (`id`), 
     3674  UNIQUE KEY `object` (`object`) 
    36743675) ENGINE=MyISAM DEFAULT CHARSET=utf8; 
    36753676 
     
    46064607('ice', 'x-conference/x-cooltalk', ''); 
    46074608 
     4609 
     4610-- -------------------------------------------------------- 
     4611 
     4612CREATE TABLE IF NOT EXISTS `sys_objects_transcoder_images` ( 
     4613  `id` int(11) NOT NULL AUTO_INCREMENT, 
     4614  `object` varchar(32) NOT NULL, 
     4615  `storage_object` varchar(32) NOT NULL, 
     4616  `source_type` enum('Folder','Storage') NOT NULL, 
     4617  `source_params` text NOT NULL, 
     4618  `private` enum('auto','yes','no') NOT NULL, 
     4619  `atime_tracking` int(11) NOT NULL, 
     4620  `atime_pruning` int(11) NOT NULL, 
     4621  `ts` int(11) NOT NULL DEFAULT '0', 
     4622  PRIMARY KEY (`id`), 
     4623  UNIQUE KEY `object` (`object`) 
     4624) ENGINE=MyISAM  DEFAULT CHARSET=utf8; 
     4625 
     4626CREATE TABLE IF NOT EXISTS `sys_transcoder_images_files` ( 
     4627  `transcoder_object` varchar(32) NOT NULL, 
     4628  `file_id` int(11) NOT NULL, 
     4629  `handler` varchar(255) NOT NULL, 
     4630  `atime` int(11) NOT NULL, 
     4631  UNIQUE KEY `transcoder_object` (`transcoder_object`,`handler`), 
     4632  KEY `atime` (`atime`), 
     4633  KEY `file_id` (`file_id`) 
     4634) ENGINE=MyISAM DEFAULT CHARSET=utf8; 
     4635 
     4636CREATE TABLE IF NOT EXISTS `sys_transcoder_images_filters` ( 
     4637  `transcoder_object` varchar(32) NOT NULL, 
     4638  `filter` varchar(32) NOT NULL, 
     4639  `filter_params` text NOT NULL, 
     4640  `order` int(11) NOT NULL DEFAULT '0' 
     4641) ENGINE=MyISAM DEFAULT CHARSET=utf8; 
     4642 
    46084643-- -------------------------------------------------------- 
    46094644 
  • trunk/plugins/S3.php

    r15446 r15512  
    429429            return false; 
    430430        } 
     431        clearstatcache(true, $file); 
    431432        return array('file' => $file, 'size' => filesize($file), 'md5sum' => $md5sum !== false ? 
    432433        (is_string($md5sum) ? $md5sum : base64_encode(md5_file($file, true))) : ''); 
Note: See TracChangeset for help on using the changeset viewer.