tinyib/inc/functions.php

1039 lines
31 KiB
PHP
Raw Normal View History

2009-09-20 02:53:15 +00:00
<?php
2014-06-24 19:51:22 +00:00
if (!defined('TINYIB_BOARD')) {
die('');
}
2009-09-20 02:53:15 +00:00
$multibyte_enabled = function_exists('mb_strlen');
if (!function_exists('array_column')) {
function array_column($array, $column_name) {
return array_map(function ($element) use ($column_name) {
return $element[$column_name];
}, $array);
}
}
// lockDatabase obtains an exclusive lock to prevent race conditions when
// accessing the database.
function lockDatabase() {
if (TINYIB_LOCKFILE == '') {
return true;
}
$fp = fopen(TINYIB_LOCKFILE, 'c+');
if (!flock($fp, LOCK_EX)) {
fancyDie('Failed to lock control file.');
}
return $fp;
}
function _strlen($string) {
global $multibyte_enabled;
if ($multibyte_enabled) {
return mb_strlen($string);
}
return strlen($string);
}
function _strpos($haystack, $needle, $offset=0) {
global $multibyte_enabled;
if ($multibyte_enabled) {
return mb_strpos($haystack, $needle, $offset);
}
return strpos($haystack, $needle, $offset);
}
function _substr($string, $start, $length=null) {
global $multibyte_enabled;
if ($multibyte_enabled) {
return mb_substr($string, $start, $length);
}
return substr($string, $start, $length);
}
function _substr_count($haystack, $needle) {
global $multibyte_enabled;
if ($multibyte_enabled) {
return mb_substr_count($haystack, $needle);
}
return substr_count($haystack, $needle);
}
function hashData($data, $force = false) {
2020-11-13 20:32:42 +00:00
global $bcrypt_salt;
if (substr($data, 0, 4) == '$2y$' && !$force) {
2020-11-13 20:32:42 +00:00
return $data;
}
return crypt($data, $bcrypt_salt);
}
2009-09-20 02:53:15 +00:00
function cleanString($string) {
2018-07-24 23:46:58 +00:00
$search = array("&", "<", ">");
$replace = array("&amp;", "&lt;", "&gt;");
2014-06-24 19:51:22 +00:00
2009-09-20 02:53:15 +00:00
return str_replace($search, $replace, $string);
}
function cleanQuotes($string) {
$search = array("'", "\"");
$replace = array("&apos;", "&quot;");
return str_replace($search, $replace, $string);
}
function plural($count, $singular, $plural) {
if ($plural == 's') {
2014-06-24 19:51:22 +00:00
$plural = $singular . $plural;
}
return ($count == 1 ? $singular : $plural);
}
2009-09-20 02:53:15 +00:00
function threadUpdated($id) {
rebuildThread($id);
rebuildIndexes();
}
function newPost($parent = TINYIB_NEWTHREAD) {
2021-05-04 06:15:52 +00:00
return array(
'parent' => $parent,
2014-06-24 19:51:22 +00:00
'timestamp' => '0',
'bumped' => '0',
'ip' => '',
'name' => '',
'tripcode' => '',
'email' => '',
'nameblock' => '',
'subject' => '',
'message' => '',
'password' => '',
'file' => '',
'file_hex' => '',
'file_original' => '',
'file_size' => '0',
'file_size_formatted' => '',
'image_width' => '0',
'image_height' => '0',
'thumb' => '',
'thumb_width' => '0',
'thumb_height' => '0',
'stickied' => '0',
'locked' => '0',
2021-05-04 06:15:52 +00:00
'moderated' => '1'
);
2009-09-20 02:53:15 +00:00
}
function convertBytes($number) {
$len = strlen($number);
if ($len < 4) {
return sprintf("%dB", $number);
} elseif ($len <= 6) {
2014-06-24 19:51:22 +00:00
return sprintf("%0.2fKB", $number / 1024);
2009-09-20 02:53:15 +00:00
} elseif ($len <= 9) {
2014-06-24 19:51:22 +00:00
return sprintf("%0.2fMB", $number / 1024 / 1024);
2009-09-20 02:53:15 +00:00
}
2014-06-24 19:51:22 +00:00
return sprintf("%0.2fGB", $number / 1024 / 1024 / 1024);
2009-09-20 02:53:15 +00:00
}
function nameAndTripcode($name) {
if (preg_match("/(#|!)(.*)/", $name, $regs)) {
2009-09-20 02:53:15 +00:00
$cap = $regs[2];
$cap_full = '#' . $regs[2];
2014-06-24 19:51:22 +00:00
2009-09-20 02:53:15 +00:00
if (function_exists('mb_convert_encoding')) {
$recoded_cap = mb_convert_encoding($cap, 'SJIS', 'UTF-8');
if ($recoded_cap != '') {
$cap = $recoded_cap;
}
}
2014-06-24 19:51:22 +00:00
2009-09-20 02:53:15 +00:00
if (strpos($name, '#') === false) {
$cap_delimiter = '!';
} elseif (strpos($name, '!') === false) {
$cap_delimiter = '#';
} else {
$cap_delimiter = (strpos($name, '#') < strpos($name, '!')) ? '#' : '!';
}
2014-06-24 19:51:22 +00:00
if (preg_match("/(.*)(" . $cap_delimiter . ")(.*)/", $cap, $regs_secure)) {
2009-09-20 02:53:15 +00:00
$cap = $regs_secure[1];
$cap_secure = $regs_secure[3];
$is_secure_trip = true;
} else {
$is_secure_trip = false;
}
2014-06-24 19:51:22 +00:00
2009-09-20 02:53:15 +00:00
$tripcode = "";
2011-01-08 01:36:00 +00:00
if ($cap != "") { // Copied from Futabally
2009-09-20 02:53:15 +00:00
$cap = strtr($cap, "&amp;", "&");
$cap = strtr($cap, "&#44;", ", ");
2014-06-24 19:51:22 +00:00
$salt = substr($cap . "H.", 1, 2);
$salt = preg_replace("/[^\.-z]/", ".", $salt);
2014-06-24 19:51:22 +00:00
$salt = strtr($salt, ":;<=>?@[\\]^_`", "ABCDEFGabcdef");
2009-09-20 02:53:15 +00:00
$tripcode = substr(crypt($cap, $salt), -10);
}
2014-06-24 19:51:22 +00:00
2009-09-20 02:53:15 +00:00
if ($is_secure_trip) {
if ($cap != "") {
$tripcode .= "!";
}
2014-06-24 19:51:22 +00:00
$tripcode .= "!" . substr(md5($cap_secure . TINYIB_TRIPSEED), 2, 10);
2009-09-20 02:53:15 +00:00
}
2014-06-24 19:51:22 +00:00
return array(preg_replace("/(" . $cap_delimiter . ")(.*)/", "", $name), $tripcode);
2009-09-20 02:53:15 +00:00
}
2014-06-24 19:51:22 +00:00
2009-09-20 02:53:15 +00:00
return array($name, "");
}
function nameBlock($name, $tripcode, $email, $timestamp, $capcode) {
global $tinyib_anonymous;
$anonymous = $tinyib_anonymous[array_rand($tinyib_anonymous)];
$output = '<span class="postername">';
$output .= ($name == '' && $tripcode == '') ? $anonymous : $name;
2014-06-24 19:51:22 +00:00
2011-09-06 06:53:37 +00:00
if ($tripcode != '') {
2009-09-20 02:53:15 +00:00
$output .= '</span><span class="postertrip">!' . $tripcode;
}
2014-06-24 19:51:22 +00:00
$output .= '</span>';
2014-06-24 19:51:22 +00:00
2011-09-06 06:53:37 +00:00
if ($email != '' && strtolower($email) != 'noko') {
2009-09-20 02:53:15 +00:00
$output = '<a href="mailto:' . $email . '">' . $output . '</a>';
}
return $output . $capcode . ' ' . formatDate($timestamp);
2009-09-20 02:53:15 +00:00
}
function writePage($filename, $contents) {
$tempfile = tempnam('res/', TINYIB_BOARD . 'tmp'); /* Create the temporary file */
2009-09-20 02:53:15 +00:00
$fp = fopen($tempfile, 'w');
fwrite($fp, $contents);
fclose($fp);
/* If we aren't able to use the rename function, try the alternate method */
if (!@rename($tempfile, $filename)) {
copy($tempfile, $filename);
unlink($tempfile);
}
2014-06-24 19:51:22 +00:00
2009-09-20 02:53:15 +00:00
chmod($filename, 0664); /* it was created 0600 */
}
function fixLinksInRes($html) {
$search = array(' href="css/', ' src="js/', ' href="src/', ' href="thumb/', ' href="res/', ' href="imgboard.php', ' href="catalog.html', ' href="favicon.ico', 'src="thumb/', 'src="inc/', 'src="sticky.png', 'src="lock.png', ' action="imgboard.php', ' action="catalog.html');
2020-08-11 13:01:00 +00:00
$replace = array(' href="../css/', ' src="../js/', ' href="../src/', ' href="../thumb/', ' href="../res/', ' href="../imgboard.php', ' href="../catalog.html', ' href="../favicon.ico', 'src="../thumb/', 'src="../inc/', 'src="../sticky.png', 'src="../lock.png', ' action="../imgboard.php', ' action="../catalog.html');
2014-06-24 19:51:22 +00:00
2009-09-20 02:53:15 +00:00
return str_replace($search, $replace, $html);
}
function _postLink($matches) {
$post = postByID($matches[1]);
if ($post) {
$is_op = $post['parent'] == TINYIB_NEWTHREAD;
return '<a href="res/' . ($is_op ? $post['id'] : $post['parent']) . '.html#' . $matches[1] . '" class="' . ($is_op ? 'refop' : 'refreply') . '">' . $matches[0] . '</a>';
}
return $matches[0];
}
function postLink($message) {
return preg_replace_callback('/&gt;&gt;([0-9]+)/', '_postLink', $message);
}
2018-07-24 23:46:58 +00:00
function _finishWordBreak($matches) {
return '<a' . $matches[1] . 'href="' . str_replace(TINYIB_WORDBREAK_IDENTIFIER, '', $matches[2]) . '"' . $matches[3] . '>' . str_replace(TINYIB_WORDBREAK_IDENTIFIER, '<br>', $matches[4]) . '</a>';
}
function finishWordBreak($message) {
return str_replace(TINYIB_WORDBREAK_IDENTIFIER, '<br>', preg_replace_callback('/<a(.*?)href="([^"]*?)"(.*?)>(.*?)<\/a>/', '_finishWordBreak', $message));
}
2009-09-20 02:53:15 +00:00
function colorQuote($message) {
2014-06-24 19:51:22 +00:00
if (substr($message, -1, 1) != "\n") {
$message .= "\n";
}
2009-09-20 02:53:15 +00:00
return preg_replace('/^(&gt;[^\>](.*))\n/m', '<span class="unkfunc">\\1</span>' . "\n", $message);
}
function deletePostImages($post) {
if (!isEmbed($post['file_hex']) && $post['file'] != '') {
2014-06-24 19:51:22 +00:00
@unlink('src/' . $post['file']);
}
if ($post['thumb'] != '') {
@unlink('thumb/' . $post['thumb']);
}
2009-09-20 02:53:15 +00:00
}
2020-11-13 20:32:42 +00:00
function deletePost($id) {
$id = intval($id);
$is_op = false;
$parent = 0;
2020-11-13 20:32:42 +00:00
$op = array();
$posts = postsInThreadByID($id, false);
2020-11-13 20:32:42 +00:00
foreach ($posts as $post) {
if ($post['parent'] == TINYIB_NEWTHREAD) {
if ($post['id'] == $id) {
$is_op = true;
}
2020-11-13 20:32:42 +00:00
$op = $post;
continue;
} else if ($post['id'] == $id) {
$parent = $post['parent'];
2020-11-13 20:32:42 +00:00
}
deletePostImages($post);
deleteReportsByPost($post['id']);
deletePostByID($post['id']);
}
if (!empty($op)) {
deletePostImages($op);
deleteReportsByPost($op['id']);
deletePostByID($op['id']);
}
if ($is_op) {
@unlink('res/' . $id . '.html');
return;
}
$current_bumped = 0;
$new_bumped = 0;
$posts = postsInThreadByID($parent, false);
foreach ($posts as $post) {
if ($post['parent'] == TINYIB_NEWTHREAD) {
$current_bumped = $post['bumped'];
} else if ($post['id'] == $id || strtolower($post['email']) == 'sage') {
continue;
}
$new_bumped = $post['timestamp'];
}
if ($new_bumped >= $current_bumped) {
return;
}
updatePostBumped($parent, $new_bumped);
rebuildIndexes();
2020-11-13 20:32:42 +00:00
}
function checkCAPTCHA($mode) {
2021-03-10 18:45:54 +00:00
if ($mode === 'hcaptcha') {
$captcha = isset($_POST['h-captcha-response']) ? $_POST['h-captcha-response'] : '';
if ($captcha == '') {
fancyDie('Failed CAPTCHA. Reason:<br>Please click the checkbox labeled "I am human".');
}
$data = array(
'secret' => TINYIB_HCAPTCHA_SECRET,
'response' => $captcha
);
$verify = curl_init();
curl_setopt($verify, CURLOPT_URL, "https://hcaptcha.com/siteverify");
curl_setopt($verify, CURLOPT_POST, true);
curl_setopt($verify, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($verify, CURLOPT_RETURNTRANSFER, true);
$verifyResponse = curl_exec($verify);
$responseData = json_decode($verifyResponse);
if (!isset($responseData->success) || !$responseData->success) {
fancyDie('Failed CAPTCHA.');
}
} else if ($mode === 'recaptcha') {
2016-07-19 21:14:54 +00:00
require_once 'inc/recaptcha/autoload.php';
$captcha = isset($_POST['g-recaptcha-response']) ? $_POST['g-recaptcha-response'] : '';
$failed_captcha = true;
2014-11-06 11:34:19 +00:00
2016-07-19 21:14:54 +00:00
$recaptcha = new \ReCaptcha\ReCaptcha(TINYIB_RECAPTCHA_SECRET);
2021-04-14 05:54:27 +00:00
$resp = $recaptcha->verify($captcha, remoteAddress());
2016-07-19 21:14:54 +00:00
if ($resp->isSuccess()) {
$failed_captcha = false;
}
2014-11-06 11:34:19 +00:00
2016-07-19 21:14:54 +00:00
if ($failed_captcha) {
$captcha_error = 'Failed CAPTCHA.';
$error_reason = '';
if (count($resp->getErrorCodes()) == 1) {
$error_codes = $resp->getErrorCodes();
$error_reason = $error_codes[0];
}
if ($error_reason == 'missing-input-response') {
2016-07-19 21:14:54 +00:00
$captcha_error .= ' Please click the checkbox labeled "I\'m not a robot".';
} else {
$captcha_error .= ' Reason:';
foreach ($resp->getErrorCodes() as $error) {
$captcha_error .= '<br>' . $error;
}
}
fancyDie($captcha_error);
}
} else if ($mode) { // Simple CAPTCHA
2016-07-19 21:14:54 +00:00
$captcha = isset($_POST['captcha']) ? strtolower(trim($_POST['captcha'])) : '';
$captcha_solution = isset($_SESSION['tinyibcaptcha']) ? strtolower(trim($_SESSION['tinyibcaptcha'])) : '';
if ($captcha == '') {
fancyDie(__('Please enter the CAPTCHA text.'));
2016-07-19 21:14:54 +00:00
} else if ($captcha != $captcha_solution) {
fancyDie(__('Incorrect CAPTCHA text entered. Please try again.<br>Click the image to retrieve a new CAPTCHA.'));
2016-07-19 21:14:54 +00:00
}
2014-11-06 11:34:19 +00:00
}
}
2010-12-31 23:24:55 +00:00
function checkBanned() {
2021-04-14 05:54:27 +00:00
$ban = banByIP(remoteAddress());
2010-12-31 23:24:55 +00:00
if ($ban) {
if ($ban['expire'] == 0 || $ban['expire'] > time()) {
$expire = ($ban['expire'] > 0) ? ('<br>This ban will expire ' . formatDate($ban['expire'])) : '<br>This ban is permanent and will not expire.';
$reason = ($ban['reason'] == '') ? '' : ('<br>Reason: ' . $ban['reason']);
2021-04-14 05:54:27 +00:00
fancyDie('Your IP address ' . remoteAddress() . ' has been banned from posting on this image board. ' . $expire . $reason);
2010-12-31 23:24:55 +00:00
} else {
clearExpiredBans();
}
}
}
function checkKeywords($text) {
$keywords = allKeywords();
foreach ($keywords as $keyword) {
2021-05-01 06:12:19 +00:00
if (substr($keyword['text'], 0, 7) == 'regexp:') {
2021-05-04 06:15:52 +00:00
if (preg_match(substr($keyword['text'], 7), $text)) {
$keyword['text'] = substr($keyword['text'], 7);
2021-05-01 06:12:19 +00:00
return $keyword;
}
continue;
}
if (stripos($text, $keyword['text']) !== false) {
return $keyword;
}
}
return array();
}
2010-12-31 23:24:55 +00:00
function checkFlood() {
if (TINYIB_DELAY > 0) {
$lastpost = lastPostByIP();
if ($lastpost) {
if ((time() - $lastpost['timestamp']) < TINYIB_DELAY) {
fancyDie("Please wait a moment before posting again. You will be able to make another post in " . (TINYIB_DELAY - (time() - $lastpost['timestamp'])) . " " . plural(TINYIB_DELAY - (time() - $lastpost['timestamp']), "second", "seconds") . ".");
}
2010-12-31 23:24:55 +00:00
}
}
}
2011-01-07 09:50:03 +00:00
function checkMessageSize() {
if (TINYIB_MAXMESSAGE > 0 && _strlen($_POST['message']) > TINYIB_MAXMESSAGE) {
fancyDie(sprintf(__('Please shorten your message, or post it in multiple parts. Your message is %1$d characters long, and the maximum allowed is %2$d.'), _strlen($_POST['message']), TINYIB_MAXMESSAGE));
2011-01-07 09:50:03 +00:00
}
}
2021-05-06 02:55:18 +00:00
function checkAutoHide($post) {
if (TINYIB_AUTOHIDE <= 0) {
return;
}
$reports = reportsByPost($post['id']);
if (count($reports) >= TINYIB_AUTOHIDE) {
approvePostByID($post['id'], 0);
$parent_id = $post['parent'] == TINYIB_NEWTHREAD ? $post['id'] : $post['parent'];
threadUpdated($parent_id);
}
}
function manageCheckLogIn($requireKey) {
$account = array();
$loggedin = false;
$isadmin = false;
$key = (isset($_GET['manage']) && $_GET['manage'] != '') ? hashData($_GET['manage']) : '';
if ($key == '' && isset($_SESSION['tinyib_key'])) {
$key = $_SESSION['tinyib_key'];
}
if (TINYIB_MANAGEKEY != '' && $key !== hashData(TINYIB_MANAGEKEY)) {
$_SESSION['tinyib_key'] = '';
$_SESSION['tinyib_account'] = '';
session_destroy();
if ($requireKey) {
fancyDie(__('Invalid key.'));
}
return array($account, $loggedin, $isadmin);
}
if (isset($_POST['username']) && isset($_POST['managepassword']) && $_POST['username'] != '' && $_POST['managepassword'] != '') {
checkCAPTCHA(TINYIB_MANAGECAPTCHA);
$a = accountByUsername($_POST['username']);
if (empty($a) || hashData($_POST['managepassword'], true) !== $a['password']) {
fancyDie(__('Invalid username or password.'));
2009-09-20 02:53:15 +00:00
}
$_SESSION['tinyib_key'] = hashData(TINYIB_MANAGEKEY);
$_SESSION['tinyib_username'] = $a['username'];
$_SESSION['tinyib_password'] = $a['password'];
// Prevent reauthentication
$_POST['username'] = '';
$_POST['managepassword'] = '';
2009-09-20 02:53:15 +00:00
}
2014-06-24 19:51:22 +00:00
if (isset($_SESSION['tinyib_username']) && isset($_SESSION['tinyib_password'])) {
$a = accountByUsername($_SESSION['tinyib_username']);
2021-04-05 00:12:17 +00:00
if (!empty($a) && $a['password'] == $_SESSION['tinyib_password'] && $a['role'] != TINYIB_DISABLED) {
$account = $a;
2009-09-20 02:53:15 +00:00
$loggedin = true;
if ($account['role'] == TINYIB_SUPER_ADMINISTRATOR || $account['role'] == TINYIB_ADMINISTRATOR) {
$isadmin = true;
}
$account['lastactive'] = time();
updateAccount($account);
2009-09-20 02:53:15 +00:00
}
}
2014-06-24 19:51:22 +00:00
return array($account, $loggedin, $isadmin);
2009-09-20 02:53:15 +00:00
}
2021-04-10 03:38:10 +00:00
function manageLogAction($action) {
global $account;
$account_id = 0;
if (isset($account['id'])) {
$account_id = $account['id'];
}
$log = array(
'timestamp' => time(),
'account' => $account_id,
'message' => $action,
);
insertLog($log);
}
function setParent() {
if (isset($_POST["parent"])) {
if ($_POST["parent"] != TINYIB_NEWTHREAD) {
if (!threadExistsByID($_POST['parent'])) {
fancyDie(__('Invalid parent thread ID supplied, unable to create post.'));
}
2014-06-24 19:51:22 +00:00
return $_POST["parent"];
}
}
2014-06-24 19:51:22 +00:00
return TINYIB_NEWTHREAD;
}
function getParent($post) {
if ($post['parent'] == TINYIB_NEWTHREAD) {
return $post['id'];
}
return $post['parent'];
}
function isStaffPost() {
if (isset($_POST['staffpost'])) {
list($loggedin, $isadmin) = manageCheckLogIn(false);
return $loggedin;
}
2014-06-24 19:51:22 +00:00
return false;
}
function validateFileUpload() {
switch ($_FILES['file']['error']) {
case UPLOAD_ERR_OK:
break;
case UPLOAD_ERR_FORM_SIZE:
fancyDie(sprintf(__('That file is larger than %s.'), TINYIB_MAXKBDESC));
break;
case UPLOAD_ERR_INI_SIZE:
fancyDie(sprintf(__('The uploaded file exceeds the upload_max_filesize directive (%s) in php.ini.'), ini_get('upload_max_filesize')));
break;
case UPLOAD_ERR_PARTIAL:
fancyDie(__('The uploaded file was only partially uploaded.'));
break;
case UPLOAD_ERR_NO_FILE:
fancyDie(__('No file was uploaded.'));
break;
case UPLOAD_ERR_NO_TMP_DIR:
fancyDie(__('Missing a temporary folder.'));
break;
case UPLOAD_ERR_CANT_WRITE:
fancyDie(__('Failed to write file to disk'));
break;
default:
fancyDie(__('Unable to save the uploaded file.'));
}
}
2014-06-24 19:51:22 +00:00
function checkDuplicateFile($hex) {
$hexmatches = postsByHex($hex);
if (count($hexmatches) > 0) {
foreach ($hexmatches as $hexmatch) {
fancyDie(sprintf(__('Duplicate file uploaded. That file has already been posted <a href="%s">here</a>.'), 'res/' . (($hexmatch['parent'] == TINYIB_NEWTHREAD) ? $hexmatch['id'] : $hexmatch['parent']) . '.html#' . $hexmatch['id']));
}
}
}
function thumbnailDimensions($post) {
if ($post['parent'] == TINYIB_NEWTHREAD) {
$max_width = TINYIB_MAXWOP;
$max_height = TINYIB_MAXHOP;
} else {
$max_width = TINYIB_MAXW;
$max_height = TINYIB_MAXH;
}
return ($post['image_width'] > $max_width || $post['image_height'] > $max_height) ? array($max_width, $max_height) : array($post['image_width'], $post['image_height']);
}
function videoDimensions($file_location) {
$discard = '';
$exit_status = 1;
exec("ffprobe -version", $discard, $exit_status);
if ($exit_status != 0) {
fancyDie('FFMPEG is not installed, or the commands ffmpeg and ffprobe are not in the server\'s $PATH.<br>Install FFMPEG, or set TINYIB_THUMBNAIL to \'gd\' or \'imagemagick\'.');
}
$dimensions = '';
$exit_status = 1;
exec("ffprobe -hide_banner -loglevel error -of csv=p=0 -select_streams v -show_entries stream=width,height $file_location", $dimensions, $exit_status);
if ($exit_status != 0) {
return array(0, 0);
}
if (is_array($dimensions)) {
$dimensions = $dimensions[0];
}
$split = explode(',', $dimensions);
if (count($split) != 2) {
return array(0, 0);
}
return array(intval($split[0]), intval($split[1]));
}
function videoDuration($file_location) {
$discard = '';
$exit_status = 1;
exec("ffprobe -version", $discard, $exit_status);
if ($exit_status != 0) {
fancyDie('FFMPEG is not installed, or the commands ffmpeg and ffprobe are not in the server\'s $PATH.<br>Install FFMPEG, or set TINYIB_THUMBNAIL to \'gd\' or \'imagemagick\'.');
}
$duration = '';
$exit_status = 1;
exec("ffprobe -hide_banner -loglevel error -of csv=p=0 -show_entries format=duration $file_location", $duration, $exit_status);
if ($exit_status != 0) {
return 0;
}
if (is_array($duration)) {
$duration = $duration[0];
}
return floatval($duration);
}
function ffmpegThumbnail($file_location, $thumb_location, $new_w, $new_h) {
$discard = '';
$exit_status = 1;
exec("ffmpeg -version", $discard, $exit_status);
if ($exit_status != 0) {
fancyDie('FFMPEG is not installed, or the commands ffmpeg and ffprobe are not in the server\'s $PATH.<br>Install FFMPEG, or set TINYIB_THUMBNAIL to \'gd\' or \'imagemagick\'.');
}
$quarter = videoDuration($file_location) / 4;
$exit_status = 1;
2021-04-25 07:00:28 +00:00
exec("ffmpeg -hide_banner -loglevel error -ss $quarter -i $file_location -frames:v 1 -vf scale=w=$new_w:h=$new_h:force_original_aspect_ratio=decrease $thumb_location", $discard, $exit_status);
if ($exit_status != 0) {
return false;
}
}
function createThumbnail($file_location, $thumb_location, $new_w, $new_h, $spoiler) {
$system = explode(".", $thumb_location);
$system = array_reverse($system);
if (TINYIB_THUMBNAIL == 'gd' || (TINYIB_THUMBNAIL == 'ffmpeg' && preg_match("/jpg|jpeg/", $system[0]))) {
if (preg_match("/jpg|jpeg/", $system[0])) {
$src_img = imagecreatefromjpeg($file_location);
} else if (preg_match("/png/", $system[0])) {
$src_img = imagecreatefrompng($file_location);
} else if (preg_match("/gif/", $system[0])) {
$src_img = imagecreatefromgif($file_location);
} else {
return false;
}
2014-06-24 19:51:22 +00:00
if (!$src_img) {
fancyDie(__('Unable to read the uploaded file while creating its thumbnail. A common cause for this is an incorrect extension when the file is actually of a different type.'));
}
2014-06-24 19:51:22 +00:00
$old_x = imageSX($src_img);
$old_y = imageSY($src_img);
$percent = ($old_x > $old_y) ? ($new_w / $old_x) : ($new_h / $old_y);
$thumb_w = round($old_x * $percent);
$thumb_h = round($old_y * $percent);
$dst_img = imagecreatetruecolor($thumb_w, $thumb_h);
if (preg_match("/png/", $system[0]) && imagepng($src_img, $thumb_location)) {
imagealphablending($dst_img, false);
imagesavealpha($dst_img, true);
$color = imagecolorallocatealpha($dst_img, 0, 0, 0, 0);
imagefilledrectangle($dst_img, 0, 0, $thumb_w, $thumb_h, $color);
imagecolortransparent($dst_img, $color);
imagecopyresampled($dst_img, $src_img, 0, 0, 0, 0, $thumb_w, $thumb_h, $old_x, $old_y);
} else {
fastimagecopyresampled($dst_img, $src_img, 0, 0, 0, 0, $thumb_w, $thumb_h, $old_x, $old_y);
2009-09-20 02:53:15 +00:00
}
if (preg_match("/png/", $system[0])) {
if (!imagepng($dst_img, $thumb_location)) {
return false;
}
} else if (preg_match("/jpg|jpeg/", $system[0])) {
if (!imagejpeg($dst_img, $thumb_location, 70)) {
return false;
}
} else if (preg_match("/gif/", $system[0])) {
if (!imagegif($dst_img, $thumb_location)) {
return false;
}
2009-09-20 02:53:15 +00:00
}
imagedestroy($dst_img);
imagedestroy($src_img);
} else if (TINYIB_THUMBNAIL == 'ffmpeg') {
ffmpegThumbnail($file_location, $thumb_location, $new_w, $new_h);
} else { // ImageMagick
$discard = '';
$exit_status = 1;
exec("convert -version", $discard, $exit_status);
if ($exit_status != 0) {
fancyDie('ImageMagick is not installed, or the convert command is not in the server\'s $PATH.<br>Install ImageMagick, or set TINYIB_THUMBNAIL to \'gd\' or \'ffmpeg\'.');
}
$exit_status = 1;
exec("convert $file_location -auto-orient -thumbnail '" . $new_w . "x" . $new_h . "' -coalesce -layers OptimizeFrame -depth 4 -type palettealpha $thumb_location", $discard, $exit_status);
if ($exit_status != 0) {
2009-09-20 02:53:15 +00:00
return false;
}
}
2014-08-03 20:43:33 +00:00
if (!$spoiler) {
return true;
}
if (preg_match("/jpg|jpeg/", $system[0])) {
$src_img = imagecreatefromjpeg($thumb_location);
} else if (preg_match("/png/", $system[0])) {
$src_img = imagecreatefrompng($thumb_location);
} else if (preg_match("/gif/", $system[0])) {
$src_img = imagecreatefromgif($thumb_location);
} else {
return true;
}
if (!$src_img) {
fancyDie(__('Unable to read the uploaded file while creating its thumbnail. A common cause for this is an incorrect extension when the file is actually of a different type.'));
}
$gaussian = array(array(1.0, 2.0, 1.0), array(2.0, 4.0, 2.0), array(1.0, 2.0, 1.0));
for ($x = 1; $x <= 149; $x++) {
imageconvolution($src_img, $gaussian, 16, 0);
}
if (preg_match("/png/", $system[0])) {
if (!imagepng($src_img, $thumb_location)) {
return false;
}
} else if (preg_match("/jpg|jpeg/", $system[0])) {
if (!imagejpeg($src_img, $thumb_location, 70)) {
return false;
}
} else if (preg_match("/gif/", $system[0])) {
if (!imagegif($src_img, $thumb_location)) {
return false;
}
}
imagedestroy($src_img);
2009-09-20 02:53:15 +00:00
return true;
}
2014-08-03 20:43:33 +00:00
function fastimagecopyresampled(&$dst_image, &$src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h, $quality = 3) {
2014-06-24 19:51:22 +00:00
// Author: Tim Eckel - Date: 12/17/04 - Project: FreeRingers.net - Freely distributable.
if (empty($src_image) || empty($dst_image)) {
return false;
}
2009-09-20 02:53:15 +00:00
if ($quality <= 1) {
2014-06-24 19:51:22 +00:00
$temp = imagecreatetruecolor($dst_w + 1, $dst_h + 1);
imagecopyresized($temp, $src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w + 1, $dst_h + 1, $src_w, $src_h);
imagecopyresized($dst_image, $temp, 0, 0, 0, 0, $dst_w, $dst_h, $dst_w, $dst_h);
imagedestroy($temp);
2009-09-20 02:53:15 +00:00
} elseif ($quality < 5 && (($dst_w * $quality) < $src_w || ($dst_h * $quality) < $src_h)) {
$tmp_w = $dst_w * $quality;
$tmp_h = $dst_h * $quality;
2014-06-24 19:51:22 +00:00
$temp = imagecreatetruecolor($tmp_w + 1, $tmp_h + 1);
imagecopyresized($temp, $src_image, $dst_x * $quality, $dst_y * $quality, $src_x, $src_y, $tmp_w + 1, $tmp_h + 1, $src_w, $src_h);
imagecopyresampled($dst_image, $temp, 0, 0, 0, 0, $dst_w, $dst_h, $tmp_w, $tmp_h);
imagedestroy($temp);
2009-09-20 02:53:15 +00:00
} else {
2014-06-24 19:51:22 +00:00
imagecopyresampled($dst_image, $src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);
2009-09-20 02:53:15 +00:00
}