From 3fd34db37ccaad054c776af57c03d4e03e132ecc Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Mon, 7 Oct 2013 00:44:17 +0200 Subject: [PATCH] Worked on #5 --- .gitignore | 2 + config.ini | 1 + files/.gitignore | 2 + init.php | 11 ++ public_html/media/css/core.css | 18 ++- public_html/media/css/upload.css | 110 ++++++++++++++++ public_html/media/img/pixel.gif | Bin 0 -> 67 bytes public_html/media/img/thumb-unavailable.png | Bin 0 -> 688 bytes public_html/media/js/upload.js | 138 ++++++++++++++++++++ src/Bootstrap.php | 1 + src/Controllers/PostController.php | 79 ++++++++++- src/Models/PostSafety.php | 12 ++ src/Models/PostType.php | 6 + src/Views/layout-normal.phtml | 12 +- src/Views/post-upload.phtml | 67 ++++++++++ 15 files changed, 454 insertions(+), 5 deletions(-) create mode 100644 files/.gitignore create mode 100644 init.php create mode 100644 public_html/media/css/upload.css create mode 100644 public_html/media/img/pixel.gif create mode 100644 public_html/media/img/thumb-unavailable.png create mode 100644 public_html/media/js/upload.js create mode 100644 src/Models/PostSafety.php create mode 100644 src/Models/PostType.php create mode 100644 src/Views/post-upload.phtml diff --git a/.gitignore b/.gitignore index b36a8176..a3c85616 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ local.ini db.sqlite db.sqlite-journal +public_html/media/js/jquery.tagit.js +public_html/media/css/jquery.tagit.css diff --git a/config.ini b/config.ini index 5f524247..8c3beb2e 100644 --- a/config.ini +++ b/config.ini @@ -4,6 +4,7 @@ prettyPrint=1 [main] dbPath=./db.sqlite +filesPath=./files/ title=szurubooru [registration] diff --git a/files/.gitignore b/files/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/files/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/init.php b/init.php new file mode 100644 index 00000000..c155b79e --- /dev/null +++ b/init.php @@ -0,0 +1,11 @@ +KewZczmuz#XON+u0n@#=42nNl7#SFt7<7PY Nfa*bPrVvI3YXHjL5YGSr literal 0 HcmV?d00001 diff --git a/public_html/media/img/thumb-unavailable.png b/public_html/media/img/thumb-unavailable.png new file mode 100644 index 0000000000000000000000000000000000000000..dbc3d48cc760eefc199b4d947b459315e5f7ae4e GIT binary patch literal 688 zcmeAS@N?(olHy`uVBq!ia0vp^DImp0*}aIAngIhZYQ(tfJU$Mba4!+xOMlo<)mf@0hfzKw;lyqO?sDq zQc#fP;3aR}nVRWme)(T=VAkE-Z~D02bhDa6=C_;w4TAapo|zJCt^IV-?1@E}&$v~- zNL{pN%ccM;D@l#Hy)ULT+NGRIkk(3F#68jIW{X?o3&%w|+ZF`KSP5wO@m>`<{&T9x z^P8bl8g`0KSupeFlmnGBr#y&^oYG<`Ic3Rq?JA!~;ub|ApA=QIVh%dmC8b=nVvG=QN%#3yrO$B_(9%>hw$xQ#JP|PqoA~q9i4;B-JXpC>2OC7#SEE>lzy98kmI`npl}wSeY7V o8yHy`7-TNH7lNW8H$NpatrE8eiQj3!)WpEx>FVdQ&MBb@0JD$_ApigX literal 0 HcmV?d00001 diff --git a/public_html/media/js/upload.js b/public_html/media/js/upload.js new file mode 100644 index 00000000..c2e58a6d --- /dev/null +++ b/public_html/media/js/upload.js @@ -0,0 +1,138 @@ +$(function() +{ + var handler = $('#file-handler'); + var tags = []; //todo: retrieve tags + + $('#upload-step2').hide(); + + handler.on('dragenter', function(e) + { + $(this).addClass('active'); + }); + + handler.on('dragleave', function(e) + { + $(this).removeClass('active'); + }); + + handler.on('dragover', function(e) + { + e.preventDefault(); + }); + + handler.on('drop', function(e) + { + e.preventDefault(); + handleFiles(e.originalEvent.dataTransfer.files); + $(this).trigger('dragleave'); + }); + + handler.on('click', function(e) + { + $(':file').show().focus().trigger('click').hide(); + }); + + $(':file').change(function(e) + { + handleFiles(this.files); + }); + + $('.post .remove-trigger').on('click', function() + { + $(this).parents('.post').slideUp(function() + { + $(this).remove(); + }); + }); + + + $('#upload-step2 form').submit(function(e) + { + var url = $(this).attr('action') + '?json'; + e.preventDefault(); + var posts = $('.post', $(this)); + + if (posts.length == 0) + { + alert('No posts to upload!'); + return; + } + + posts.each(function() + { + var postDom = $(this); + var file = postDom.data('file'); + var tags = postDom.find('[name=tags]').val(); + var safety = postDom.find('[name=safety]').val(); + var fd = new FormData(); + fd.append('file', file); + fd.append('tags', tags); + fd.append('safety', safety); + + var ajax = + { + url: url, + data: fd, + processData: false, + contentType: false, + type: 'POST', + success: function(data) + { + //todo: do this nice + if (data['success']) + { + postDom.slideUp(); + //alert(file.name + ': success!'); + } + else + { + alert(data['errorMessage']); + } + } + }; + + $.ajax(ajax); + }); + }); + + function handleFiles(files) + { + $('#upload-step1').fadeOut(function() + { + for (var i = 0; i < files.length; i ++) + { + var file = files[i]; + var postDom = $('#post-template').clone(true); + postDom.removeAttr('id'); + postDom.data('file', file); + $('.file-name strong', postDom).text(file.name); + $('.tags input', postDom).tagit({caseSensitive: true, availableTags: tags, placeholderText: $('.tags input').attr('placeholder')}); + $('.posts').append(postDom); + + if (!file.type.match('image.*')) + { + continue; + } + + var reader = new FileReader(); + reader.onload = (function(theFile) + { + return function(e) + { + var img = postDom.find('img') + /*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); + reader.readAsDataURL(file); + } + $('#upload-step2').fadeIn(function() + { + }); + }); + } +}); diff --git a/src/Bootstrap.php b/src/Bootstrap.php index f96e2e59..707f1f2a 100644 --- a/src/Bootstrap.php +++ b/src/Bootstrap.php @@ -29,6 +29,7 @@ class Bootstrap $this->context->title = $this->config->main->title; $this->context->stylesheets = ['core.css']; + $this->context->scripts = []; $this->context->layoutName = isset($_GET['json']) ? 'layout-json' diff --git a/src/Controllers/PostController.php b/src/Controllers/PostController.php index 24167d9d..0a77b1a8 100644 --- a/src/Controllers/PostController.php +++ b/src/Controllers/PostController.php @@ -1,6 +1,13 @@ context->stylesheets []= 'jquery.tagit.css'; + $this->context->scripts []= 'jquery.tagit.js'; + $callback(); + } + /** * @route /posts * @route /posts/{query} @@ -27,8 +34,78 @@ class PostController */ public function uploadAction() { + $this->context->stylesheets []= 'upload.css'; + $this->context->scripts []= 'upload.js'; $this->context->subTitle = 'upload'; - throw new Exception('Not implemented'); + + PrivilegesHelper::confirmWithException($this->context->user, Privilege::UploadPost); + + if (isset($_FILES['file'])) + { + $suppliedSafety = intval(InputHelper::get('safety')); + if (!in_array($suppliedSafety, PostSafety::getAll())) + throw new SimpleException('Invalid safety type "' . $suppliedSafety . '"'); + + $suppliedTags = InputHelper::get('tags'); + $suppliedTags = preg_split('/[,;\s+]/', $suppliedTags); + $suppliedTags = array_filter($suppliedTags); + $suppliedTags = array_unique($suppliedTags); + foreach ($suppliedTags as $tag) + if (!preg_match('/^\w+$/i', $tag)) + throw new SimpleException('Invalid tag "' . $tag . '"'); + + $suppliedFile = $_FILES['file']; + + switch ($suppliedFile['type']) + { + case 'image/gif': + case 'image/png': + case 'image/jpeg': + $postType = PostType::Image; + break; + case 'application/x-shockwave-flash': + $postType = PostType::Flash; + break; + default: + throw new SimpleException('Invalid file type "' . $suppliedFile['type'] . '"'); + } + + //todo: find out duplicate files + + do + { + $name = md5(mt_rand() . uniqid()); + $path = $this->config->main->filesPath . DIRECTORY_SEPARATOR . $name; + } + while (file_exists($path)); + + $dbTags = []; + foreach ($suppliedTags as $tag) + { + $dbTag = R::findOne('tag', 'name = ?', [$tag]); + if (!$dbTag) + { + $dbTag = R::dispense('tag'); + $dbTag->name = $tag; + R::store($dbTag); + } + $dbTags []= $dbTag; + } + + $dbPost = R::dispense('post'); + $dbPost->type = $postType; + $dbPost->name = $name; + $dbPost->mimeType = $suppliedFile['type']; + $dbPost->safety = $suppliedSafety; + $dbPost->sharedTag = $dbTags; + + move_uploaded_file($suppliedFile['tmp_name'], $path); + R::store($dbPost); + + //todo: generate thumbnail + + $this->context->transport->success = true; + } } /** diff --git a/src/Models/PostSafety.php b/src/Models/PostSafety.php new file mode 100644 index 00000000..8c24a330 --- /dev/null +++ b/src/Models/PostSafety.php @@ -0,0 +1,12 @@ + - + context->subTitle)): ?> <?php printf('%s – %s', $this->context->title, $this->context->subTitle) ?> <?php echo $this->context->title ?> context->stylesheets as $name): ?> - + + + + + + + context->scripts as $name): ?> + - diff --git a/src/Views/post-upload.phtml b/src/Views/post-upload.phtml new file mode 100644 index 00000000..73f40a9f --- /dev/null +++ b/src/Views/post-upload.phtml @@ -0,0 +1,67 @@ +context->transport->success === true): ?> +

Post created!

+context->transport->errorMessage)): ?> +

context->transport->errorMessage ?>

+ + + + +
+
+ +
+
+ Drop files here!
+ Or just click on this box. +
+
+ +
+
+ +
+
+
+
+ +
+ +
+
+
+ +
+ + remove × + + + Thumbnail +
+
+ + filename.jpg +
+ +
+ + + + +
+ +
+ + +
+
+
+
+
+ +