Closed #36
This commit is contained in:
parent
47759adb66
commit
d3eaf27bdc
9 changed files with 230 additions and 82 deletions
26
public_html/media/css/tabs.css
Normal file
26
public_html/media/css/tabs.css
Normal file
|
@ -0,0 +1,26 @@
|
|||
.tabs ul {
|
||||
list-style-type: none;
|
||||
margin: 0 0 1em 0;
|
||||
padding: 0;
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
.tabs li {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.tabs li a {
|
||||
display: inline-block;
|
||||
padding: 0.5em 1em;
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
|
||||
.tabs li a {
|
||||
border: 1px solid white;
|
||||
border-bottom: 1px solid #ccc;
|
||||
color: silver;
|
||||
}
|
||||
.tabs li.selected a {
|
||||
border: 1px solid #ccc;
|
||||
border-bottom: 1px solid white;
|
||||
color: inherit;
|
||||
}
|
|
@ -26,6 +26,11 @@
|
|||
border-color: firebrick;
|
||||
}
|
||||
|
||||
#url-handler textarea {
|
||||
width: 50%;
|
||||
height: 6em;
|
||||
}
|
||||
|
||||
.post .thumbnail {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
|
@ -145,3 +150,13 @@ ul.tagit {
|
|||
.post .form-wrapper {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.tab.url {
|
||||
display: none;
|
||||
}
|
||||
.tab {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
.tab textarea {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
|
|
@ -3,33 +3,6 @@
|
|||
font-size: 90%;
|
||||
}
|
||||
|
||||
.tabs ul {
|
||||
list-style-type: none;
|
||||
margin: 0 0 1em 0;
|
||||
padding: 0;
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
.tabs li {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.tabs li a {
|
||||
display: inline-block;
|
||||
padding: 0.5em 1em;
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
|
||||
.tabs li a {
|
||||
border: 1px solid white;
|
||||
border-bottom: 1px solid #ccc;
|
||||
color: silver;
|
||||
}
|
||||
.tabs li.selected a {
|
||||
border: 1px solid #ccc;
|
||||
border-bottom: 1px solid white;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.avatar-wrapper {
|
||||
text-align: center;
|
||||
}
|
||||
|
|
|
@ -1,35 +1,36 @@
|
|||
$(function()
|
||||
{
|
||||
$('.tabs nav a').click(function(e)
|
||||
{
|
||||
e.preventDefault();
|
||||
var className = $(this).parents('li').attr('class').replace('selected', '').replace(/^\s+|\s+$/, '');
|
||||
$('.tabs nav li').removeClass('selected');
|
||||
$(this).parents('li').addClass('selected');
|
||||
$('.tab').hide();
|
||||
$('.tab.' + className).show();
|
||||
});
|
||||
|
||||
var tags = [];
|
||||
$.getJSON('/tags?json', function(data)
|
||||
{
|
||||
tags = data['tags'];
|
||||
});
|
||||
|
||||
var handler = $('#file-handler');
|
||||
handler.on('dragenter', function(e)
|
||||
$('#file-handler').on('dragenter', function(e)
|
||||
{
|
||||
$(this).addClass('active');
|
||||
});
|
||||
|
||||
handler.on('dragleave', function(e)
|
||||
}).on('dragleave', function(e)
|
||||
{
|
||||
$(this).removeClass('active');
|
||||
});
|
||||
|
||||
handler.on('dragover', function(e)
|
||||
}).on('dragover', function(e)
|
||||
{
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
handler.on('drop', function(e)
|
||||
}).on('drop', function(e)
|
||||
{
|
||||
e.preventDefault();
|
||||
handleFiles(e.originalEvent.dataTransfer.files);
|
||||
$(this).trigger('dragleave');
|
||||
});
|
||||
|
||||
handler.on('click', function(e)
|
||||
}).on('click', function(e)
|
||||
{
|
||||
$(':file').show().focus().trigger('click').hide();
|
||||
});
|
||||
|
@ -39,6 +40,16 @@ $(function()
|
|||
handleFiles(this.files);
|
||||
});
|
||||
|
||||
|
||||
|
||||
$('#url-handler-wrapper button').click(function(e)
|
||||
{
|
||||
var urls = $('#url-handler-wrapper textarea').val().split(/\s+/);
|
||||
handleURLs(urls);
|
||||
});
|
||||
|
||||
|
||||
|
||||
$('.post .move-down-trigger, .post .move-up-trigger').on('click', function()
|
||||
{
|
||||
var dir = $(this).hasClass('move-down-trigger') ? 'd' : 'u';
|
||||
|
@ -62,6 +73,7 @@ $(function()
|
|||
});
|
||||
|
||||
|
||||
|
||||
function sendNextPost()
|
||||
{
|
||||
var posts = $('#upload-step2 .post');
|
||||
|
@ -73,12 +85,14 @@ $(function()
|
|||
|
||||
var postDom = posts.first();
|
||||
var url = postDom.find('form').attr('action') + '?json';
|
||||
var file = postDom.data('file');
|
||||
var sourceFile = postDom.data('file');
|
||||
var sourceUrl = postDom.data('url');
|
||||
var tags = postDom.find('[name=tags]').val();
|
||||
var safety = postDom.find('[name=safety]:checked').val();
|
||||
var source = postDom.find('[name=source]').val();
|
||||
var fd = new FormData();
|
||||
fd.append('file', file);
|
||||
fd.append('file', sourceFile);
|
||||
fd.append('url', sourceUrl);
|
||||
fd.append('tags', tags);
|
||||
fd.append('safety', safety);
|
||||
fd.append('source', source);
|
||||
|
@ -145,17 +159,54 @@ $(function()
|
|||
});
|
||||
|
||||
function handleFiles(files)
|
||||
{
|
||||
handleInputs(files, function(postDom, file)
|
||||
{
|
||||
postDom.data('file', file);
|
||||
$('.file-name strong', postDom).text(file.name);
|
||||
|
||||
if (file.type.match('image.*'))
|
||||
{
|
||||
var img = postDom.find('img')
|
||||
var reader = new FileReader();
|
||||
reader.onload = (function(theFile, img)
|
||||
{
|
||||
return function(e)
|
||||
{
|
||||
img.css('background-image', 'none');
|
||||
img.attr('src', e.target.result);
|
||||
};
|
||||
})(file, img);
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function handleURLs(urls)
|
||||
{
|
||||
handleInputs(urls, function(postDom, url)
|
||||
{
|
||||
postDom.data('url', url);
|
||||
$('.file-name strong', postDom).text(url);
|
||||
$('[name=source]', postDom).val(url);
|
||||
|
||||
var img = postDom.find('img');
|
||||
img.css('background-image', 'none');
|
||||
img.attr('src', url);
|
||||
});
|
||||
}
|
||||
|
||||
function handleInputs(inputs, callback)
|
||||
{
|
||||
$('#upload-step1').fadeOut(function()
|
||||
{
|
||||
for (var i = 0; i < files.length; i ++)
|
||||
for (var i = 0; i < inputs.length; i ++)
|
||||
{
|
||||
var file = files[i];
|
||||
var input = inputs[i];
|
||||
var postDom = $('#post-template').clone(true);
|
||||
postDom.find('form').submit(false);
|
||||
postDom.removeAttr('id');
|
||||
postDom.data('file', file);
|
||||
$('.file-name strong', postDom).text(file.name);
|
||||
|
||||
$('.posts').append(postDom);
|
||||
|
||||
postDom.show();
|
||||
|
@ -164,26 +215,7 @@ $(function()
|
|||
tagItOptions.placeholderText = $('.tags input').attr('placeholder');
|
||||
$('.tags input', postDom).tagit(tagItOptions);
|
||||
|
||||
if (!file.type.match('image.*'))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var img = postDom.find('img')
|
||||
var reader = new FileReader();
|
||||
reader.onload = (function(theFile, img)
|
||||
{
|
||||
return function(e)
|
||||
{
|
||||
/*img.css('max-width', img.css('width'));
|
||||
img.css('max-height', img.css('height'));
|
||||
img.css('width', 'auto');
|
||||
img.css('height', 'auto');*/
|
||||
img.css('background-image', 'none');
|
||||
img.attr('src', e.target.result);
|
||||
};
|
||||
})(file, img);
|
||||
reader.readAsDataURL(file);
|
||||
callback(postDom, input);
|
||||
}
|
||||
$('#upload-step2').fadeIn(function()
|
||||
{
|
||||
|
|
|
@ -197,6 +197,7 @@ class PostController
|
|||
public function uploadAction()
|
||||
{
|
||||
$this->context->stylesheets []= 'upload.css';
|
||||
$this->context->stylesheets []= 'tabs.css';
|
||||
$this->context->scripts []= 'upload.js';
|
||||
$this->context->subTitle = 'upload';
|
||||
PrivilegesHelper::confirmWithException(Privilege::UploadPost);
|
||||
|
@ -206,12 +207,56 @@ class PostController
|
|||
if (InputHelper::get('submit'))
|
||||
{
|
||||
/* file contents */
|
||||
$suppliedFile = $_FILES['file'];
|
||||
self::handleUploadErrors($suppliedFile);
|
||||
if (isset($_FILES['file']))
|
||||
{
|
||||
$suppliedFile = $_FILES['file'];
|
||||
self::handleUploadErrors($suppliedFile);
|
||||
$origName = basename($suppliedFile['name']);
|
||||
$sourcePath = $suppliedFile['tmp_name'];
|
||||
}
|
||||
elseif (InputHelper::get('url'))
|
||||
{
|
||||
$url = InputHelper::get('url');
|
||||
if (!preg_match('/^https?:\/\//', $url))
|
||||
throw new SimpleException('Invalid URL "' . $url . '"');
|
||||
$origName = $url;
|
||||
$sourcePath = tempnam(sys_get_temp_dir(), 'upload') . '.dat';
|
||||
|
||||
//warning: low level sh*t ahead
|
||||
//download the URL $url into $sourcePath
|
||||
$maxBytes = TextHelper::stripBytesUnits(ini_get('upload_max_filesize'));
|
||||
set_time_limit(0);
|
||||
$urlFP = fopen($url, 'rb');
|
||||
if (!$urlFP)
|
||||
throw new SimpleException('Cannot open URL for reading');
|
||||
$sourceFP = fopen($sourcePath, 'w+b');
|
||||
if (!$sourceFP)
|
||||
{
|
||||
fclose($urlFP);
|
||||
throw new SimpleException('Cannot open file for writing');
|
||||
}
|
||||
try
|
||||
{
|
||||
while (!feof($urlFP))
|
||||
{
|
||||
$buffer = fread($urlFP, 4 * 1024);
|
||||
if (fwrite($sourceFP, $buffer) === false)
|
||||
throw new SimpleException('Cannot write into file');
|
||||
fflush($sourceFP);
|
||||
if (ftell($sourceFP) > $maxBytes)
|
||||
throw new SimpleException('File is too big (maximum allowed size: ' . TextHelper::useBytesUnits($maxBytes) . ')');
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
fclose($urlFP);
|
||||
fclose($sourceFP);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* file details */
|
||||
$mimeType = mime_content_type($suppliedFile['tmp_name']);
|
||||
$mimeType = mime_content_type($sourcePath);
|
||||
$imageWidth = null;
|
||||
$imageHeight = null;
|
||||
switch ($mimeType)
|
||||
|
@ -220,17 +265,17 @@ class PostController
|
|||
case 'image/png':
|
||||
case 'image/jpeg':
|
||||
$postType = PostType::Image;
|
||||
list ($imageWidth, $imageHeight) = getimagesize($suppliedFile['tmp_name']);
|
||||
list ($imageWidth, $imageHeight) = getimagesize($sourcePath);
|
||||
break;
|
||||
case 'application/x-shockwave-flash':
|
||||
$postType = PostType::Flash;
|
||||
list ($imageWidth, $imageHeight) = getimagesize($suppliedFile['tmp_name']);
|
||||
list ($imageWidth, $imageHeight) = getimagesize($sourcePath);
|
||||
break;
|
||||
default:
|
||||
throw new SimpleException('Invalid file type "' . $mimeType . '"');
|
||||
}
|
||||
|
||||
$fileHash = md5_file($suppliedFile['tmp_name']);
|
||||
$fileHash = md5_file($sourcePath);
|
||||
$duplicatedPost = R::findOne('post', 'file_hash = ?', [$fileHash]);
|
||||
if ($duplicatedPost !== null)
|
||||
throw new SimpleException('Duplicate upload: @' . $duplicatedPost->id);
|
||||
|
@ -260,9 +305,9 @@ class PostController
|
|||
$dbPost = R::dispense('post');
|
||||
$dbPost->type = $postType;
|
||||
$dbPost->name = $name;
|
||||
$dbPost->orig_name = basename($suppliedFile['name']);
|
||||
$dbPost->orig_name = $origName;
|
||||
$dbPost->file_hash = $fileHash;
|
||||
$dbPost->file_size = filesize($suppliedFile['tmp_name']);
|
||||
$dbPost->file_size = filesize($sourcePath);
|
||||
$dbPost->mime_type = $mimeType;
|
||||
$dbPost->safety = $suppliedSafety;
|
||||
$dbPost->source = $suppliedSource;
|
||||
|
@ -274,7 +319,10 @@ class PostController
|
|||
$dbPost->ownFavoritee = [];
|
||||
$dbPost->sharedTag = $dbTags;
|
||||
|
||||
move_uploaded_file($suppliedFile['tmp_name'], $path);
|
||||
if (is_uploaded_file($sourcePath))
|
||||
move_uploaded_file($sourcePath, $path);
|
||||
else
|
||||
rename($sourcePath, $path);
|
||||
R::store($dbPost);
|
||||
|
||||
$this->context->transport->success = true;
|
||||
|
|
|
@ -359,6 +359,7 @@ class UserController
|
|||
$page = 1;
|
||||
|
||||
PrivilegesHelper::confirmWithException(Privilege::ViewUser, PrivilegesHelper::getIdentitySubPrivilege($user));
|
||||
$this->context->stylesheets []= 'tabs.css';
|
||||
$this->context->stylesheets []= 'user-view.css';
|
||||
$this->context->stylesheets []= 'post-list.css';
|
||||
$this->context->stylesheets []= 'post-small.css';
|
||||
|
|
|
@ -63,6 +63,18 @@ class TextHelper
|
|||
return constant($constantName);
|
||||
}
|
||||
|
||||
private static function stripUnits($string, $base, $suffixes)
|
||||
{
|
||||
$suffix = substr($string, -1, 1);
|
||||
$index = array_search($suffix, $suffixes);
|
||||
if ($index === false)
|
||||
return $string;
|
||||
$number = intval($string);
|
||||
for ($i = 0; $i < $index; $i ++)
|
||||
$number *= $base;
|
||||
return $number;
|
||||
}
|
||||
|
||||
private static function useUnits($number, $base, $suffixes)
|
||||
{
|
||||
$suffix = array_shift($suffixes);
|
||||
|
@ -89,6 +101,16 @@ class TextHelper
|
|||
return self::useUnits($number, 1000, ['', 'K', 'M']);
|
||||
}
|
||||
|
||||
public static function stripBytesUnits($string)
|
||||
{
|
||||
return self::stripUnits($string, 1024, ['B', 'K', 'M', 'G']);
|
||||
}
|
||||
|
||||
public static function stripDecimalUnits($string)
|
||||
{
|
||||
return self::stripUnits($string, 1000, ['', 'K', 'M']);
|
||||
}
|
||||
|
||||
public static function removeUnsafeKeys(&$input, $regex)
|
||||
{
|
||||
if (is_array($input))
|
||||
|
|
|
@ -14,11 +14,40 @@
|
|||
|
||||
<div id="inner-content">
|
||||
<div id="upload-step1">
|
||||
<input type=file multiple style="display: none"/>
|
||||
<div id="file-handler-wrapper">
|
||||
<div id="file-handler">
|
||||
Drop files here!<br>
|
||||
Or just click on this box.
|
||||
<div class="tabs">
|
||||
<nav>
|
||||
<ul>
|
||||
<li class="selected file">
|
||||
<a href="#">
|
||||
Upload from file
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="url">
|
||||
<a href="#">
|
||||
Upload from URL
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<div class="tab file">
|
||||
<input type=file multiple style="display: none"/>
|
||||
<div id="file-handler-wrapper">
|
||||
<div id="file-handler">
|
||||
Drop files here!<br>
|
||||
Or just click on this box.<br><br>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab url">
|
||||
<div id="url-handler-wrapper">
|
||||
<div id="url-handler">
|
||||
<textarea placeholder="You can also paste some URLs." name="urls"></textarea>
|
||||
</div>
|
||||
<button type="submit">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -96,7 +96,9 @@
|
|||
<a href="<?php echo \Chibi\UrlHelper::route('post', 'retrieve', ['name' => $this->context->transport->post->name]) ?>" title="Download">
|
||||
<i class="icon-dl"></i>
|
||||
<span class="ext">
|
||||
<?php echo strtoupper(substr($this->context->transport->post->orig_name, strrpos($this->context->transport->post->orig_name, '.') + 1)) ?>
|
||||
<?php $mimes = ['image/jpeg' => 'JPG', 'image/gif' => 'GIF', 'image/png' => 'PNG', 'application/x-shockwave-flash' => 'SWF'] ?>
|
||||
<?php $mime = $this->context->transport->post->mimeType ?>
|
||||
<?php echo isset($mimes[$mime]) ? $mimes[$mime] : 'unknown' ?>
|
||||
</span>
|
||||
<span class="size">
|
||||
<?php echo TextHelper::useBytesUnits($this->context->transport->post->file_size) ?>
|
||||
|
|
Loading…
Reference in a new issue