$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 * * @param integer $errno * @param string $errstr * * @return boolean */ 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; } /** * Determine if the system supports editing of that image type * * @param string $reqtype * * @return string|false */ 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; } 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()) { send404AsImage(); return; } // media file somewhere else? if ($media->isExternal()) { header('Location: ' . $media->getFilename()); return; } $which = $thumb ? 'thumb' : 'main'; $serverFilename = $media->getServerFilename($which); if (!file_exists($serverFilename)) { send404AsImage(); return; } $mimetype = $media->mimeType(); $imgsize = $media->getImageAttributes($which); $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') || $WT_TREE->getPreference('WATERMARK_THUMB')) { // if the user’s priv’s justify it... if (WT_USER_ACCESS_LEVEL > $WT_TREE->getPreference('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 (isset($_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 (isset($_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) { http_response_code(304); return; } } // 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; $imSendFunc = 'image' . $type; if (function_exists($imCreateFunc) && function_exists($imSendFunc)) { $im = $imCreateFunc($serverFilename); $im = applyWatermark($im); // save the image, if preferences allow if ($which === 'thumb' && $WT_TREE->getPreference('SAVE_WATERMARK_THUMB') || $which === 'main' && $WT_TREE->getPreference('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); return; } 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); }