$mxl) { $taille_c--; if ($taille_c == 2) break; } return ($taille_c); } // imagettftext is the function that is most likely to throw an error // use this custom error handler to catch and log it function imagettftextErrorHandler($errno, $errstr) { global $useTTF, $serverFilename; // log the error Log::addErrorLog("Media Firewall error: >" . $errno . '/' . $errstr . "< while processing file >" . $serverFilename . "<"); // change value of useTTF to false so the fallback watermarking can be used. $useTTF = false; return true; } // pass in an image type and this will determine if your system supports editing of that image type function isImageTypeSupported($reqtype) { $supportByGD = array('jpg'=>'jpeg', 'jpeg'=>'jpeg', 'gif'=>'gif', 'png'=>'png'); $reqtype = strtolower($reqtype); if (empty($supportByGD[$reqtype])) return false; $type = $supportByGD[$reqtype]; if (function_exists('imagecreatefrom'.$type) && function_exists('image'.$type)) return $type; // Here we could check for image types that are supported by other than the GD library return false; } //////////////////////////////////////////////////////////////////////////////// // this needs to be a global variable so imagettftextErrorHandler can set it $useTTF = function_exists('imagettftext'); // Media object missing/private? if (!$media || !$media->canShow()) { send404AndExit(); } // media file somewhere else? if ($media->isExternal()) { header('Location: ' . $media->getFilename()); exit; } $which = $thumb ? 'thumb' : 'main'; $serverFilename = $media->getServerFilename($which); if (!file_exists($serverFilename)) { send404AndExit(); } $mimetype = $media->mimeType(); $imgsize = $media->getImageAttributes($which); $protocol = $_SERVER["SERVER_PROTOCOL"]; // determine if we are using HTTP/1.0 or HTTP/1.1 $filetime = $media->getFiletime($which); $filetimeHeader = gmdate("D, d M Y H:i:s", $filetime).' GMT'; $expireOffset = 3600 * 24; // tell browser to cache this image for 24 hours if (WT_Filter::get('cb')) $expireOffset = $expireOffset * 7; // if cb parameter was sent, cache for 7 days $expireHeader = gmdate("D, d M Y H:i:s", WT_TIMESTAMP + $expireOffset) . " GMT"; $type = isImageTypeSupported($imgsize['ext']); $usewatermark = false; // if this image supports watermarks and the watermark module is intalled... if ($type) { // if this is not a thumbnail, or WATERMARK_THUMB is true if (($which=='main') || $WATERMARK_THUMB ) { // if the user’s priv’s justify it... if (WT_USER_ACCESS_LEVEL > $SHOW_NO_WATERMARK ) { // add a watermark $usewatermark = true; } } } // determine whether we have enough memory to watermark this image if ($usewatermark) { if (!hasMemoryForImage($serverFilename)) { // not enough memory to watermark this file $usewatermark = false; } } $watermarkfile = ""; $generatewatermark = false; if ($usewatermark) { if ($which=='thumb') { $watermarkfile = WT_DATA_DIR . $MEDIA_DIRECTORY . 'watermark/' . WT_GEDCOM . '/thumb/' . $media->getFilename(); } else { $watermarkfile = WT_DATA_DIR . $MEDIA_DIRECTORY . 'watermark/' . WT_GEDCOM . '/' . $media->getFilename(); } if (!file_exists($watermarkfile)) { // no saved watermark file exists // generate the watermark file $generatewatermark = true; } else { $watermarktime = filemtime($watermarkfile); if ($filetime > $watermarktime) { // if the original image was updated after the saved file was created // generate the watermark file $generatewatermark = true; } } } $etag = $media->getEtag($which); // parse IF_MODIFIED_SINCE header from client $if_modified_since = 'x'; if (@$_SERVER["HTTP_IF_MODIFIED_SINCE"]) { $if_modified_since = preg_replace('/;.*$/', '', $_SERVER["HTTP_IF_MODIFIED_SINCE"]); } // parse IF_NONE_MATCH header from client $if_none_match = 'x'; if (@$_SERVER["HTTP_IF_NONE_MATCH"]) { $if_none_match = str_replace("\"", "", $_SERVER["HTTP_IF_NONE_MATCH"]); } // add caching headers. allow browser to cache file, but not proxy header("Last-Modified: " . $filetimeHeader); header('ETag: "'.$etag.'"'); header("Expires: ".$expireHeader); header("Cache-Control: max-age=".$expireOffset.", s-maxage=0, proxy-revalidate"); // if this file is already in the user’s cache, don’t resend it // first check if the if_modified_since param matches if (($if_modified_since == $filetimeHeader)) { // then check if the etag matches if ($if_none_match == $etag) { header($protocol." 304 Not Modified"); exit; } } // send headers for the image header('Content-Type: ' . $mimetype); header('Content-Disposition: filename="' . addslashes(basename($media->file)) . '"'); if ($generatewatermark) { // generate the watermarked image $imCreateFunc = 'imagecreatefrom'.$type; $im = @$imCreateFunc($serverFilename); if ($im) { $im = applyWatermark($im); $imSendFunc = 'image'.$type; // save the image, if preferences allow if ((($which=='thumb') && $SAVE_WATERMARK_THUMB) || (($which=='main') && $SAVE_WATERMARK_IMAGE)) { // make sure the folder exists WT_File::mkdir(dirname($watermarkfile)); // save the image $imSendFunc($im, $watermarkfile); } // send the image $imSendFunc($im); imagedestroy($im); exit; } else { // this image is defective. log it Log::addMediaLog("Media Firewall error: >" . WT_I18N::translate('This media file is broken and cannot be watermarked') . "< in file >" . $serverFilename . "< memory used: " . memory_get_usage()); // set usewatermark to false so image will simply be passed through below $usewatermark = false; } } // pass the image through without manipulating it if ($usewatermark) { // the stored watermarked image is good, lets use it $serverFilename = $watermarkfile; } // determine filesize of image (could be original or watermarked version) $filesize = filesize($serverFilename); // set content-length header, send file header("Content-Length: " . $filesize); // Some servers disable fpassthru() and readfile() if (function_exists('readfile')) { readfile($serverFilename); } else { $fp=fopen($serverFilename, 'rb'); if (function_exists('fpassthru')) { fpassthru($fp); } else { while (!feof($fp)) { echo fread($fp, 65536); } } fclose($fp); }