629 lines
29 KiB
PHP
629 lines
29 KiB
PHP
<?php
|
|
/*
|
|
* This file is part of kusaba.
|
|
*
|
|
* kusaba is free software; you can redistribute it and/or modify it under the
|
|
* terms of the GNU General Public License as published by the Free Software
|
|
* Foundation; either version 2 of the License, or (at your option) any later
|
|
* version.
|
|
*
|
|
* kusaba is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with
|
|
* kusaba; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
* +------------------------------------------------------------------------------+
|
|
* Upload class
|
|
* +------------------------------------------------------------------------------+
|
|
* Used for image/misc file upload through the post form on board/thread pages
|
|
* +------------------------------------------------------------------------------+
|
|
*/
|
|
|
|
class Upload {
|
|
function __construct($isreply) {
|
|
$this->isreply = $isreply;
|
|
}
|
|
|
|
function exitWithUploadErrorPage($errormsg, $attype, $i, $literal_name='') {
|
|
if ($_POST['AJAX']) {
|
|
exitWithErrorPage($errormsg, '', 'upload_error', array(
|
|
'attachmenttype' => $attype,
|
|
'position' => $i
|
|
));
|
|
}
|
|
else {
|
|
$verbose = $literal_name ? '('._gettext('Error in '.$attype).' "'.$literal_name.'")' : '';
|
|
exitWithErrorPage($errormsg, $verbose);
|
|
}
|
|
}
|
|
|
|
function UnifyAttachments() {
|
|
global $board_class;
|
|
|
|
if ($_POST['legacy-posting']) { // no-js file input (implemented first)
|
|
$attachments = array();
|
|
|
|
// 1) Collect uploaded files
|
|
$file_hashes = array();
|
|
if (isset($_FILES['imagefile']) && is_array($_FILES['imagefile']['name']))
|
|
foreach($_FILES['imagefile']['name'] as $i => $filename) {
|
|
if ($_FILES['imagefile']['error'][$i] != UPLOAD_ERR_NO_FILE) {
|
|
switch ($_FILES['imagefile']['error'][$i]) {
|
|
case UPLOAD_ERR_OK:
|
|
break;
|
|
case UPLOAD_ERR_INI_SIZE:
|
|
$this->exitWithUploadErrorPage(sprintf(_gettext('The uploaded file exceeds the upload_max_filesize directive (%s) in php.ini.'), ini_get('upload_max_filesize')),
|
|
$atype, $i, $filename);
|
|
break;
|
|
case UPLOAD_ERR_FORM_SIZE:
|
|
$this->exitWithUploadErrorPage(sprintf(_gettext('Please make sure your file is smaller than %dB'), $board_class->board['maximagesize']),
|
|
$atype, $i, $filename);
|
|
break;
|
|
case UPLOAD_ERR_PARTIAL:
|
|
$this->exitWithUploadErrorPage(_gettext('The uploaded file was only partially uploaded.'),
|
|
$atype, $i, $filename);
|
|
break;
|
|
case UPLOAD_ERR_NO_TMP_DIR:
|
|
$this->exitWithUploadErrorPage(_gettext('Missing a temporary folder.'),
|
|
$atype, $i, $filename);
|
|
break;
|
|
case UPLOAD_ERR_CANT_WRITE:
|
|
$this->exitWithUploadErrorPage(_gettext('Failed to write file to disk'),
|
|
$atype, $i, $filename);
|
|
break;
|
|
default:
|
|
$this->exitWithUploadErrorPage(_gettext('Unknown File Error'),
|
|
$atype, $i, $filename);
|
|
}
|
|
$file_type = strtolower(preg_replace('/.*(\..+)/','\1', $filename));
|
|
if ($file_type == '.jpeg') {
|
|
// Fix for the rarely used 4-char format
|
|
$file_type = '.jpg';
|
|
}
|
|
$filetype_withoutdot = substr($file_type, 1);
|
|
$generic_filetype_allowed = $board_class->board['any_filetype'] && !$this->isBannedFiletype($filetype_withoutdot);
|
|
if ($generic_filetype_allowed || in_array($filetype_withoutdot, $board_class->board['filetypes_allowed'])) {
|
|
$file_md5 = md5_file($_FILES['imagefile']['tmp_name'][$i]);
|
|
if (in_array($file_md5, $file_hashes)) {
|
|
$this->exitWithUploadErrorPage(_gettext('Duplicate file entry detected.'),
|
|
$atype, $i, $filename);
|
|
}
|
|
else {
|
|
$file_hashes []= $file_md5;
|
|
}
|
|
$file_entry = array(
|
|
'attachmenttype' => 'file',
|
|
'spoiler' => isset($_POST['spoiler-'.$i]) ? $_POST['spoiler-'.$i] : '0',
|
|
'file_original' => isset($_POST['spoiler-'.$i]) && ($_POST['hidename-'.$i]==1)
|
|
? '/hidden'
|
|
: ( $_POST['filename-'.$i]
|
|
? htmlspecialchars($_POST['filename-'.$i])
|
|
: preg_replace('/(.*)\..+/','\1', $filename)
|
|
),
|
|
'tmp_name' => $_FILES['imagefile']['tmp_name'][$i],
|
|
'type' => $_FILES['imagefile']['type'][$i],
|
|
'size' => $_FILES['imagefile']['size'][$i],
|
|
'file_type' => $file_type,
|
|
'filetype_withoutdot' => $filetype_withoutdot,
|
|
'file_md5' => $file_md5
|
|
);
|
|
if (in_array($file_entry['file_type'], array('.png', '.gif'))) {
|
|
$file_entry['emoji_candidate'] = true;
|
|
}
|
|
$attachments []= $file_entry;
|
|
}
|
|
else $this->exitWithUploadErrorPage(_gettext('Sorry, that filetype is not allowed on this board.'),
|
|
$atype, $i, $filename);
|
|
}
|
|
}
|
|
|
|
// 2) Collect embeds
|
|
$embed_hashes = array();
|
|
if (is_array($_POST['embed']) || is_object($_POST['embed'])) {
|
|
foreach($_POST['embed'] as $i => $url) {
|
|
list($site, $code, $time) = $this->ParseEmbed($url);
|
|
if ($code != '') {
|
|
if (array_key_exists($site, $board_class->board['embeds_allowed_assoc'])) {
|
|
$hash = md5($site.'/'.$code);
|
|
if (in_array($hash, $embed_hashes)) {
|
|
$this->exitWithUploadErrorPage(_gettext('Duplicate embed entry detected.'),
|
|
$atype, $i, $site . '/' . $code);
|
|
}
|
|
else {
|
|
$embed_hashes []= $hash;
|
|
}
|
|
$attachments []= array(
|
|
'attachmenttype' => 'embed',
|
|
'spoiler' => isset($_POST['embed-spoiler-'.$i]) ? $_POST['embed-spoiler-'.$i] : '0',
|
|
'embedtype' => $site,
|
|
'embedtime' => $time,
|
|
'embed' => $code,
|
|
'filetype_withoutdot' => $site,
|
|
'file_md5' => $hash,
|
|
'start' => $time
|
|
);
|
|
}
|
|
else $this->exitWithUploadErrorPage(_gettext('Sorry, that filetype is not allowed on this board.'),
|
|
$atype, $i, $site . '/' . $code);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*else { // Fancy embeds (not yet implemented) }*/
|
|
|
|
if (count($attachments) > $board_class->board['maxfiles']) {
|
|
exitWithErrorPage(_gettext('Attachments number limit reached.'), _gettext('Maximum number of files + embeds per post is').' '.$board_class->board['maxfiles'].'.', 'upload_error');
|
|
}
|
|
if (!$this->isreply && count($attachments) == 0 && !$board_class->board['enablenofile']) {
|
|
exitWithErrorPage(_gettext('A file or embed ID is required for a new thread.'));
|
|
}
|
|
$this->attachments = $attachments;
|
|
}
|
|
|
|
function ParseEmbed($url) {
|
|
$sites = array(
|
|
'you' => "/(?:youtu(?:\.be|be\.com)\/(?:.*v(?:\/|=)|(?:.*\/)?)(?P<code>[\w'-]+))(?:[?#&]t=(?:(?P<h>[0-9]{1,2})h)?(?:(?P<m>[0-9]{1,2})m)?(?:(?P<s>[0-9]{1,2})s)?)?/i",
|
|
'vim' => "/[\w\W]*vimeo\.com\/(?:.*?)(?P<code>[0-9]+)(?:#t=(?:(?P<h>[0-9]{1,2})h)?(?:(?P<m>[0-9]{1,2})m)?(?:(?P<s>[0-9]{1,2})s)?)?/i",
|
|
'cob' => "/[\w\W]*coub\.com\/view\/(?P<code>[\w\W]*)[\w\W]*/i",
|
|
'scl' => "/[\w\W]*soundcloud.com\/(?P<code>[\w\W]*)[\w\W]*/i",
|
|
);
|
|
list($site, $code, $time) = array(null,null,null);
|
|
foreach ($sites as $s => $rx) {
|
|
preg_match($rx, $url, $matches);
|
|
if ($matches) {
|
|
$time = 0;
|
|
$code = $matches['code'];
|
|
$site = $s;
|
|
foreach(array('h', 'm', 's') as $u) {
|
|
$t = isset($matches[$u]) ? (int)$matches[$u] : 0;
|
|
if ($t > 0 && $t < 60) {
|
|
if ($u == 'h')
|
|
$t *= 60;
|
|
if ($u != 's')
|
|
$t *= 60;
|
|
$time += $t;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
return array($site, $code, $time);
|
|
}
|
|
|
|
function HandleUpload() {
|
|
global $tc_db, $board_class;
|
|
|
|
if (KU_FILESIZE_METHOD == 'sum') {
|
|
$sum = 0;
|
|
foreach($this->attachments as $i => &$attachment) {
|
|
if ($attachment['attachmenttype'] == 'file') {
|
|
$sum += $attachment['size'];
|
|
}
|
|
if ($sum > $board_class->board['maximagesize']) {
|
|
$this->exitWithUploadErrorPage(sprintf(_gettext('Please make sure that the total size of all your files does not exceed %d KB'), round($board_class->board['maximagesize']) / 1024), $atype, $i);
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach($this->attachments as $i => &$attachment) {
|
|
$atype = $attachment['attachmenttype'];
|
|
$filename = $atype == 'file'
|
|
? $attachment['file_original'].$attachment['file_type']
|
|
: $attachment['embedtype'] . '/' . $attachment['embed'];
|
|
// Check if attachment already posted somewhere else
|
|
$existing = checkMd5($attachment['file_md5'], $board_class->board['name'], $board_class->board['id']);
|
|
if ($existing) {
|
|
if ($board_class->board['duplication']) { // If file duplication is allowed on this board just copy all the properties from the prototype
|
|
$attachment[$attachment['attachmenttype']=='file' ? 'file_name' : 'embed'] = $existing['file'];
|
|
$attachment['imgWidth'] = $existing['image_w'];
|
|
$attachment['imgHeight'] = $existing['image_h'];
|
|
$attachment['file_size'] = $existing['file_size'];
|
|
$attachment['file_size_formatted'] = $existing['file_size_formatted'];
|
|
$attachment['imgWidth_thumb'] = $existing['thumb_w'];
|
|
$attachment['imgHeight_thumb'] = $existing['thumb_h'];
|
|
$attachment['is_duplicate'] = true;
|
|
if ($attachment['attachmenttype']=='embed')
|
|
$attachment['file_original'] = $existing['file_original'];
|
|
continue;
|
|
}
|
|
else {
|
|
$exists_url = KU_BOARDSPATH . '/' . $board_class->board['name'] . '/res/' . $existing['parentid'] . '.html#' . $existing['id'];
|
|
$this->exitWithUploadErrorPage(_gettext('Duplicate file entry detected.') .
|
|
sprintf(_gettext('Already posted %shere%s.'),'<a target="_blank" href="' . $exists_url . '">','</a>'), $atype, $i, $filename);
|
|
}
|
|
}
|
|
// Handle File
|
|
if ($attachment['attachmenttype'] == 'file') {
|
|
if (KU_FILESIZE_METHOD == 'single') {
|
|
if ($attachment['size'] > $board_class->board['maximagesize']) {
|
|
$this->exitWithUploadErrorPage(sprintf(_gettext('Please make sure your file is smaller than %d KB'), round($board_class->board['maximagesize']) / 1024), $atype, $i, $filename);
|
|
}
|
|
}
|
|
$pass = true;
|
|
if (!is_file($attachment['tmp_name']) || !is_readable($attachment['tmp_name'])) {
|
|
$pass = false;
|
|
}
|
|
else {
|
|
$attachment['is_video'] = ($attachment['file_type'] == '.webm' || $attachment['file_type'] == '.mp4');
|
|
if(in_array($attachment['file_type'], array('.jpg', '.gif', '.png'))) {
|
|
if (!@getimagesize($attachment['tmp_name'])) {
|
|
$pass = false;
|
|
}
|
|
}
|
|
elseif($attachment['is_video']) {
|
|
$pass = $this->ffProbe($attachment['tmp_name']);
|
|
}
|
|
}
|
|
if (!$pass) {
|
|
$this->exitWithUploadErrorPage(_gettext('File transfer failure. Please go back and try again.'), $atype, $i, $filename);
|
|
}
|
|
|
|
if($attachment['file_type'] == '.css') {
|
|
$finfo = finfo_open(FILEINFO_MIME_TYPE);
|
|
$mime = finfo_file($finfo, $attachment['tmp_name']);
|
|
if(!$mime)
|
|
$this->exitWithUploadErrorPage("Unable to get MIME type of CSS", $atype, $i, $filename);
|
|
if(!preg_match("/^text/i", $mime)) {
|
|
$this->exitWithUploadErrorPage(sprintf(_gettext("Uploaded CSS is non-text (\"%s\")"), $mime), $atype, $i, $filename);
|
|
}
|
|
finfo_close($finfo);
|
|
if(filesize($attachment['tmp_name']) >= KU_MAX_CSS_SIZE)
|
|
$this->exitWithUploadErrorPage(sprintf(_gettext("Uploaded CSS is too big"), KU_MAX_CSS_SIZE), $atype, $i, $filename);
|
|
$css = file_get_contents($attachment['tmp_name']);
|
|
$css_error = check_css($css);
|
|
if($css_error)
|
|
$this->exitWithUploadErrorPage($css_error, $atype, $i, $filename);
|
|
}
|
|
|
|
$attachment['file_name'] = time() . mt_rand(1, 99);
|
|
|
|
if ($attachment['file_type'] == 'svg') {
|
|
require_once 'svg.class.php';
|
|
$svg = new Svg($attachment['tmp_name']);
|
|
$attachment['imgWidth'] = $svg->width;
|
|
$attachment['imgHeight'] = $svg->height;
|
|
}
|
|
elseif($attachment['is_video']) {
|
|
$videoinfo = $pass;
|
|
$attachment['imgWidth'] = $videoinfo['width'];
|
|
$attachment['imgHeight'] = $videoinfo['height'];
|
|
}
|
|
else {
|
|
$imageDim = getimagesize($attachment['tmp_name']);
|
|
$attachment['imgWidth'] = $imageDim[0];
|
|
$attachment['imgHeight'] = $imageDim[1];
|
|
}
|
|
|
|
$attachment['file_size'] = $attachment['size'];
|
|
|
|
$filetype_forcethumb = $tc_db->GetOne("SELECT " . KU_DBPREFIX . "filetypes.force_thumb
|
|
FROM " . KU_DBPREFIX . "boards, " . KU_DBPREFIX . "filetypes, " . KU_DBPREFIX . "board_filetypes
|
|
WHERE " . KU_DBPREFIX . "boards.id = " . KU_DBPREFIX . "board_filetypes.boardid
|
|
AND " . KU_DBPREFIX . "filetypes.id = " . KU_DBPREFIX . "board_filetypes.typeid
|
|
AND " . KU_DBPREFIX . "boards.name = '" . $board_class->board['name'] . "'
|
|
AND " . KU_DBPREFIX . "filetypes.filetype = '" . $attachment['filetype_withoutdot'] . "';");
|
|
$generic_filetype_allowed = $board_class->board['any_filetype'] && !$this->isBannedFiletype($attachment['filetype_withoutdot']);
|
|
if ($generic_filetype_allowed || $filetype_forcethumb != '') {
|
|
// Make thumbnails for images and videos
|
|
if ($filetype_forcethumb != '' && $filetype_forcethumb == 0) {
|
|
/* If this board has a load balance url and password configured for it, attempt to use it */
|
|
if ($board_class->board['loadbalanceurl'] != '' && $board_class->board['loadbalancepassword'] != '') {
|
|
require_once KU_ROOTDIR . 'inc/classes/loadbalancer.class.php';
|
|
$loadbalancer = new Load_Balancer;
|
|
|
|
$loadbalancer->url = $board_class->board['loadbalanceurl'];
|
|
$loadbalancer->password = $board_class->board['loadbalancepassword'];
|
|
|
|
$response = $loadbalancer->Send('thumbnail', base64_encode(file_get_contents($attachment['tmp_name'])), 'src/' . $attachment['file_name'] . $attachment['file_type'], 'thumb/' . $attachment['file_name'] . 's' . $attachment['file_type'], 'thumb/' . $attachment['file_name'] . 'c' . $attachment['file_type'], '', $this->isreply, true);
|
|
|
|
if ($response != 'failure' && $response != '') {
|
|
$response_unserialized = unserialize($response);
|
|
|
|
$attachment['imgWidth_thumb'] = $response_unserialized['imgw_thumb'];
|
|
$attachment['imgHeight_thumb'] = $response_unserialized['imgh_thumb'];
|
|
} else {
|
|
$this->exitWithUploadErrorPage(_gettext('File was not properly thumbnailed').': ' . $response, $atype, $i, $filename);
|
|
}
|
|
}
|
|
else { /* Otherwise, use this script alone */
|
|
$attachment['file_location'] = KU_BOARDSDIR . $board_class->board['name'] . '/src/' . $attachment['file_name'] . $attachment['file_type'];
|
|
|
|
if($attachment['is_video']) {
|
|
$thumbs = $this->ffThumb($attachment['tmp_name'], KU_BOARDSDIR . $board_class->board['name'] . '/thumb/', $attachment['file_name'], $videoinfo['midtime']);
|
|
if($thumbs) {
|
|
$attachment['imgWidth_thumb'] = $thumbs['thumbwidth'];
|
|
$attachment['imgHeight_thumb'] = $thumbs['thumbheight'];
|
|
$move_result = move_uploaded_file($attachment['tmp_name'], $attachment['file_location']);
|
|
if (!$move_result) {
|
|
$this->exitWithUploadErrorPage(_gettext('Could not copy uploaded image.'), $atype, $i, $filename);
|
|
}
|
|
chmod($attachment['file_location'], 0644);
|
|
if ($attachment['size'] != filesize($attachment['file_location']))
|
|
$this->exitWithUploadErrorPage(_gettext('File was not fully uploaded. Please go back and try again.'), $atype, $i, $filename);
|
|
}
|
|
else $this->exitWithUploadErrorPage(_gettext('Could not create thumbnail.'), $atype, $i, $filename);
|
|
}
|
|
else {
|
|
$attachment['file_thumb_location'] = KU_BOARDSDIR . $board_class->board['name'] . '/thumb/' . $attachment['file_name'] . 's' . $attachment['file_type'];
|
|
$attachment['file_thumb_cat_location'] = KU_BOARDSDIR . $board_class->board['name'] . '/thumb/' . $attachment['file_name'] . 'c' . $attachment['file_type'];
|
|
|
|
if (!move_uploaded_file($attachment['tmp_name'], $attachment['file_location'])) {
|
|
$this->exitWithUploadErrorPage(_gettext('Could not copy uploaded image.'), $atype, $i, $filename);
|
|
}
|
|
chmod($attachment['file_location'], 0644);
|
|
|
|
if ($attachment['size'] == filesize($attachment['file_location'])) {
|
|
if ((!$this->isreply && ($attachment['imgWidth'] > KU_THUMBWIDTH || $attachment['imgHeight'] > KU_THUMBHEIGHT)) || ($this->isreply && ($attachment['imgWidth'] > KU_REPLYTHUMBWIDTH || $attachment['imgHeight'] > KU_REPLYTHUMBHEIGHT))) {
|
|
if (!$this->isreply) {
|
|
if (!createThumbnail($attachment['file_location'], $attachment['file_thumb_location'], KU_THUMBWIDTH, KU_THUMBHEIGHT)) {
|
|
$this->exitWithUploadErrorPage(_gettext('Could not create thumbnail.'), $atype, $i, $filename);
|
|
}
|
|
} else {
|
|
if (!createThumbnail($attachment['file_location'], $attachment['file_thumb_location'], KU_REPLYTHUMBWIDTH, KU_REPLYTHUMBHEIGHT)) {
|
|
$this->exitWithUploadErrorPage(_gettext('Could not create thumbnail.'), $atype, $i, $filename);
|
|
}
|
|
}
|
|
} else {
|
|
if (!createThumbnail($attachment['file_location'], $attachment['file_thumb_location'], $attachment['imgWidth'], $attachment['imgHeight'])) {
|
|
$this->exitWithUploadErrorPage(_gettext('Could not create thumbnail.'), $atype, $i, $filename);
|
|
}
|
|
}
|
|
if (!createThumbnail($attachment['file_location'], $attachment['file_thumb_cat_location'], KU_CATTHUMBWIDTH, KU_CATTHUMBHEIGHT)) {
|
|
$this->exitWithUploadErrorPage(_gettext('Could not create thumbnail.'), $atype, $i, $filename);
|
|
}
|
|
$imageDim_thumb = getimagesize($attachment['file_thumb_location']);
|
|
$attachment['imgWidth_thumb'] = $imageDim_thumb[0];
|
|
$attachment['imgHeight_thumb'] = $imageDim_thumb[1];
|
|
}
|
|
else {
|
|
$this->exitWithUploadErrorPage(_gettext('File was not fully uploaded. Please go back and try again.'), $atype, $i, $filename);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Assign a generic thumbnail to file
|
|
else {
|
|
/* Fetch the mime requirement for this special filetype */
|
|
$filetype_required_mime = $tc_db->GetOne("SELECT `mime`
|
|
FROM `" . KU_DBPREFIX . "filetypes`
|
|
WHERE `filetype` = " . $tc_db->qstr($attachment['filetype_withoutdot']));
|
|
|
|
$attachment['file_is_special'] = false;
|
|
/* If this board has a load balance url and password configured for it, attempt to use it */
|
|
if ($board_class->board['loadbalanceurl'] != '' && $board_class->board['loadbalancepassword'] != '') {
|
|
require_once KU_ROOTDIR . 'inc/classes/loadbalancer.class.php';
|
|
$loadbalancer = new Load_Balancer;
|
|
|
|
$loadbalancer->url = $board_class->board['loadbalanceurl'];
|
|
$loadbalancer->password = $board_class->board['loadbalancepassword'];
|
|
|
|
if ($filetype_required_mime != '') {
|
|
$checkmime = $filetype_required_mime;
|
|
} else {
|
|
$checkmime = '';
|
|
}
|
|
|
|
$response = $loadbalancer->Send('direct', $attachment['tmp_name'], 'src/' . $attachment['file_name'] . $attachment['file_type'], '', '', $checkmime, false, true);
|
|
|
|
$attachment['file_is_special'] = true;
|
|
/* Otherwise, use this script alone */
|
|
}
|
|
else {
|
|
$attachment['file_location'] = KU_BOARDSDIR . $board_class->board['name'] . '/src/' . $attachment['file_name'] . $attachment['file_type'];
|
|
|
|
if (file_exists($attachment['file_location'])) {
|
|
$this->exitWithUploadErrorPage(_gettext('A file by that name already exists'), $atype, $i, $filename);
|
|
die();
|
|
}
|
|
|
|
if($attachment['file_type'] == '.mp3' || $attachment['file_type'] == '.ogg') {
|
|
require_once(KU_ROOTDIR . 'lib/getid3/getid3.php');
|
|
|
|
$getID3 = new getID3;
|
|
$getID3->analyze($attachment['tmp_name']);
|
|
if (isset($getID3->info['id3v2']['APIC'][0]['data']) && isset($getID3->info['id3v2']['APIC'][0]['image_mime'])) {
|
|
$source_data = $getID3->info['id3v2']['APIC'][0]['data'];
|
|
$mime = $getID3->info['id3v2']['APIC'][0]['image_mime'];
|
|
}
|
|
elseif (isset($getID3->info['id3v2']['PIC'][0]['data']) && isset($getID3->info['id3v2']['PIC'][0]['image_mime'])) {
|
|
$source_data = $getID3->info['id3v2']['PIC'][0]['data'];
|
|
$mime = $getID3->info['id3v2']['PIC'][0]['image_mime'];
|
|
}
|
|
|
|
if($source_data) {
|
|
$im = imagecreatefromstring($source_data);
|
|
if (preg_match("/png/", $mime)) {
|
|
$ext = ".png";
|
|
imagepng($im,$attachment['file_location'].".tmp",0,PNG_ALL_FILTERS);
|
|
} else if (preg_match("/jpg|jpeg/", $mime)) {
|
|
$ext = ".jpg";
|
|
imagejpeg($im, $attachment['file_location'].".tmp");
|
|
} else if (preg_match("/gif/", $mime)) {
|
|
$ext = ".gif";
|
|
imagegif($im, $attachment['file_location'].".tmp");
|
|
}
|
|
$attachment['file_thumb_location'] = KU_BOARDSDIR . $board_class->board['name'] . '/thumb/' . $attachment['file_name'] .'s'. $ext;
|
|
$attachment['file_thumb_cat_location'] = KU_BOARDSDIR . $board_class->board['name'] . '/thumb/' . $attachment['file_name'] .'c'. $ext;
|
|
if (!$this->isreply) {
|
|
if (!createThumbnail($attachment['file_location'].".tmp", $attachment['file_thumb_location'], KU_THUMBWIDTH, KU_THUMBHEIGHT)) {
|
|
$this->exitWithUploadErrorPage(_gettext('Could not create thumbnail.'), $atype, $i, $filename);
|
|
}
|
|
}
|
|
else {
|
|
if (!createThumbnail($attachment['file_location'].".tmp", $attachment['file_thumb_location'], KU_REPLYTHUMBWIDTH, KU_REPLYTHUMBHEIGHT)) {
|
|
$this->exitWithUploadErrorPage(_gettext('Could not create thumbnail.'), $atype, $i, $filename);
|
|
}
|
|
}
|
|
if (!createThumbnail($attachment['file_location'].".tmp", $attachment['file_thumb_cat_location'], KU_CATTHUMBWIDTH, KU_CATTHUMBHEIGHT)) {
|
|
$this->exitWithUploadErrorPage(_gettext('Could not create thumbnail.'), $atype, $i, $filename);
|
|
}
|
|
$imageDim_thumb = getimagesize($attachment['file_thumb_location']);
|
|
$attachment['imgWidth_thumb'] = $imageDim_thumb[0];
|
|
$attachment['imgHeight_thumb'] = $imageDim_thumb[1];
|
|
unlink($attachment['file_location'].".tmp");
|
|
}
|
|
}
|
|
|
|
/* Move the file from the post data to the server */
|
|
if (!move_uploaded_file($attachment['tmp_name'], $attachment['file_location'])) {
|
|
$this->exitWithUploadErrorPage(_gettext('Could not copy uploaded image.'), $atype, $i, $filename);
|
|
}
|
|
|
|
/* Check if the filetype provided comes with a MIME restriction */
|
|
if ($filetype_required_mime != '') {
|
|
/* Check if the MIMEs don't match up */
|
|
$finfo = finfo_open( FILEINFO_MIME_TYPE );
|
|
if (finfo_file($finfo, $attachment['file_location']) != $filetype_required_mime) {
|
|
/* Delete the file we just uploaded and kill the script */
|
|
unlink($attachment['file_location']);
|
|
$this->exitWithUploadErrorPage(_gettext('Invalid MIME type for this filetype.'), $atype, $i, $filename);
|
|
}
|
|
finfo_close($finfo);
|
|
}
|
|
|
|
/* Make sure the entire file was uploaded */
|
|
if ($attachment['size'] != filesize($attachment['file_location']))
|
|
$this->exitWithUploadErrorPage(_gettext('File transfer failure. Please go back and try again.'), $atype, $i, $filename);
|
|
|
|
/* Flag that the file used isn't an internally supported type */
|
|
$attachment['file_is_special'] = true;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
$this->exitWithUploadErrorPage(_gettext('Sorry, that filetype is not allowed on this board.'), $atype, $i, $filename);
|
|
}
|
|
}
|
|
// Handle Embed
|
|
else {
|
|
$attachment['embed'] = ($attachment['embedtype'] == 'scl') ? strip_tags(($attachment['embed'])) : strip_tags(substr($attachment['embed'], 0, 20));
|
|
$video_id = $attachment['embed'];
|
|
$attachment['file_name'] = $video_id;
|
|
|
|
if (strpos($video_id, '@') == false && strpos($video_id, '&') == false) {
|
|
$result = $tc_db->GetOne("SELECT HIGH_PRIORITY `videourl`
|
|
FROM `" . KU_DBPREFIX . "embeds`
|
|
WHERE `filetype`= ".$tc_db->qstr($attachment['embedtype']));
|
|
if ($result) {
|
|
$videourl_start = $result;
|
|
}
|
|
else {
|
|
$this->exitWithUploadErrorPage(_gettext('Invalid video type.'), $atype, $i, $filename);
|
|
}
|
|
|
|
$attachment['file_type'] = '.' . $attachment['embedtype'];
|
|
|
|
$results = $tc_db->GetOne("SELECT COUNT(*)
|
|
FROM `" . KU_DBPREFIX . "postembeds`
|
|
WHERE `boardid` = " . $board_class->board['id'] . "
|
|
AND `file` = " . $tc_db->qstr($video_id) . "
|
|
AND `IS_DELETED` = 0");
|
|
if ($results == 0) {
|
|
/*$thumbw = $this->isreply ? KU_REPLYTHUMBWIDTH : KU_THUMBWIDTH;
|
|
$thumbh = $this->isreply ? KU_REPLYTHUMBHEIGHT : KU_THUMBHEIGHT;*/
|
|
$thumb_tmpfile = tmpfile();
|
|
$video_data = fetch_video_data($attachment['embedtype'], $attachment['embed'], KU_VIDEOTHUMBWIDTH, $thumb_tmpfile);
|
|
if (isset($video_data['error']) && $video_data['error'])
|
|
$this->exitWithUploadErrorPage($video_data['error'], $atype, $i, $filename);
|
|
if (isset($video_data['code']) && $video_data['code']) {
|
|
$attachment['embed'] = $video_data['code'];
|
|
}
|
|
$embed_filename = $attachment['embedtype'].'-'.$attachment['embed'].'-';
|
|
$attachment['file_thumb_location'] = KU_BOARDSDIR . $board_class->board['name'] . '/thumb/' . str_replace("/", "_", $embed_filename) . 's.jpg';
|
|
$attachment['file_thumb_cat_location'] = KU_BOARDSDIR . $board_class->board['name'] . '/thumb/' . str_replace("/", "_", $embed_filename) . 'c.jpg';
|
|
// Copy or create thumbnail
|
|
$metaData = stream_get_meta_data($thumb_tmpfile);
|
|
$thumbfile = $metaData['uri'];
|
|
if ($video_data['width'] <= KU_VIDEOTHUMBWIDTH) {
|
|
$thumbnailed = copy($thumbfile, $attachment['file_thumb_location']);
|
|
}
|
|
else {
|
|
$thumbnailed = createThumbnail($thumbfile, $attachment['file_thumb_location'], KU_VIDEOTHUMBWIDTH, KU_VIDEOTHUMBWIDTH);
|
|
}
|
|
if (!$thumbnailed) {
|
|
$this->exitWithUploadErrorPage(_gettext('Could not create thumbnail.'), $atype, $i, $filename);
|
|
}
|
|
// Copy or create catalog thumbnail
|
|
if ($video_data['width'] <= KU_CATTHUMBWIDTH) {
|
|
$thumbnailed = copy($thumbfile, $attachment['file_thumb_cat_location']);
|
|
}
|
|
else {
|
|
$thumbnailed = createThumbnail($thumbfile, $attachment['file_thumb_cat_location'], KU_CATTHUMBWIDTH, KU_CATTHUMBHEIGHT);
|
|
}
|
|
if (!$thumbnailed) {
|
|
$this->exitWithUploadErrorPage(_gettext('Could not create thumbnail.'), $atype, $i, $filename);
|
|
}
|
|
fclose($thumb_tmpfile);
|
|
// Fill the rest of the data
|
|
$imageDim_thumb = getimagesize($attachment['file_thumb_location']);
|
|
$attachment['imgWidth_thumb'] = $imageDim_thumb[0];
|
|
$attachment['imgHeight_thumb'] = $imageDim_thumb[1];
|
|
$attachment['imgWidth'] = $video_data['width'];
|
|
$attachment['imgHeight'] = $video_data['height'];
|
|
$attachment['file_original'] = $video_data['title'];
|
|
$attachment['file_size_formatted'] = $video_data['duration'];
|
|
}
|
|
else {
|
|
$results = $tc_db->GetAll("SELECT `id`,`parentid`
|
|
FROM `" . KU_DBPREFIX . "postembeds`
|
|
WHERE `boardid` = " . $board_class->board['id'] . "
|
|
AND `file` = " . $tc_db->qstr($video_id) . "
|
|
AND `IS_DELETED` = 0
|
|
LIMIT 1");
|
|
foreach ($results as $line) {
|
|
$real_threadid = ($line[1] == 0) ? $line[0] : $line[1];
|
|
$this->exitWithUploadErrorPage(sprintf(_gettext('That video ID has already been posted %shere%s.', $atype, $i, $filename),
|
|
'<a href="' . KU_BOARDSFOLDER . '/' . $board_class->board['name'] . '/res/' . $real_threadid . '.html#' . $line[1] . '">','</a>'));
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
$this->exitWithUploadErrorPage(_gettext('Invalid ID'), $atype, $i, $filename);
|
|
}
|
|
}
|
|
} unset($i);
|
|
}
|
|
|
|
function isBannedFiletype($type) {
|
|
return in_array($type, explode(':', I0_BANNED_FILETYPES));
|
|
}
|
|
|
|
function ffProbe($filepath) {
|
|
if(KU_FFMPEGPATH) putenv('PATH=' . KU_FFMPEGPATH . PATH_SEPARATOR . getenv('PATH'));
|
|
exec("ffprobe -v error -show_entries format=duration:stream=width,height -of default=noprint_wrappers=1:nokey=1 ".$filepath." 2>&1", $finfo, $x);
|
|
if($x !== 0 || count($finfo) !== 3) return false;
|
|
$w = (int)$finfo[0];
|
|
$h = (int)$finfo[1];
|
|
$s = (float)$finfo[2];
|
|
return array(
|
|
'width' => $w,
|
|
'height' => $h,
|
|
'midtime' => gmdate("H:i:s", $s/2)
|
|
);
|
|
}
|
|
|
|
function ffThumb($filepath, $thumbpath, $filename, $midtime) {
|
|
if(KU_FFMPEGPATH) putenv('PATH=' . KU_FFMPEGPATH . PATH_SEPARATOR . getenv('PATH'));
|
|
$scale = "w=".KU_THUMBWIDTH.":h=".KU_THUMBHEIGHT;
|
|
$scalecat = "w=".KU_CATTHUMBWIDTH.":h=".KU_CATTHUMBHEIGHT;
|
|
$foar = ':force_original_aspect_ratio=decrease';
|
|
$rawdur = shell_exec("ffmpeg -i ".$filepath." 2>&1");
|
|
$common = ' -ss '.$midtime.' -vframes 1 -filter:v scale=';
|
|
$newfn = $thumbpath.$filename;
|
|
exec('ffmpeg -i '.$filepath.$common.$scale.$foar.' '.$newfn.'s.jpg'.$common.$scalecat.$foar.' '.$newfn.'c.jpg 2>&1', $result, $x);
|
|
if($x !== 0) return false;
|
|
preg_match('/Output[\s\S]+?\sStream.+?(\d+)x(\d+)[\s\S]+?Stream.+?(\d+)x(\d+)/m', implode('<br>', $result), $ths);
|
|
if(count($ths) == 5) return array(
|
|
'thumbwidth' => $ths[1],
|
|
'thumbheight' => $ths[2],
|
|
'catthumbwidth' => $ths[3],
|
|
'catthumbheight' => $ths[4]
|
|
);
|
|
else return false;
|
|
}
|
|
}
|
|
?>
|