Paste
Pasted as PHP by registered user atmaca ( 1 month ago )
<?php
define('THIS_SCRIPT', 'ft_story_upload');
require_once('./global.php');
/*
FT Story Upload
- Desteklenen türler: JPG / PNG / GIF (5 MB) + MP4 (15 MB)
- Visibility:
1 = Kayıtlı üyeler
3 = Sadece arkadaşlar
Geliştirici: atmaca
*/
function ft_utf8ize($mixed, $fromCharset)
{
if (is_array($mixed))
{
foreach ($mixed as $k => $v)
{
$mixed[$k] = ft_utf8ize($v, $fromCharset);
}
return $mixed;
}
if (is_string($mixed))
{
if (!strcasecmp($fromCharset, 'utf-8'))
{
return $mixed;
}
if (function_exists('mb_convert_encoding'))
{
return @mb_convert_encoding($mixed, 'UTF-8', $fromCharset);
}
return utf8_encode($mixed);
}
return $mixed;
}
function ft_json_exit($arr)
{
global $stylevar;
$fromCharset = 'UTF-8';
if (!empty($stylevar['charset']))
{
$fromCharset = $stylevar['charset'];
}
$json = json_encode($arr, JSON_UNESCAPED_UNICODE);
if ($json === false)
{
$arr = ft_utf8ize($arr, $fromCharset);
$json = json_encode($arr, JSON_UNESCAPED_UNICODE);
}
if (function_exists('ob_get_length') && ob_get_length())
{
@ob_clean();
}
header('Content-Type: application/json; charset=UTF-8');
if ($json === false)
{
echo json_encode(array(
'ok' => 0,
'error' => 'JSON üretilemedi.',
'code' => json_last_error()
));
exit;
}
echo $json;
exit;
}
function ft_upload_error_message($code)
{
$map = array(
1 => 'Dosya çok büyük (php.ini upload_max_filesize).',
2 => 'Dosya çok büyük (form MAX_FILE_SIZE).',
3 => 'Dosya kısmen yüklendi.',
4 => 'Dosya seçilmedi.',
6 => 'Geçici klasör (tmp) bulunamadı.',
7 => 'Dosya diske yazılamadı.',
8 => 'Bir PHP eklentisi yüklemeyi durdurdu.',
);
return isset($map[$code]) ? $map[$code] : ('Yükleme hatası (kod: ' . intval($code) . ').');
}
function ft_fail($code, $ajax)
{
$msg = $code;
if (is_string($code))
{
if (strpos($code, 'upload_hata_') === 0)
{
$err = intval(substr($code, strlen('upload_hata_')));
$msg = ft_upload_error_message($err);
}
else
{
$map = array(
'bad_token' => 'Oturum doğrulaması başarısız. Sayfayı yenileyip tekrar deneyin.',
'dosya_gelmedi' => 'Dosya seçilmedi.',
'dosya_5mb_ustu' => 'Görsel boyutu 5 MB sınırını aşıyor.',
'video_15mb_ustu' => 'Video boyutu 15 MB sınırını aşıyor.',
'gecersiz_resim' => 'Geçersiz resim dosyası.',
'yalnizca_jpg_png_gif' => 'Sadece JPG / PNG / GIF kabul ediliyor.',
'yalnizca_mp4' => 'Sadece MP4 video kabul ediliyor.',
'upload_klasoru_yazilamaz' => 'Sunucuda yükleme klasörü yazılabilir değil.',
'dosya_tasinamadi' => 'Dosya sunucuya kaydedilemedi.',
'not_logged_in' => 'Bu işlem için oturum açmalısınız.',
);
if (isset($map[$code]))
{
$msg = $map[$code];
}
}
}
if ($ajax)
{
ft_json_exit(array(
'ok' => 0,
'error' => $msg,
'code' => $code
));
}
die($msg);
}
/* Visibility normalize helper */
function ft_normalize_visibility($value)
{
$value = intval($value);
// Sadece 1 = kayıtlı üyeler, 3 = arkadaşlar
if ($value === 3)
{
return 3;
}
return 1;
}
$vbulletin->input->clean_array_gpc('p', array(
'do' => TYPE_STR,
'securitytoken' => TYPE_STR,
'ajax' => TYPE_UINT,
'visibility' => TYPE_UINT,
));
$do = $vbulletin->GPC['do'];
$ajax = ($vbulletin->GPC['ajax'] ? true : false);
if (!$vbulletin->userinfo['userid'])
{
if ($ajax)
{
ft_fail('not_logged_in', true);
}
print_no_permission();
}
// Ayarlar (MVP)
$MAX_IMG_BYTES = 5 * 1024 * 1024; // 5 MB
$MAX_VID_BYTES = 15 * 1024 * 1024; // 15 MB
$EXPIRE_SECS = 24 * 60 * 60; // 24 saat
$UPLOAD_DIR = DIR . '/ft_story_uploads';
$UPLOAD_URL = 'ft_story_uploads';
if ($do == 'upload' && $_SERVER['REQUEST_METHOD'] == 'POST')
{
$token = $vbulletin->GPC['securitytoken'];
$raw = (!empty($vbulletin->userinfo['securitytoken_raw']) ? $vbulletin->userinfo['securitytoken_raw'] : '');
if (!$token || $token === 'guest')
{
ft_fail('bad_token', $ajax);
}
if (!verify_security_token($token, $raw))
{
ft_fail('bad_token', $ajax);
}
if (empty($_FILES['storyfile']) || !is_uploaded_file($_FILES['storyfile']['tmp_name']))
{
ft_fail('dosya_gelmedi', $ajax);
}
$f = $_FILES['storyfile'];
if (!empty($f['error']))
{
ft_fail('upload_hata_' . intval($f['error']), $ajax);
}
$tmp = $f['tmp_name'];
$ext = strtolower(pathinfo((string)$f['name'], PATHINFO_EXTENSION));
$is_video = ($ext === 'mp4');
$mediatype = 1;
$width = 0;
$height = 0;
if ($is_video)
{
if ($f['size'] <= 0 || $f['size'] > $MAX_VID_BYTES)
{
ft_fail('video_15mb_ustu', $ajax);
}
$mime = '';
if (function_exists('finfo_open'))
{
$fi = @finfo_open(FILEINFO_MIME_TYPE);
if ($fi)
{
$mime = @finfo_file($fi, $tmp);
@finfo_close($fi);
}
}
if ($mime && $mime !== 'video/mp4' && $mime !== 'application/octet-stream')
{
ft_fail('yalnizca_mp4', $ajax);
}
$mediatype = 2;
$ext = 'mp4';
}
else
{
if ($f['size'] <= 0 || $f['size'] > $MAX_IMG_BYTES)
{
ft_fail('dosya_5mb_ustu', $ajax);
}
$img = @getimagesize($tmp);
if (!$img || empty($img[2]))
{
ft_fail('gecersiz_resim', $ajax);
}
// Sadece JPG/PNG/GIF
$allowed = array(
IMAGETYPE_JPEG => 'jpg',
IMAGETYPE_PNG => 'png',
IMAGETYPE_GIF => 'gif',
);
$type = intval($img[2]);
if (!isset($allowed[$type]))
{
ft_fail('yalnizca_jpg_png_gif', $ajax);
}
$ext = $allowed[$type];
$width = intval($img[0]);
$height = intval($img[1]);
}
if (!is_dir($UPLOAD_DIR))
{
@mkdir($UPLOAD_DIR, 0755, true);
}
if (!is_dir($UPLOAD_DIR) || !is_writable($UPLOAD_DIR))
{
ft_fail('upload_klasoru_yazilamaz', $ajax);
}
$userid = intval($vbulletin->userinfo['userid']);
$visibility = ft_normalize_visibility($vbulletin->GPC['visibility']);
$rand = substr(md5(uniqid((string)$userid, true)), 0, 12);
$fname = 's_' . $userid . '_' . TIMENOW . '_' . $rand . '.' . $ext;
$dest_abs = $UPLOAD_DIR . '/' . $fname;
$dest_rel = $UPLOAD_URL . '/' . $fname;
if (!move_uploaded_file($tmp, $dest_abs))
{
ft_fail('dosya_tasinamadi', $ajax);
}
@chmod($dest_abs, 0644);
$dateline = TIMENOW;
$expiretime = TIMENOW + $EXPIRE_SECS;
$db->query_write("
INSERT INTO ft_story (userid, dateline, expiretime, state, privacy, visibility)
VALUES ($userid, $dateline, $expiretime, 1, 0, $visibility)
");
$storyid = intval($db->insert_id());
$filepath_sql = $db->escape_string($dest_rel);
$db->query_write("
INSERT INTO ft_story_media (storyid, mediatype, filepath, thumbpath, filesize, width, height, dateline)
VALUES ($storyid, " . intval($mediatype) . ", '$filepath_sql', '', " . intval($f['size']) . ", " . intval($width) . ", " . intval($height) . ", $dateline)
");
// Kullanıcı adı + avatar (upload sonrası storybar güncellemesi için)
$u = $db->query_first("
SELECT u.username, u.avatarid, u.avatarrevision, a.avatarpath
FROM user u
LEFT JOIN avatar a ON (a.avatarid = u.avatarid)
WHERE u.userid = $userid
LIMIT 1
");
$username = (!empty($u['username']) ? $u['username'] : $vbulletin->userinfo['username']);
if (!empty($u['avatarpath']))
{
$avatar = $u['avatarpath'];
}
else
{
$avatar = 'image.php?u=' . $userid . '&dateline=' . intval($u['avatarrevision']);
}
// AJAX ise JSON dön
if ($ajax)
{
ft_json_exit(array(
'ok' => 1,
'storyid' => $storyid,
'url' => $dest_rel,
'visibility' => $visibility,
'mediatype' => $mediatype,
'userid' => $userid,
'username' => $username,
'avatar' => $avatar,
'story' => array(
'storyid' => $storyid,
'userid' => $userid,
'username' => $username,
'avatar' => $avatar,
'url' => $dest_rel,
'image' => $dest_rel,
'visibility' => $visibility,
'mediatype' => $mediatype
)
));
}
echo '<h2>Hikaye yüklendi</h2>';
echo '<div>storyid: <b>' . $storyid . '</b></div>';
echo '<div>tür: <b>' . ($mediatype == 2 ? 'Video (MP4)' : 'Görsel') . '</b></div>';
echo '<div>görünürlük: <b>' . ($visibility == 3 ? 'Sadece Arkadaşlar' : 'Forum Üyeleri') . '</b></div>';
if ($mediatype == 2)
{
echo '<div style="margin-top:10px;"><video src="' . htmlspecialchars($dest_rel) . '" controls style="max-width:420px; width:100%;"></video></div>';
}
else
{
echo '<div style="margin-top:10px;"><img src="' . htmlspecialchars($dest_rel) . '" style="max-width:360px; height:auto;"></div>';
}
exit;
}
$token_out = htmlspecialchars($vbulletin->userinfo['securitytoken']);
?>
<h2>Hikaye Yükle</h2>
<form action="ft_story_upload.php" method="post" enctype="multipart/form-data">
<input type="hidden" name="do" value="upload">
<input type="hidden" name="securitytoken" value="<?php echo $token_out; ?>">
<input type="hidden" name="ajax" value="0">
<div style="margin-bottom:10px;">
<input type="file" name="storyfile" accept=".jpg,.jpeg,.png,.gif,.mp4,image/jpeg,image/png,image/gif,video/mp4" required>
</div>
<div style="margin-bottom:10px;">
<label for="ftStoryVisibility" style="display:block; margin-bottom:4px;">Kimler görebilsin?</label>
<select name="visibility" id="ftStoryVisibility">
<option value="1">Forum Üyeleri</option>
<option value="3">Sadece Arkadaşlar</option>
</select>
</div>
<div style="margin-top:10px;">
<button type="submit">Yükle</button>
</div>
<div style="margin-top:8px; font-size:12px; color:#666;">
Maks: Görsel 5 MB / Video 15 MB | Süre: 24 saat | Tür: JPG/PNG/GIF/MP4
</div>
</form>
Revise this Paste