From 24547ccec6526fcef3cccb34bc35fb81f31236b3 Mon Sep 17 00:00:00 2001 From: Nicolas BERNSTEIN Date: Sun, 12 Feb 2012 19:50:55 +0100 Subject: A lot of changes : blogging system essentially. --- design/style.css | 28 +++++++++++++++++++ lib/account/list.php | 23 ++++++++++++++++ lib/account/new.php | 10 +++++-- lib/blog/delete.php | 13 +++++++++ lib/blog/drafts.php | 19 +++++++++++++ lib/blog/edit.php | 61 +++++++++++++++++++++++++++++++++++++++++ lib/blog/index.php | 72 +++++++++++++++++++++++++++++++++++++++++++++++++ lib/blog/post.php | 44 ++++++++++++++++++++++++++++++ lib/blog/publish.php | 13 +++++++++ lib/conf/apps.php | 18 ++++++++++--- lib/conf/image.php | 4 +-- lib/image/index.php | 22 ++++++++++++--- lib/image/rename.php | 32 ++++++++++++++++++++++ lib/image/upload.php | 8 ++++-- lib/notes/index.php | 21 --------------- lib/study/index.php | 4 +++ schema.sql | 47 +++++++++++++++++++++++++++----- tpl/account/list.php | 21 +++++++++++++++ tpl/blog/drafts.php | 41 ++++++++++++++++++++++++++++ tpl/blog/index.php | 53 ++++++++++++++++++++++++++++++++++++ tpl/general/top.php | 9 ++++--- tpl/image/index.php | 23 +++++++++------- tpl/image/upload-ok.php | 11 +++++++- tpl/image/upload.php | 3 ++- tpl/notes/index.php | 13 --------- tpl/study/index.php | 4 ++- 26 files changed, 549 insertions(+), 68 deletions(-) create mode 100644 lib/account/list.php create mode 100644 lib/blog/delete.php create mode 100644 lib/blog/drafts.php create mode 100644 lib/blog/edit.php create mode 100644 lib/blog/index.php create mode 100644 lib/blog/post.php create mode 100644 lib/blog/publish.php create mode 100644 lib/image/rename.php delete mode 100644 lib/notes/index.php create mode 100644 tpl/account/list.php create mode 100644 tpl/blog/drafts.php create mode 100644 tpl/blog/index.php delete mode 100644 tpl/notes/index.php diff --git a/design/style.css b/design/style.css index 2d41f57..dbb3e91 100644 --- a/design/style.css +++ b/design/style.css @@ -171,6 +171,7 @@ iframe, textarea { } .small_right { + clear: right; float: right; } @@ -262,3 +263,30 @@ hr { border-left: 1px solid #0000FF; border-bottom: 1px solid #0000FF; } + + +/* blog */ + +.blog_post { + margin: 4px; + margin-top: 16px; + border-left: 1px solid #ccc; + border-bottom: 1px dashed #ccc; + padding: 8px; + padding-top: 16px; +} + +.blog_post .inside { + /*clear: right; + padding-top: 1px;*/ +} +.blog_post .small_right { + margin-left: 100px; +} + +.blog_post h2 { + margin: 0px; + padding: 0px; + margin-left: 16px; + font-size: 1.2em; +} diff --git a/lib/account/list.php b/lib/account/list.php new file mode 100644 index 0000000..dcb6575 --- /dev/null +++ b/lib/account/list.php @@ -0,0 +1,23 @@ + array ( + "name" => "username", + "reg_date" => "date registered", + "nbNotes" => "number of notes", + ), + "way" => $ord_ways, +); +$fdefaults = array ( + "order" => "name", + "way" => "ASC", +); + +$users = array(); +$n = sql("SELECT account.id AS id, login AS name, nc.count AS nbNotes, pc.count AS nbPosts ". + "FROM account ". + "LEFT JOIN (SELECT notes.owner AS owner, COUNT(notes.id) AS count FROM notes WHERE notes.public != 0 GROUP BY notes.owner) nc ON nc.owner = account.id ". + "LEFT JOIN (SELECT blog_posts.owner AS owner, COUNT(blog_posts.id) AS count FROM blog_posts GROUP BY blog_posts.owner) pc ON pc.owner = account.id ". + "ORDER BY " . get_filter("order") . " " . get_filter("way")); +while ($nn = mysql_fetch_assoc($n)) $users[] = $nn; +require("tpl/account/list.php"); diff --git a/lib/account/new.php b/lib/account/new.php index c06083e..2366fbb 100644 --- a/lib/account/new.php +++ b/lib/account/new.php @@ -3,18 +3,23 @@ $title = "Register"; $login = ""; +$email = ""; if (isset($_POST['login']) && isset($_POST['pw1']) && isset($_POST['pw2'])) { $login = esca($_POST["login"]); + $email = esca($_POST["email"]); $pw1 = esc($_POST["pw1"]); $pw2 = esc($_POST["pw2"]); if ($login == "") { $error = "You must enter a username."; + } else if (!preg_match('#^[\w.-]+@[\w.-]+\.[a-zA-Z]{2,6}$#', $email)) { + $error = "You must enter a valid email address."; } else if ($pw1 != $pw2) { $error = "You must enter twice the same password."; } else if ($pw1 == "") { $error = "You must enter a password"; } else { - sql("INSERT INTO account(login, password) VALUES('" . escs($login) . "', PASSWORD('$pw1'))"); + sql("INSERT INTO account(login, password, email, reg_date) ". + "VALUES('" . escs($login) . "', PASSWORD('$pw1'), '" . escs($email) . "', NOW())"); $message = "Your account has been created. Please log in now."; $url = $homepage; require("tpl/account/login.php"); @@ -25,7 +30,8 @@ $form_message = "Please fill in the following form to create an account :"; $fields = array( array("label" => "Username : ", "name" => "login", "value" => $login), array("label" => "Password : ", "name" => "pw1", "type" => "password"), - array("label" => "Confirm password : ", "name" => "pw2", "type" => "password") + array("label" => "Confirm password : ", "name" => "pw2", "type" => "password"), + array("label" => "Email address : ", "name" => "email", "value" => $email) ); $validate = "Create an account"; diff --git a/lib/blog/delete.php b/lib/blog/delete.php new file mode 100644 index 0000000..a57b5ac --- /dev/null +++ b/lib/blog/delete.php @@ -0,0 +1,13 @@ += 3, 'blog'); +$postid = intval($args[2]); + +$post = mysql_fetch_assoc(sql("SELECT owner FROM blog_posts WHERE id = $postid")); +assert_error($post && $post['owner'] == $user['id'], + "This note does not exist, or you are not allowed to delete it."); + +token_validate("Do you really want to delete this post ?", "blog"); +sql("DELETE FROM blog_posts WHERE id = $postid"); +sql("DELETE FROM blog_tags WHERE post = $postid"); +header("Location: drafts-blog"); diff --git a/lib/blog/drafts.php b/lib/blog/drafts.php new file mode 100644 index 0000000..735b039 --- /dev/null +++ b/lib/blog/drafts.php @@ -0,0 +1,19 @@ += 1) { + $v = array(); + foreach ($tags as $tag) { + $v[] = "($postid, '" . escs($tag) . "')"; + } + sql("INSERT INTO blog_tags(post, tag) VALUES " . implode(',', $v)); + } + if ($post['draft']) { + header("Location: drafts-blog"); + } else { + header("Location: blog"); + } + die(); + } +} + +$title = "Edit : " . $post['title']; +$fields = array( + array("label" => "Title : ", "name" => "title", "value" => $post_title), + array("label" => "Tags : ", "name" => "tags", "type" => "text", "value" => $post_tags), + array("label" => "Text : ", "name" => "text", "type" => "textarea", "value" => $post_text), + ); +$validate = "Edit post"; + +require("tpl/general/form.php"); + + diff --git a/lib/blog/index.php b/lib/blog/index.php new file mode 100644 index 0000000..aaeb969 --- /dev/null +++ b/lib/blog/index.php @@ -0,0 +1,72 @@ + array ( + "title" => "title", + "owner" => "author name", + "date" => "date published", + ), + "way" => $ord_ways, +); +$fdefaults = array ( + "order" => "date", + "way" => "DESC", +); + +$posts = array(); + +$fa = array ( + "author" => array(), + "date" => array(), + "tag" => array(), +); +$fvalues = array(); +for ($i = 2; $i < count($args); $i += 2) { + if (isset($args[$i+1])) { + $fvalues[$args[$i]] = urldecode($args[$i+1]); + } +} +function count_in($fat, $v, $d) { + global $fa; + if (isset($fa[$fat][$v])) { + $fa[$fat][$v]['count']++; + } else { + $fa[$fat][$v] = array('name' => $d, 'count' => 1); + } +} + +$q = + "SELECT blog_posts.id AS id, blog_posts.title AS title, blog_posts.date AS date, ". + "DATE_FORMAT(blog_posts.date, '%Y-%m') AS month, ". + "blog_posts.text_html AS text_html, GROUP_CONCAT(ba.tag SEPARATOR ', ') AS tags, ". + "account.login AS owner, account.id AS owner_id ". + "FROM blog_posts LEFT JOIN account ON blog_posts.owner = account.id ". + "LEFT JOIN blog_tags ba ON ba.post = blog_posts.id ". + (isset($fvalues['tag']) ? "LEFT JOIN blog_tags bb ON bb.post = blog_posts.id AND bb.tag = '" . escs($fvalues['tag'])."' " : ""). + "WHERE blog_posts.draft = 0 ". + (isset($fvalues['author']) ? 'AND blog_posts.owner = ' . intval($fvalues['author']) .' ' : ''). + (isset($fvalues['date']) ? "AND blog_posts.date >= '" . escs(str_replace('.', '-', $fvalues['date'])) ."-01 00:00:00' " . + "AND blog_posts.date <= '" . escs(str_replace('.', '-', $fvalues['date'])) . "-31 23:59:59'" : ''). + (isset($fvalues['tag']) ? " AND bb.post != 0 " : ""). + "GROUP BY blog_posts.id ". + "ORDER BY " . get_filter('order') . " " . get_filter('way'); +$n = sql($q); + + +while ($pp = mysql_fetch_assoc($n)) { + $posts[] = $pp; + count_in('author', $pp['owner_id'], $pp['owner']); + $tags = explode(', ', $pp['tags']); + foreach ($tags as $tag) { + count_in('tag', $tag, $tag); + } + count_in('date', str_replace('-', '.', $pp['month']), $pp['month']); +} + +$can_post = ($user['priv'] >= $apps['blog']['drafts'] && $user['id'] != 0); +$can_edit = ($user['priv'] >= $apps['blog']['edit'] && $user['id'] != 0); +$can_delete = ($user['priv'] >= $apps['blog']['delete'] && $user['id'] != 0); + +require("tpl/blog/index.php"); diff --git a/lib/blog/post.php b/lib/blog/post.php new file mode 100644 index 0000000..1f1525a --- /dev/null +++ b/lib/blog/post.php @@ -0,0 +1,44 @@ += 1) { + $v = array(); + foreach ($tags as $tag) { + $v[] = "($id, '" . escs($tag) . "')"; + } + sql("INSERT INTO blog_tags(post, tag) VALUES " . implode(',', $v)); + } + header("Location: drafts-blog"); + die(); + } +} + +$title = "Post to blog"; +$fields = array( + array("label" => "Title : ", "name" => "title", "value" => $post_title), + array("label" => "Tags ", "name" => "tags", "type" => "text", "value" => $post_tags), + array("label" => "Text : ", "name" => "text", "type" => "textarea", "value" => $post_text), + ); +$validate = "Post entry"; + +require("tpl/general/form.php"); diff --git a/lib/blog/publish.php b/lib/blog/publish.php new file mode 100644 index 0000000..1674911 --- /dev/null +++ b/lib/blog/publish.php @@ -0,0 +1,13 @@ += 3, 'blog'); +$postid = intval($args[2]); + +$post = mysql_fetch_assoc(sql("SELECT owner, draft FROM blog_posts WHERE id = $postid")); +assert_error($post && $post['owner'] == $user['id'], + "This note does not exist, or you are not allowed to delete it."); +assert_error($post['draft'] == 1, "This post is already published."); + +token_validate("Are you sure this post is ready to be published ?", "blog"); +sql("UPDATE blog_posts SET draft = 0, date = NOW() WHERE id = $postid"); +header("Location: blog"); diff --git a/lib/conf/apps.php b/lib/conf/apps.php index d8cb1c2..26de50c 100644 --- a/lib/conf/apps.php +++ b/lib/conf/apps.php @@ -1,6 +1,6 @@ array( "index" => 1, "delete" => 1, + "rename" => 1, "upload" => 0, ), // Account application "account" => array( "new" => 0, + "list" => 0, ), // Notebook application "notes" => array( - "index" => 0, + //"index" => 0, "user" => 0, "view" => 0, "new" => 1, @@ -28,6 +30,16 @@ $apps = array( "source" => 0, ), + // Blogging application + "blog" => array( + "index" => 0, + "drafts" => 1, + "publish" => 1, + "post" => 1, + "edit" => 1, + "delete" => 1, + ), + // Studies application "deck" => array( "index" => 0, @@ -52,7 +64,7 @@ $apps = array( ), "study" => array ( - "index" => 1, + "index" => 0, "deckadd" => 1, "deck" => 1, "deckrm" => 1, diff --git a/lib/conf/image.php b/lib/conf/image.php index 8fd48ec..462300e 100644 --- a/lib/conf/image.php +++ b/lib/conf/image.php @@ -3,5 +3,5 @@ $baseurl = "http://localhost/alex.auvolat/images/"; $savedir = getcwd() . "/images/"; $miniature_width = 127; -$quota = ceil((time() - 1220000000) / (3600 * 24 * 20)); -$min_priv_for_no_quota = 2; +//$quota = 128;; //ceil((time() - 1220000000) / (3600 * 24 * 20)); +//$min_priv_for_no_quota = 2; diff --git a/lib/image/index.php b/lib/image/index.php index 01c0928..59a304d 100644 --- a/lib/image/index.php +++ b/lib/image/index.php @@ -2,16 +2,31 @@ require("lib/conf/image.php"); +$filters = array ( + "order" => array ( + "name" => "title", + "upl_date" => "date uploaded", + ), + "way" => $ord_ways, +); +$fdefaults = array ( + "order" => "name", + "way" => "ASC", +); + $title = "Image upload"; $images = array(); -$files = sql("SELECT * FROM images WHERE owner = " . $user['id']); +$files = sql("SELECT * FROM images WHERE owner = " . $user['id'] . + " ORDER BY " . get_filter('order') . " " . get_filter('way')); while ($img = mysql_fetch_assoc($files)) $images[] = $img; -if (count($images) >= $quota && $user['priv'] < $min_priv_for_no_quota) { +/*if (count($images) >= $quota && $user['priv'] < $min_priv_for_no_quota) { $error = "You have already exceeded your quota of $quota uploadable images."; $can_upload = false; -} else if ($user['priv'] < $apps['image']['upload']) { +} else */ + +if ($user['priv'] < $apps['image']['upload']) { $error = "You don't have the rights to upload images."; $can_upload = false; } else { @@ -19,5 +34,6 @@ if (count($images) >= $quota && $user['priv'] < $min_priv_for_no_quota) { } $can_delete = ($user['priv'] >= $apps['image']['delete'] && $user['id'] != 0); +$can_rename = ($user['priv'] >= $apps['image']['rename'] && $user['id'] != 0); require("tpl/image/index.php"); diff --git a/lib/image/rename.php b/lib/image/rename.php new file mode 100644 index 0000000..0fbc442 --- /dev/null +++ b/lib/image/rename.php @@ -0,0 +1,32 @@ + "New name : ", "name" => "name", "value" => $name), +); +$validate = "Rename"; + +require("tpl/general/form.php"); diff --git a/lib/image/upload.php b/lib/image/upload.php index 812295f..5176a3a 100644 --- a/lib/image/upload.php +++ b/lib/image/upload.php @@ -4,11 +4,15 @@ $title = "Upload an image"; require("lib/conf/image.php"); +/* $number = mysql_fetch_assoc(sql("SELECT count(*) AS count FROM images WHERE owner = " . $user['id'])); assert_error($number['count'] < $quota || $user['priv'] >= $min_priv_for_no_quota || $user['id'] == 0, "You have already exceeded your upload quota."); +*/ -if (isset($_FILES['image'])) { +if (isset($_FILES['image']) && isset($_POST['name'])) { + $name = esca($_POST['name']); + if ($name == "") $name = $_FILES['image']['name']; if ($_FILES['image']['error'] != 0) { $error = "Sorry, an error occurred while uploading your file. Try with a smaller one."; require("tpl/image/upload.php"); @@ -24,7 +28,7 @@ if (isset($_FILES['image'])) { $error = "Sorry, we only accept GIF, PNG and JPEG images."; require("tpl/image/upload.php"); } - sql("INSERT INTO images(owner, extension) VALUES(" . $user['id'] . ", '$type')"); + sql("INSERT INTO images(owner, extension, name, upl_date) VALUES(" . $user['id'] . ", '$type', '" . escs($name) . "', NOW())"); $id = mysql_insert_id(); $filen = $savedir . $id . "." . $type; $minin = $savedir . $id . "-min." . $type; diff --git a/lib/notes/index.php b/lib/notes/index.php deleted file mode 100644 index 3089605..0000000 --- a/lib/notes/index.php +++ /dev/null @@ -1,21 +0,0 @@ - array ( - "nbNotes" => "number of notes", - "name" => "username", - ), - "way" => $ord_ways, -); -$fdefaults = array ( - "order" => "nbNotes", - "way" => "DESC", -); - -$users = array(); -$n = sql("SELECT account.id AS id, login AS name, COUNT(notes.id) AS nbNotes FROM account ". - "LEFT JOIN notes ON notes.owner = account.id ". - "WHERE notes.public != 0 AND notes.id != 0 ". - "GROUP BY account.id ORDER BY " . get_filter("order") . " " . get_filter("way")); -while ($nn = mysql_fetch_assoc($n)) $users[] = $nn; -require("tpl/notes/index.php"); diff --git a/lib/study/index.php b/lib/study/index.php index e6cec20..6b43d53 100644 --- a/lib/study/index.php +++ b/lib/study/index.php @@ -1,3 +1,7 @@ ' . filters_html_full() . ''; + +echo ""; +echo ""; +foreach($users as $u) { + echo ''; + echo ''; + if ($u['nbPosts'] > 0) { + echo ''; + } else { + echo ''; + } + echo ''; +} +echo "
UsernameNotebookBlog
' . $u['name'] . '' . $u['nbNotes'] . ' notes' . $u['nbPosts'] . ' postsno posts
"; + +require("tpl/general/bottom.php"); diff --git a/tpl/blog/drafts.php b/tpl/blog/drafts.php new file mode 100644 index 0000000..5440cbc --- /dev/null +++ b/tpl/blog/drafts.php @@ -0,0 +1,41 @@ +'; +echo 'post a message'; + +echo '

My drafts

'; + +if (count($drafts) > 0) { + foreach ($drafts as $post) { + echo '
'; + echo '
'; + echo 'edit'; + echo ' | delete'; + echo ' | publish'; + echo '
'; + echo '

' . $post['title'] . '

'; + echo $post['text_html']; + echo '
'; + } +} else { + echo '

No drafts

'; +} + +echo '

My published posts

'; + +if (count($pub) > 0) { + echo ''; + foreach ($pub as $post) { + echo ''; + echo ''; + } + echo '
TitleActions
' . $post['title'] . 'edit'; + echo ' | delete
'; +} else { + echo '

No published posts

'; +} + + +require("tpl/general/bottom.php"); diff --git a/tpl/blog/index.php b/tpl/blog/index.php new file mode 100644 index 0000000..07e3388 --- /dev/null +++ b/tpl/blog/index.php @@ -0,0 +1,53 @@ +'; + echo 'post a message'; + echo ' | my drafts'; + echo ''; +} + +echo ''; + +foreach ($posts as $post) { + echo '
'; + echo '
Written by ' . $post['owner']; + if ($can_edit && $post['owner_id'] == $user['id']) + echo ' | edit'; + if ($can_delete && $post['owner_id'] == $user['id']) + echo ' | delete'; + echo '
'; + echo '
published ' . $post['date'] . '
'; + if ($post['tags'] != '') { + echo '
tags: ' . $post['tags'] . '
'; + } + echo '

' . $post['title'] . '

'; + echo '
' . $post['text_html'] . '
'; + echo '
'; +} + +echo '
'; + +foreach ($fa as $kname => $kdata) { + echo '

Filter by ' . $kname . '

'; + if (isset($fvalues[$kname])) { + echo '

Filtering ' . $kname . ' : ' . $kdata[$fvalues[$kname]]['name'] . '.
'; + $n = array(); + foreach ($fvalues as $k => $v) { + if ($k != $kname) $n[] = "$k-$v"; + } + echo 'remove filtering

'; + } else { + echo ''; + } +} + +require("tpl/general/bottom.php"); diff --git a/tpl/general/top.php b/tpl/general/top.php index 2ddc84e..08481fd 100644 --- a/tpl/general/top.php +++ b/tpl/general/top.php @@ -29,16 +29,17 @@ if ($user['id'] == 0) { ?>
- Notebooks + Home + People Uploaded imagesMy studies'; + echo 'My studies'; + echo 'Uploaded images'; } else { + echo 'Studies'; if ($user['priv'] >= $apps['image']['upload']) { echo 'Upload image'; } - echo 'Study decks'; - echo 'Study lists'; } ?>
diff --git a/tpl/image/index.php b/tpl/image/index.php index 0f76abe..4f9db8e 100644 --- a/tpl/image/index.php +++ b/tpl/image/index.php @@ -1,20 +1,24 @@ Images you have uploaded'; - if (count($images) == 0) { echo '
You have uploaded no images yet.
'; } else { -echo ''; + echo '

You have uploaded ' . count($images) .' images.

'; + echo ''; + echo '
PreviewFiles
'; foreach ($images as $img) { $min = $baseurl . $img['id'] . "-min." . $img['extension']; $imgf = $baseurl . $img['id'] . "." . $img['extension']; - echo ''; - echo ''; + echo ''; + echo ''; + echo ''; } echo '
PreviewInfoDate
Miniature: ' . $min . '
'; - echo 'Image: ' . $imgf . ''; - if ($can_delete) echo '
Delete this image'; - echo '
' . $img['name'] . '

'; + echo 'Miniature: ' . $min . '
'; + echo 'Image: ' . $imgf . '
'; + echo 'Markdown: !['.$img['name'].']('.$imgf.')
' . $img['upl_date'] . '
'; + if ($can_delete) echo '
delete'; + if ($can_rename) echo '
rename'; + echo '
'; } @@ -25,7 +29,8 @@ if ($can_upload) {

Upload an image

-A px preview will be created.

+A px preview will be created.

+Title :

- Preview :
+

Preview :
Image :
+ Markdown code : ![]()

+

+

+ Back to upload form + = $apps['image']['index']) + echo ' - back to list of uploaded images'; + ?> +

"Image file : ", "type" => "file", "name" => "image") + array("label" => "Image file : ", "type" => "file", "name" => "image"), + array("label" => "Image title (optionnal) : ", "type" => "text", "name" => "name") ); $validate = "Upload"; diff --git a/tpl/notes/index.php b/tpl/notes/index.php deleted file mode 100644 index 6c0eb99..0000000 --- a/tpl/notes/index.php +++ /dev/null @@ -1,13 +0,0 @@ -' . filters_html_full() . '
'; - -echo ""; - -require("tpl/general/bottom.php"); diff --git a/tpl/study/index.php b/tpl/study/index.php index 82178df..287be11 100644 --- a/tpl/study/index.php +++ b/tpl/study/index.php @@ -11,7 +11,7 @@ require("tpl/general/top.php");

The first method is based on decks of cards, keeping track of your progress and everything.

-

Please take a look in the List of decks and start learning whatever you want to learn.

+

Please take a look at the list of decks and start learning whatever you want to learn.

The cards you are studying are classified in the following boxes :