From ac83bb750bbe3359904f8d3b0e90788c0064c304 Mon Sep 17 00:00:00 2001 From: Hendrik Date: Mon, 23 Jan 2017 16:05:22 +0100 Subject: [PATCH 001/140] fix status for enums, fix pages --- website/views/adminpanel.php | 64 ++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/website/views/adminpanel.php b/website/views/adminpanel.php index e53d679..834f54f 100644 --- a/website/views/adminpanel.php +++ b/website/views/adminpanel.php @@ -85,37 +85,37 @@ $listm = $currentpage * $perpage;

Show:

- > + >
- > + >
- > + >
- > + >
- > + >
- > + >

Show:

- > + >
- > + >
- > + >
@@ -138,11 +138,11 @@ $listm = $currentpage * $perpage; id="admin-batchform" action="" method="post"> - +
- +
- +

@@ -154,11 +154,11 @@ $listm = $currentpage * $perpage; id="admin-groupbatchform" action="" method="post"> - +
- +
- +

@@ -225,7 +225,7 @@ $listm = $currentpage * $perpage; $listm = $currentpage * $perpage; if ($pagetype == 'user') { - $q = searchSomeUsersByStatus($listn, $listm, $search, $status); + $q = searchSomeUsersByStatus($listn, $perpage, $search, $status); while($user = $q->fetch(PDO::FETCH_ASSOC)) { $userID = $user['userID']; @@ -252,9 +252,9 @@ $listm = $currentpage * $perpage; action='$thispage' method='post'> @@ -264,7 +264,7 @@ $listm = $currentpage * $perpage; "); } } else { - $q = searchSomeGroupsByStatus($listn, $listm, $search, $groupstatus); + $q = searchSomeGroupsByStatus($listn, $perpage, $search, $groupstatus); while ($group = $q->fetch(PDO::FETCH_ASSOC)) { $groupID = $group['groupID']; @@ -291,9 +291,9 @@ $listm = $currentpage * $perpage; action='$thispage' method='post'> -- 2.49.1 From 1a53d01747efff5f90c995f91e2b226ffea7fe23 Mon Sep 17 00:00:00 2001 From: Hendrik Date: Thu, 26 Jan 2017 13:29:56 +0100 Subject: [PATCH 002/140] add authentication --- website/public/admin.php | 8 ++++++++ website/queries/user.php | 15 +++++++++++++++ website/views/adminpanel.php | 1 + 3 files changed, 24 insertions(+) diff --git a/website/public/admin.php b/website/public/admin.php index 5faa096..fcd386a 100644 --- a/website/public/admin.php +++ b/website/public/admin.php @@ -12,6 +12,14 @@ * This view adds the main layout over the screen. * Header and menu. */ +include_once ("../queries/user.php"); + +$userinfo = getRoleByID($_SESSION['userID'])->fetch(PDO::FETCH_ASSOC); + +if ($userinfo['role'] != 'admin' AND $userinfo['role'] != 'owner') { + header("location:profile.php"); +} + include("../views/main.php"); /* Add your view files here. */ diff --git a/website/queries/user.php b/website/queries/user.php index be06197..104d526 100644 --- a/website/queries/user.php +++ b/website/queries/user.php @@ -370,3 +370,18 @@ function countSomeUsers($search) { $q->execute(); return $q; } + +function getRoleByID($userID) { + $stmt = $GLOBALS['db']->prepare(" + SELECT + `role` + FROM + `user` + WHERE + `userID` = :userID + "); + + $stmt->bindParam(':userID', $userID); + $stmt->execute(); + return $stmt; +} \ No newline at end of file diff --git a/website/views/adminpanel.php b/website/views/adminpanel.php index 86fbb36..fd10d15 100644 --- a/website/views/adminpanel.php +++ b/website/views/adminpanel.php @@ -2,6 +2,7 @@ Date: Thu, 26 Jan 2017 14:31:45 +0100 Subject: [PATCH 003/140] Fixed post titles for htmlchars. --- website/public/js/masonry.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/public/js/masonry.js b/website/public/js/masonry.js index 0b31443..6b91e4b 100644 --- a/website/public/js/masonry.js +++ b/website/public/js/masonry.js @@ -100,7 +100,7 @@ function masonry(mode) { */ jQuery.each(posts, function() { $post = $("
"); - $post.append($("

").text(this["title"])); + $post.append($("

").html(this["title"])); $post.append($("

").html(this["content"])); $post.append($("

").text(this["nicetime"])); -- 2.49.1 From ee204d78a7e35adb43ab0a956cc71350b58b27a6 Mon Sep 17 00:00:00 2001 From: Hendrik Date: Thu, 26 Jan 2017 15:32:38 +0100 Subject: [PATCH 004/140] minor fixes --- website/public/API/postComment.php | 2 +- website/public/styles/post-popup.css | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/website/public/API/postComment.php b/website/public/API/postComment.php index b840e0b..5fd48b5 100644 --- a/website/public/API/postComment.php +++ b/website/public/API/postComment.php @@ -8,7 +8,7 @@ require("../../queries/checkInput.php"); if (empty($_POST['newcomment-content'])) { echo 0; } else { - if(makeComment($_POST['postID'], + if(makeComment(test_input($_POST['postID']), $_SESSION['userID'], test_input($_POST['newcomment-content']))) { echo 1; diff --git a/website/public/styles/post-popup.css b/website/public/styles/post-popup.css index 11fe03b..c205c09 100644 --- a/website/public/styles/post-popup.css +++ b/website/public/styles/post-popup.css @@ -14,7 +14,7 @@ /* Modal Content/Box */ .modal-content { - margin: 5% auto; + margin: 50px auto; width: 70%; /* Could be more or less, depending on screen size */ overflow-y: auto; } -- 2.49.1 From 59fc65e27af9a388497dbdfb067f5dd7055c46d0 Mon Sep 17 00:00:00 2001 From: "K. Nobel" Date: Thu, 26 Jan 2017 16:09:18 +0100 Subject: [PATCH 005/140] Made small changes to posts, added amount of comments and niet slechts --- website/public/js/masonry.js | 7 +++---- website/queries/user.php | 30 +++++++++++++++++++++--------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/website/public/js/masonry.js b/website/public/js/masonry.js index f30139c..f30f0af 100644 --- a/website/public/js/masonry.js +++ b/website/public/js/masonry.js @@ -70,9 +70,7 @@ function masonry(mode) { $form.append($("")); columns[0][1].append($postInput); - $postInput.on("load", function() { - columns[0][0] = $postInput.height() + margin; - }); + columns[0][0] = $postInput.height() + margin; } /* @@ -99,11 +97,12 @@ function masonry(mode) { /* * Rearange the objects. */ - jQuery.each(posts, function() { + $.each(posts, function() { $post = $("

"); $post.append($("

").html(this["title"])); $post.append($("

").html(this["content"])); $post.append($("

").text(this["nicetime"])); + $post.append($("

").text("comments: " + this["comments"] + ", niet slechts: " + this["niet_slechts"])); shortestColumn = getShortestColumn(columns); shortestColumn[1].append($post); diff --git a/website/queries/user.php b/website/queries/user.php index 4a7ee57..9c23721 100644 --- a/website/queries/user.php +++ b/website/queries/user.php @@ -105,24 +105,36 @@ function selectAllUserGroups($userID) { function selectAllUserPosts($userID) { $stmt = $GLOBALS["db"]->prepare(" SELECT - `postID`, - `author`, + `post`.`postID`, + `post`.`author`, `title`, - CASE LENGTH(`content`) >= 150 AND `content` NOT LIKE '= 150 AND `post`.`content` NOT LIKE 'bindParam(':userID', $userID, PDO::PARAM_INT); -- 2.49.1 From 7e2c20e2447a10fd449bc718e4b735bf5b589559 Mon Sep 17 00:00:00 2001 From: Marijn Jansen Date: Fri, 27 Jan 2017 15:40:07 +0100 Subject: [PATCH 006/140] Added showEmail and showBday to the settings page --- website/queries/settings.php | 49 ++++++++++++++++++++++++++++----- website/views/settings-view.php | 26 +++++++++++++++++ 2 files changed, 68 insertions(+), 7 deletions(-) diff --git a/website/queries/settings.php b/website/queries/settings.php index 0bf8791..05e7fbf 100644 --- a/website/queries/settings.php +++ b/website/queries/settings.php @@ -1,6 +1,10 @@ fetch(); } +/** + * Gets the passwordHas form the database + * @return mixed passwordhash + */ function getPasswordHash() { $stmt = $GLOBALS["db"]->prepare(" SELECT @@ -73,6 +91,10 @@ function getPasswordHash() { return $stmt->fetch(); } +/** + * Changes the setting from post. + * @throws HappyAlert + */ function updateSettings() { $stmt = $GLOBALS["db"]->prepare(" UPDATE @@ -82,7 +104,9 @@ function updateSettings() { `lname` = :lname, `location` = :location, `birthdate` = :bday, - `bio` = :bio + `bio` = :bio, + `showEmail` = :showEmail, + `showBday` = :showBday WHERE `userID` = :userID "); @@ -92,15 +116,22 @@ function updateSettings() { $stmt->bindValue(":location", test_input($_POST["location"])); $stmt->bindValue(":bday", test_input($_POST["bday"])); $stmt->bindValue(":bio", test_input($_POST["bio"])); + $stmt->bindValue(":showEmail", test_input($_POST["showEmail"])); + $stmt->bindValue(":showBday", test_input($_POST["showBday"])); + $stmt->bindValue(":userID", $_SESSION["userID"]); $stmt->execute(); throw new HappyAlert("Instellingen zijn opgeslagen."); } +/** + * Change + * @throws AngryAlert + */ function changePassword() { $user = getPasswordHash(); - if (password_verify($_POST["password-old"], $user["password"])) { - if ($_POST["password-new"] == $_POST["password-confirm"] && (strlen($_POST["password-new"]) >= 8)) { + if (password_verify($_POST["password-old"], test_input($user["password"]))) { + if (test_input($_POST["password-new"]) == test_input($_POST["password-confirm"]) && (strlen(test_input($_POST["password-new"])) >= 8)) { doChangePassword(); } else { throw new AngryAlert("Wachtwoorden komen niet overeen."); @@ -110,6 +141,10 @@ function changePassword() { } } +/** + * @throws AngryAlert + * @throws HappyAlert + */ function doChangePassword() { $stmt = $GLOBALS["db"]->prepare(" UPDATE @@ -134,8 +169,8 @@ function doChangePassword() { function changeEmail() { - if ($_POST["email"] == $_POST["email-confirm"]) { - $email = strtolower($_POST["email"]); + if (test_input($_POST["email"]) == test_input($_POST["email-confirm"])) { + $email = strtolower(test_input($_POST["email"])); if (filter_var($email, FILTER_VALIDATE_EMAIL)) { //check if email exists emailIsAvailableInDatabase($email); @@ -193,7 +228,6 @@ function updateAvatar() { $tmpImg = $_FILES["pp"]["tmp_name"]; checkAvatarSize($tmpImg); - removeOldAvatar(); if (getimagesize($tmpImg)["mime"] == "image/gif") { if ($_FILES["pp"]["size"] > 4000000) { throw new AngryAlert("Bestand is te groot, maximaal 4MB toegestaan."); @@ -205,6 +239,7 @@ function updateAvatar() { $scaledImg = scaleAvatar($tmpImg); imagepng($scaledImg, $profilePictureDir . $relativePath); } + removeOldAvatar(); setAvatarToDatabase("../" . $relativePath); throw new HappyAlert("Profielfoto veranderd."); } diff --git a/website/views/settings-view.php b/website/views/settings-view.php index 66513fc..b6a3b4c 100644 --- a/website/views/settings-view.php +++ b/website/views/settings-view.php @@ -51,6 +51,32 @@ $settings = getSettings(); value="" > +

  • + + + > Ja + + > Nee +
  • +
  • + + + > Ja + + > Nee +

  • - - -- 2.49.1 From 9a36dea59219f037eb266412fd090d1b950a1f1b Mon Sep 17 00:00:00 2001 From: Marijn Jansen Date: Mon, 30 Jan 2017 13:22:44 +0100 Subject: [PATCH 018/140] Removed a comma --- website/views/post-view.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/views/post-view.php b/website/views/post-view.php index 81aca46..264d67c 100644 --- a/website/views/post-view.php +++ b/website/views/post-view.php @@ -50,7 +50,7 @@ echo("
    $commentauthor - + $commentnicetime
    -- 2.49.1 From 54ddb784531c5dc8ae57cba6bf8cc6cf2416bc4f Mon Sep 17 00:00:00 2001 From: Lars van Hijfte Date: Mon, 30 Jan 2017 13:59:02 +0100 Subject: [PATCH 019/140] Chat receive messages is now better --- website/public/js/chat.js | 36 +++++++++++++++++++------------ website/public/styles/main.css | 1 - website/public/styles/profile.css | 3 --- website/queries/friendship.php | 6 ++++++ website/views/menu.php | 2 +- 5 files changed, 29 insertions(+), 19 deletions(-) diff --git a/website/public/js/chat.js b/website/public/js/chat.js index 773a819..0f32fa6 100644 --- a/website/public/js/chat.js +++ b/website/public/js/chat.js @@ -1,25 +1,30 @@ var previousDate = new Date("1970-01-01 00:00:00"); +var gettingMessages = false; + $(document).ready(function() { - loadMessages(); + setInterval(loadMessages, 2000); sayEmpty(); $(".chat-field").hide(); }); function loadMessages() { - $.post( - "API/loadMessages.php", - $("#lastIDForm").serialize() - ).done(function(data) { - if (data && data != "[]") { - messages = JSON.parse(data); - addMessages(messages); - $("#lastID").val(messages[messages.length - 1].messageID); - $("#chat-history").scrollTop($("#chat-history")[0].scrollHeight); - } - }); - - setTimeout(loadMessages, 1000); + if (!gettingMessages) { + gettingMessages = true; + $.post( + "API/loadMessages.php", + $("#lastIDForm").serialize() + ).done(function (data) { + if (data && data != "[]") { + messages = JSON.parse(data); + addMessages(messages); + $("#lastID").val(messages[messages.length - 1].messageID); + } + gettingMessages = false; + }); + } else { + setTimeout(loadMessages, 500); + } } @@ -30,6 +35,7 @@ function sendMessage() { ); $("#newContent").val(""); + loadMessages(); } function addMessages(messages) { @@ -59,6 +65,8 @@ function addMessages(messages) {
    \ '); } + + $("#chat-history").scrollTop($("#chat-history")[0].scrollHeight); } function switchUser(userID) { diff --git a/website/public/styles/main.css b/website/public/styles/main.css index be2f4f7..3eb0bb3 100644 --- a/website/public/styles/main.css +++ b/website/public/styles/main.css @@ -97,7 +97,6 @@ p { } .item-box, .item-box-full-width { - margin: 20px 0 0 0; padding: 25px; background-color: #FFFFFF; } diff --git a/website/public/styles/profile.css b/website/public/styles/profile.css index 2fe819a..03ab19f 100644 --- a/website/public/styles/profile.css +++ b/website/public/styles/profile.css @@ -2,7 +2,6 @@ .user-box { text-align: center; - margin-bottom: 50px; } .status-buttons-container { @@ -64,14 +63,12 @@ } div.posts { - padding-top: 20px; width: calc(100% + 20px); display: inline-flex; } div.posts div.post { display: block; - margin: 20px 0 0 0; padding: 10px; width: calc(100% - 40px); cursor: pointer; diff --git a/website/queries/friendship.php b/website/queries/friendship.php index a1a23d8..01e3d8a 100644 --- a/website/queries/friendship.php +++ b/website/queries/friendship.php @@ -29,6 +29,12 @@ function selectLimitedFriends($userID, $limit) { `friendship`.`user1ID` = `user`.`userID`) AND `user`.`role` != 'banned' AND `friendship`.`status` = 'confirmed' + ORDER BY + CASE + WHEN `friendship`.`user2ID` = `user`.`userID` THEN `friendship`.`chatLastVisted1` + WHEN `friendship`.`user1ID` = `user`.`userID` THEN `friendship`.`chatLastVisted2` + END + DESC LIMIT :limitCount "); diff --git a/website/views/menu.php b/website/views/menu.php index 0444384..f3f3cde 100644 --- a/website/views/menu.php +++ b/website/views/menu.php @@ -1,7 +1,7 @@
  • "); \ No newline at end of file diff --git a/website/public/img/zelda.png b/website/public/img/zelda.png new file mode 100644 index 0000000000000000000000000000000000000000..0c1580a80256fdfe87e07b3769a4ee9fa52d4c3b GIT binary patch literal 150915 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 O0000

    - +
    $content
    -- 2.49.1 From f1b5a7fe95531d2f18b7f6443d13be718ead232e Mon Sep 17 00:00:00 2001 From: Marijn Jansen Date: Mon, 30 Jan 2017 14:33:38 +0100 Subject: [PATCH 022/140] Resize --- website/public/error/404.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/public/error/404.php b/website/public/error/404.php index 673fbc0..15ad06b 100644 --- a/website/public/error/404.php +++ b/website/public/error/404.php @@ -4,6 +4,6 @@ require_once "../../views/messagepage.php"; messagePage("

    404

    -

    Wrong link...


    - +

    Verkeerde link...


    +
    "); \ No newline at end of file -- 2.49.1 From 282875c6a2e574bb58dcfd9cf579f32ba043b204 Mon Sep 17 00:00:00 2001 From: Marijn Jansen Date: Mon, 30 Jan 2017 14:35:25 +0100 Subject: [PATCH 023/140] Redirect to index --- website/views/messagepage.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/views/messagepage.php b/website/views/messagepage.php index 70268b9..e6c3fb8 100644 --- a/website/views/messagepage.php +++ b/website/views/messagepage.php @@ -12,7 +12,7 @@ function messagePage(string $content) {
    - +
    $content
    -- 2.49.1 From 44ff3a4cabc81a06fe6ab49b29fc40d1a24bea64 Mon Sep 17 00:00:00 2001 From: Lars van Hijfte Date: Mon, 30 Jan 2017 15:08:07 +0100 Subject: [PATCH 024/140] added time to chat messages --- website/public/js/chat.js | 56 ++++++++++++++++++++++------------ website/public/styles/chat.css | 10 ++++++ 2 files changed, 47 insertions(+), 19 deletions(-) diff --git a/website/public/js/chat.js b/website/public/js/chat.js index 5566d15..014d723 100644 --- a/website/public/js/chat.js +++ b/website/public/js/chat.js @@ -1,6 +1,7 @@ var previousDate = new Date("1970-01-01 00:00:00"); +var previousTime = "00:00"; var gettingMessages = false; - +var previousType = "robot"; $(document).ready(function() { setInterval(loadMessages, 1000); @@ -39,34 +40,51 @@ function sendMessage() { } function addMessages(messages) { + var messagesText = ""; for(var i in messages) { - thisDate = new Date(messages[i].creationdate); + // Initialize message variables + var thisDate = new Date(messages[i].creationdate); + var thisTime = thisDate.getHours() + ":" + thisDate.getMinutes(); + var type; thisDate.setHours(0,0,0,0); + if (messages[i].destination == $(".destinationID").val()) { type = "chat-message-self"; } else { type = "chat-message-other"; } - if (thisDate > previousDate) { + if (i == 0) { + messagesText += '
    '; + } else if (type != previousType || thisTime != previousTime || thisDate > previousDate) { + messagesText += '
    \ + ' + thisTime + '\ +
    '; + previousDate = thisDate; - $("#chat-history").append('\ -
    \ -
    \ - ' + days[thisDate.getDay()] + " " + thisDate.getDate() + " " + months[thisDate.getMonth()] + " " + thisDate.getFullYear() + '\ -
    \ -
    \ - '); + previousTime = thisTime; + previousType = type; + if (thisDate > previousDate) { + messagesText += '\ +
    \ +
    \ + ' + days[thisDate.getDay()] + " " + thisDate.getDate() + " " + months[thisDate.getMonth()] + " " + thisDate.getFullYear() + '\ +
    \ +
    '; + } + + messagesText += '
    '; } - $("#chat-history").append('\ -
    \ -
    \ - ' + fancyText(messages[i].content) + '\ -
    \ -
    \ - '); + messagesText += fancyText(messages[i].content) + "
    "; } - $("#chat-history").scrollTop($("#chat-history")[0].scrollHeight); + // Close the last message + messagesText += '
    \ + ' + thisTime + '\ +
    '; + + $("#chat-history").append(messagesText); + + $("#chat-history").scrollTop($("#chat-history")[0].scrollHeight - $('#chat-history')[0].clientHeight); } function switchUser(userID) { @@ -80,5 +98,5 @@ function switchUser(userID) { } function sayEmpty() { - $("#chat-history").html("Begin nu met chatten!"); + $("#chat-history").html("Probeer ook eens foto's en video's te sturen"); } \ No newline at end of file diff --git a/website/public/styles/chat.css b/website/public/styles/chat.css index 75a4a6d..47b0639 100644 --- a/website/public/styles/chat.css +++ b/website/public/styles/chat.css @@ -134,4 +134,14 @@ body { .chat-message a { text-decoration: underline; +} + +.chat-time { + color: #666666; + font-size: 12px; + margin-bottom: -3px; +} + +.chat-message-other .chat-time { + text-align: right; } \ No newline at end of file -- 2.49.1 From 1acad8e7654004d840fa6f76fedf214a90cba0e5 Mon Sep 17 00:00:00 2001 From: "K. Nobel" Date: Mon, 30 Jan 2017 15:28:54 +0100 Subject: [PATCH 025/140] modified masonry and posts, masonry is now reusable on group pages. --- website/public/API/getPosts.php | 12 +++-- website/public/API/postComment.php | 2 +- website/public/js/masonry.js | 2 +- website/public/js/post.js | 4 +- website/queries/group_page.php | 3 +- website/queries/post.php | 46 +++++++++++++++++ website/queries/user.php | 82 +++++++++++++++--------------- 7 files changed, 101 insertions(+), 50 deletions(-) diff --git a/website/public/API/getPosts.php b/website/public/API/getPosts.php index eef8261..620a707 100644 --- a/website/public/API/getPosts.php +++ b/website/public/API/getPosts.php @@ -1,13 +1,17 @@ = 150 AND `post`.`content` NOT LIKE 'bindParam(':userID', $userID, PDO::PARAM_INT); + $stmt->bindParam(':groupID', $groupID , PDO::PARAM_INT); + if(!$stmt->execute()) { + return False; + } + return $stmt; + +} + function selectPostById($postID) { $stmt = prepareQuery(" SELECT diff --git a/website/queries/user.php b/website/queries/user.php index ec211c0..e3bf758 100644 --- a/website/queries/user.php +++ b/website/queries/user.php @@ -103,47 +103,47 @@ function selectAllUserGroups($userID) { return $stmt; } -function selectAllUserPosts($userID) { - $stmt = prepareQuery(" - SELECT - `post`.`postID`, - `post`.`author`, - `title`, - CASE LENGTH(`post`.`content`) >= 150 AND `post`.`content` NOT LIKE 'bindParam(':userID', $userID, PDO::PARAM_INT); - if(!$stmt->execute()) { - return False; - } - return $stmt; -} +//function selectAllUserPosts($userID) { +// $stmt = prepareQuery(" +// SELECT +// `post`.`postID`, +// `post`.`author`, +// `title`, +// CASE LENGTH(`post`.`content`) >= 150 AND `post`.`content` NOT LIKE 'bindParam(':userID', $userID, PDO::PARAM_INT); +// if(!$stmt->execute()) { +// return False; +// } +// return $stmt; +//} function select20UsersFromN($n) { $q = prepareQuery(" -- 2.49.1 From aa12e29948a4ae79922c274cfdc489cc9b65b350 Mon Sep 17 00:00:00 2001 From: "K. Nobel" Date: Mon, 30 Jan 2017 15:29:42 +0100 Subject: [PATCH 026/140] Fixed posts on profile page. --- website/public/profile.php | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/website/public/profile.php b/website/public/profile.php index 95c5b86..83b9d10 100644 --- a/website/public/profile.php +++ b/website/public/profile.php @@ -27,7 +27,6 @@ if(empty($_GET["username"])) { $user = selectUser($_SESSION["userID"], $userID); $profile_friends = selectAllFriends($userID); $profile_groups = selectAllUserGroups($userID); -$posts = selectAllUserPosts($userID); if ($userID == $_SESSION["userID"]) { @@ -54,23 +53,12 @@ include("../views/footer.php"); -- 2.49.1 From 941296802f9d744059264101b403b98d6f337fcb Mon Sep 17 00:00:00 2001 From: "K. Nobel" Date: Mon, 30 Jan 2017 15:30:08 +0100 Subject: [PATCH 027/140] Added posts to group page. --- website/public/group.php | 16 ++++++++ website/views/group.php | 88 ++++++---------------------------------- 2 files changed, 28 insertions(+), 76 deletions(-) diff --git a/website/public/group.php b/website/public/group.php index fa45090..2ef3493 100644 --- a/website/public/group.php +++ b/website/public/group.php @@ -4,6 +4,8 @@ @@ -30,6 +32,20 @@ include("../views/group.php"); /* This adds the footer. */ include("../views/footer.php"); + +$masonry_mode = 0; ?> + + + + + diff --git a/website/views/group.php b/website/views/group.php index b2098c7..24cf9d5 100644 --- a/website/views/group.php +++ b/website/views/group.php @@ -13,88 +13,24 @@

    \"""; + echo "\"""; } ?>

    -
    -

    Lorem

    -

    Lorem ipsum dolor sit amet, consectetur.

    -

    Enkele minuten geleden geplaatst

    -
    -
    -

    Image

    - Olympic Mountains, Washington -

    Gisteren geplaatst

    -
    -
    -

    Ipsum

    -

    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rem nihil alias amet dolores fuga totam sequi a cupiditate ipsa voluptas id facilis nobis.

    -

    Maandag geplaatst

    -
    -
    -

    Dolor

    -

    Lorem ipsum dolor sit amet, consectetur adipisicing elit.

    -

    4 Januari geplaatst

    -
    -
    -

    Sit

    -

    Lorem ipsum dolor sit.

    -

    4 Januari geplaatst

    -
    -
    -

    Image

    - Nunobiki Falls, Kobe Japan -

    4 Januari geplaatst

    -
    -
    -

    Amet

    -

    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minima asperiores eveniet vero velit eligendi aliquid in.

    -

    4 Januari geplaatst

    -
    -
    -

    Consectetur

    -

    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Error aliquid reprehenderit expedita odio beatae est.

    -

    4 Januari geplaatst

    -
    -
    -

    Adipisicing

    -

    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat architecto quis tenetur fugiat veniam iste molestiae fuga labore!

    -

    4 Januari geplaatst

    -
    -
    -

    Elit

    -

    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rem ut debitis dolorum earum expedita eveniet voluptatem quibusdam facere eos numquam commodi ad iusto laboriosam rerum aliquam.

    -

    4 Januari geplaatst

    -
    -
    -

    Geen error

    -

    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Doloribus dolorem maxime minima animi cum.

    -

    4 Januari geplaatst

    -
    -
    -

    Image

    - Oregon cliffs are no joke. -

    4 Januari geplaatst

    -
    -
    -

    Aliquid

    -

    Lorem ipsum dolor sit amet, consectetur.

    -

    4 Januari geplaatst

    -
    -
    -

    Odit

    -

    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Odit accusamus tempore at porro officia rerum est impedit ea ipsa tenetur. Labore libero hic error sunt laborum expedita.

    -

    4 Januari geplaatst

    -
    -
    -

    Accusamus

    -

    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nobis quaerat suscipit ad.

    -

    4 Januari geplaatst

    -
    +
    + \ No newline at end of file -- 2.49.1 From 183a98a339c1f5011ed1e666a46fabbb01d49f4f Mon Sep 17 00:00:00 2001 From: "K. Nobel" Date: Mon, 30 Jan 2017 15:34:32 +0100 Subject: [PATCH 028/140] Fixed link to groups on profile page. --- website/views/profile.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/views/profile.php b/website/views/profile.php index bd009e3..036cab4 100644 --- a/website/views/profile.php +++ b/website/views/profile.php @@ -38,7 +38,7 @@

    fetch()) { - echo "${group["name"]}s logo"; + echo "${group["name"]}s logo"; } if($profile_groups->rowCount() === 0) { -- 2.49.1 From b0a8ceafc35c10d3fc23ef6f071ac7a34e919fce Mon Sep 17 00:00:00 2001 From: Lars van Hijfte Date: Mon, 30 Jan 2017 15:40:31 +0100 Subject: [PATCH 029/140] Added youtube links --- website/public/js/main.js | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/website/public/js/main.js b/website/public/js/main.js index 07a0cb8..d23bbbf 100644 --- a/website/public/js/main.js +++ b/website/public/js/main.js @@ -2,22 +2,35 @@ var days = ["zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", var months = ["januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december"] function fancyText(text) { - // Add images and gifs. + // Add links, images, gifs and (youtube) video's. var regex = /(https?:\/\/.[^ ]*)/ig; text = text.replace(regex, function(link) { + // Add images if (link.match(/(https?:\/\/.[^ ]*\.(?:png|jpg|jpeg|gif))/ig)) { return "" + link + ""; - } else if (link.match(/(https?:\/\/.[^ ]*\.(?:mp4))/ig)) { + } + // Add mp4 video's + else if (link.match(/(https?:\/\/.[^ ]*\.(?:mp4))/ig)) { return ""; - } else if (link.match(/(https?:\/\/.[^ ]*\.(?:ogg))/ig)) { + ""; + } + // Add ogg video's + else if (link.match(/(https?:\/\/.[^ ]*\.(?:ogg))/ig)) { return ""; - } else { + } + // Add youtube video's + else if (link.match(/(https?:\/\/.(www.)?youtube|youtu.be)*watch/ig)) { + return ''; + } + // Add links + else { return "" + link + ""; } }); -- 2.49.1 From 0b6ca72dfc3bf87e098008125cfacfa9677b618c Mon Sep 17 00:00:00 2001 From: Lars van Hijfte Date: Mon, 30 Jan 2017 16:00:16 +0100 Subject: [PATCH 030/140] Fixed chat date not showing --- website/public/js/chat.js | 11 ++++++++++- website/public/styles/chat.css | 6 ++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/website/public/js/chat.js b/website/public/js/chat.js index 014d723..e35f85c 100644 --- a/website/public/js/chat.js +++ b/website/public/js/chat.js @@ -54,16 +54,25 @@ function addMessages(messages) { type = "chat-message-other"; } if (i == 0) { + if (thisDate > previousDate) { + previousDate = thisDate; + messagesText += '\ +

    \ +
    \ + ' + days[thisDate.getDay()] + " " + thisDate.getDate() + " " + months[thisDate.getMonth()] + " " + thisDate.getFullYear() + '\ +
    \ +
    '; + } messagesText += '
    '; } else if (type != previousType || thisTime != previousTime || thisDate > previousDate) { messagesText += '
    \ ' + thisTime + '\
    '; - previousDate = thisDate; previousTime = thisTime; previousType = type; if (thisDate > previousDate) { + previousDate = thisDate; messagesText += '\
    \
    \ diff --git a/website/public/styles/chat.css b/website/public/styles/chat.css index 47b0639..85eb219 100644 --- a/website/public/styles/chat.css +++ b/website/public/styles/chat.css @@ -144,4 +144,10 @@ body { .chat-message-other .chat-time { text-align: right; +} + +@media only screen and (max-width: 1200px) { + .chat-message-self, .chat-message-other { + max-width: 75%; + } } \ No newline at end of file -- 2.49.1 From 3140242b4fa4a9c9116c25504f21c30ecea861fa Mon Sep 17 00:00:00 2001 From: "K. Nobel" Date: Mon, 30 Jan 2017 16:24:07 +0100 Subject: [PATCH 031/140] Removed old query for posts. --- website/queries/user.php | 42 ---------------------------------------- 1 file changed, 42 deletions(-) diff --git a/website/queries/user.php b/website/queries/user.php index e3bf758..afd92b5 100644 --- a/website/queries/user.php +++ b/website/queries/user.php @@ -103,48 +103,6 @@ function selectAllUserGroups($userID) { return $stmt; } -//function selectAllUserPosts($userID) { -// $stmt = prepareQuery(" -// SELECT -// `post`.`postID`, -// `post`.`author`, -// `title`, -// CASE LENGTH(`post`.`content`) >= 150 AND `post`.`content` NOT LIKE 'bindParam(':userID', $userID, PDO::PARAM_INT); -// if(!$stmt->execute()) { -// return False; -// } -// return $stmt; -//} - function select20UsersFromN($n) { $q = prepareQuery(" SELECT -- 2.49.1 From e464f5bca2535a1d80df8a535f318cc1c6329c21 Mon Sep 17 00:00:00 2001 From: Hendrik Date: Mon, 30 Jan 2017 16:32:57 +0100 Subject: [PATCH 032/140] cleaned admin.js, add admin/owner check (frontend), fix submit ajax --- website/public/API/adminChangeUser.php | 3 -- website/public/API/adminSearchUsers.php | 2 + website/public/admin.php | 2 +- website/public/js/admin.js | 56 ++++++++++++++++--------- website/public/styles/adminpanel.css | 2 +- website/views/adminpanel-grouptable.php | 6 +-- website/views/adminpanel-table.php | 28 ++++++++----- website/views/adminpanel.php | 27 ++++++++---- 8 files changed, 79 insertions(+), 47 deletions(-) diff --git a/website/public/API/adminChangeUser.php b/website/public/API/adminChangeUser.php index 067a7ba..5c9384c 100644 --- a/website/public/API/adminChangeUser.php +++ b/website/public/API/adminChangeUser.php @@ -15,6 +15,3 @@ if (isset($_POST["actions"]) && isset($_POST["userID"])) { } else if (isset($_POST["groupbatchactions"]) && isset($_POST["checkbox-group"])) { changeMultipleGroupStatusByID($_POST["checkbox-group"], $_POST["groupbatchactions"]); } - -//header("location: ../admin.php"); -print_r($_POST); \ No newline at end of file diff --git a/website/public/API/adminSearchUsers.php b/website/public/API/adminSearchUsers.php index c809db7..f1d7fc1 100644 --- a/website/public/API/adminSearchUsers.php +++ b/website/public/API/adminSearchUsers.php @@ -35,6 +35,8 @@ if (isset($_POST['groupstatus'])) { $groupstatus = $_POST["groupstatus"]; } +$userinfo = getRoleByID($_SESSION['userID'])->fetch(PDO::FETCH_ASSOC); + if ($pagetype == "user") { include ("../../views/adminpanel-table.php"); } else if ($pagetype == "group") { diff --git a/website/public/admin.php b/website/public/admin.php index 2785606..13a025d 100644 --- a/website/public/admin.php +++ b/website/public/admin.php @@ -8,7 +8,7 @@ - + input, label").click(function(){ + $("#admin-filter, #admin-groupfilter > input, label").change(function(){ adminSearch(); }); $("#pagetype").change(function(){ adminSearch(); }); + /* Update hidden input to be equal to submit pressed, + because serialize doesn't take submit values. */ + $('#admin-batchform > button').click(function () { + $('#batchinput').prop('value', $(this).prop('value')); + console.log($('#batchinput').prop('value')); + }); + + $('#admin-groupbatchform > button').click(function () { + $('#groupbatchinput').prop('value', $(this).prop('value')); + console.log($('#batchinput').prop('value')); + }); + adminSearch(); }); -function checkAll(allbox) { - var checkboxes = document.getElementsByClassName('checkbox-list'); - - for (var i = 0; i < checkboxes.length; i++) { - if (checkboxes[i].type == 'checkbox') { - checkboxes[i].checked = allbox.checked; - } - } +function checkAll() { + $('.checkbox-list').each(function () { + $(this).prop('checked', $('#checkall').prop('checked')); + }); } -function checkCheckAll(allbox) { - var checkboxes = document.getElementsByClassName('checkbox-list'); +function checkCheckAll() { var checked = true; - for (var i = 0; i < checkboxes.length; i++) { - if (checkboxes[i].type == 'checkbox') { - if (checkboxes[i].checked == false) { - checked = false; - break; - } + $('.checkbox-list').each(function () { + if ($(this).prop('checked') == false) { + checked = false; + return; } - } - allbox.checked = checked; + }); + + $('#checkall').prop('checked', checked); } function changeFilter() { @@ -60,11 +66,21 @@ function adminSearch() { "API/adminSearchUsers.php", $("#admin-searchform").serialize() ).done(function (data) { - console.log(data); + // console.log(data); $("#usertable").html(data); }) } +function adminUpdate(form) { + console.log($(form).serialize()); + $.post( + "API/adminChangeUser.php", + $(form).serialize() + ).done(function () { + adminSearch(); + }) +} + function updatePageN() { $.post( "API/adminPageNumber.php", diff --git a/website/public/styles/adminpanel.css b/website/public/styles/adminpanel.css index f9410e1..75fa8b1 100644 --- a/website/public/styles/adminpanel.css +++ b/website/public/styles/adminpanel.css @@ -44,7 +44,7 @@ padding: 3px; } -.usertable tr { +.usertable th, tr { text-align: left; } diff --git a/website/views/adminpanel-grouptable.php b/website/views/adminpanel-grouptable.php index 4999666..9d2c8e8 100644 --- a/website/views/adminpanel-grouptable.php +++ b/website/views/adminpanel-grouptable.php @@ -16,7 +16,6 @@ while ($group = $q->fetch(PDO::FETCH_ASSOC)) { $name = $group['name']; $role = $group['status']; $description = $group['description']; - $function = "checkCheckAll(document.getElementById('checkall'))"; echo(" @@ -25,15 +24,14 @@ while ($group = $q->fetch(PDO::FETCH_ASSOC)) { class='checkbox-list' value='$groupID' form='admin-groupbatchform' - onchange='$function'> + onchange='checkCheckAll();'> $name $role $description
    + onsubmit=\"adminUpdate(this); return false;\"> + Gebruikersnaam Status Aantekening @@ -14,7 +14,6 @@ while($user = $q->fetch(PDO::FETCH_ASSOC)) { $username = $user['username']; $role = $user['role']; $bancomment = $user['bancomment']; - $function = "checkCheckAll(document.getElementById('checkall'))"; echo(" @@ -24,20 +23,29 @@ while($user = $q->fetch(PDO::FETCH_ASSOC)) { class='checkbox-list' value='$userID' form='admin-batchform' - onchange='$function'> + onchange='checkCheckAll();'> $username $role $bancomment - + onsubmit=\"adminUpdate(this); return false;\"> +
    diff --git a/website/views/adminpanel.php b/website/views/adminpanel.php index c48a28d..d2b83d2 100644 --- a/website/views/adminpanel.php +++ b/website/views/adminpanel.php @@ -7,6 +7,7 @@ $perpage = 20; $status = array("user", "frozen", "banned", "unconfirmed", "admin", "owner"); $groupstatus = array("hidden", "public", "membersonly"); $pagetype = "user"; +$userinfo = getRoleByID($_SESSION['userID'])->fetch(PDO::FETCH_ASSOC); if (isset($_GET["search"])) { $search = test_input($_GET["search"]); @@ -123,20 +124,30 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") { -
    + + + Maak Admin + "; + } + ?>
    -
    + + -- 2.49.1 From 422e2d13086ec6d501edf1aa71f8f6107ab53f32 Mon Sep 17 00:00:00 2001 From: Marijn Jansen Date: Mon, 30 Jan 2017 21:48:18 +0100 Subject: [PATCH 033/140] Date picker in bday --- website/queries/settings.php | 14 +++++++-- website/views/settings-view.php | 53 ++++++++++++++++++++++++++------- 2 files changed, 54 insertions(+), 13 deletions(-) diff --git a/website/queries/settings.php b/website/queries/settings.php index f4c5403..6c52fc4 100644 --- a/website/queries/settings.php +++ b/website/queries/settings.php @@ -110,20 +110,30 @@ function updateSettings() { WHERE `userID` = :userID "); + $bday = new DateTime(test_input($_POST["year"] . $_POST["month"] . $_POST["day"])); + checkBday($bday); $stmt->bindValue(":fname", test_input($_POST["fname"])); $stmt->bindValue(":lname", test_input($_POST["lname"])); $stmt->bindValue(":location", test_input($_POST["location"])); - $stmt->bindValue(":bday", test_input($_POST["bday"])); + $stmt->bindValue(":bday", $bday->format("Ymd")); $stmt->bindValue(":bio", test_input($_POST["bio"])); $stmt->bindValue(":showEmail", test_input($_POST["showEmail"])); - $stmt->bindValue(":showBday", test_input($_POST["showBday"])); + $stmt->bindValue(":showBday",test_input($_POST["showBday"])); $stmt->bindValue(":userID", $_SESSION["userID"]); $stmt->execute(); throw new HappyAlert("Instellingen zijn opgeslagen."); } +function checkBday(DateTime $bday) { + $today = new DateTime(); + if ($bday >= $today) { + throw new AngryAlert("Jij bent vast niet in de toekomst geboren toch? ;)"); + } +} + + /** * Change * @throws AngryAlert diff --git a/website/views/settings-view.php b/website/views/settings-view.php index b6a3b4c..1079c91 100644 --- a/website/views/settings-view.php +++ b/website/views/settings-view.php @@ -44,37 +44,68 @@ $settings = getSettings();
  • - " - > + + + +
  • + > Ja + > Nee
  • + > Ja + > Nee
  • @@ -189,4 +220,4 @@ $settings = getSettings();
  • -
    \ No newline at end of file + -- 2.49.1 From ce53b6e9e4e592b55a4f1918862e01ba50bbc4c5 Mon Sep 17 00:00:00 2001 From: Marijn Jansen Date: Mon, 30 Jan 2017 22:42:47 +0100 Subject: [PATCH 034/140] Checkbox for showBday and showEmail --- website/queries/settings.php | 7 ++-- website/views/settings-view.php | 58 +++++++++++++-------------------- 2 files changed, 26 insertions(+), 39 deletions(-) diff --git a/website/queries/settings.php b/website/queries/settings.php index 6c52fc4..bdc9d38 100644 --- a/website/queries/settings.php +++ b/website/queries/settings.php @@ -110,7 +110,8 @@ function updateSettings() { WHERE `userID` = :userID "); - $bday = new DateTime(test_input($_POST["year"] . $_POST["month"] . $_POST["day"])); + $bday = new DateTime(); + $bday->setDate(test_input($_POST["year"]), test_input($_POST["month"]), test_input($_POST["day"])); checkBday($bday); $stmt->bindValue(":fname", test_input($_POST["fname"])); @@ -118,8 +119,8 @@ function updateSettings() { $stmt->bindValue(":location", test_input($_POST["location"])); $stmt->bindValue(":bday", $bday->format("Ymd")); $stmt->bindValue(":bio", test_input($_POST["bio"])); - $stmt->bindValue(":showEmail", test_input($_POST["showEmail"])); - $stmt->bindValue(":showBday",test_input($_POST["showBday"])); + $stmt->bindValue(":showEmail", (array_key_exists("showEmail", $_POST) ? "1" : "0")); + $stmt->bindValue(":showBday", (array_key_exists("showBday", $_POST) ? "1" : "0")); $stmt->bindValue(":userID", $_SESSION["userID"]); $stmt->execute(); diff --git a/website/views/settings-view.php b/website/views/settings-view.php index 1079c91..6271a45 100644 --- a/website/views/settings-view.php +++ b/website/views/settings-view.php @@ -45,30 +45,30 @@ $settings = getSettings();
  • - + "; - + + + - format("Y"); for ($year = $now; $year >= 1900; $year--): ?> @@ -80,33 +80,19 @@ $settings = getSettings();
  • - - > Ja - - > Nee + >
  • - - > Ja - - > Nee + >
  • @@ -220,4 +206,4 @@ $settings = getSettings(); - + \ No newline at end of file -- 2.49.1 From 8dfa31696c8c53ceac1214c862261bd8ba875d06 Mon Sep 17 00:00:00 2001 From: Marijn Jansen Date: Mon, 30 Jan 2017 22:49:43 +0100 Subject: [PATCH 035/140] autocomplete suggestions at password --- website/views/settings-view.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/website/views/settings-view.php b/website/views/settings-view.php index 6271a45..c5c58c2 100644 --- a/website/views/settings-view.php +++ b/website/views/settings-view.php @@ -141,24 +141,30 @@ $settings = getSettings();
    Verander Wachtwoord
    • - +
    • - +
    • - +
    • -- 2.49.1 From 6983aa06a2c97646ff2f5fce9ebe4b03c18c8a33 Mon Sep 17 00:00:00 2001 From: Marijn Jansen Date: Mon, 30 Jan 2017 23:03:50 +0100 Subject: [PATCH 036/140] Finishing touches --- website/views/settings-view.php | 37 +++++++++++++++++---------------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/website/views/settings-view.php b/website/views/settings-view.php index c5c58c2..029a32b 100644 --- a/website/views/settings-view.php +++ b/website/views/settings-view.php @@ -21,7 +21,7 @@ $settings = getSettings(); id="fname" placeholder="Voornaam" title="Voornaam" - value="" + value="" >
    • @@ -30,7 +30,7 @@ $settings = getSettings(); name="lname" id="lname" placeholder="Achternaam" - value="" + value="" >
    • @@ -39,18 +39,19 @@ $settings = getSettings(); name="location" id="location" placeholder="Locatie" - value="" + value="" >
    • - + - -
    • @@ -83,7 +84,7 @@ $settings = getSettings(); + >
    • @@ -91,7 +92,7 @@ $settings = getSettings(); + >
    • @@ -100,7 +101,7 @@ $settings = getSettings(); rows="5" title="bio" id="bio" - > + >
    • @@ -116,7 +117,7 @@ $settings = getSettings();
      • - " + " class="profile-picture" >
      • @@ -183,7 +184,7 @@ $settings = getSettings(); " + value="" disabled > -- 2.49.1 From a6b6d6d747ca2a02e53f8bab68dcafda38ea5387 Mon Sep 17 00:00:00 2001 From: Marijn Jansen Date: Tue, 31 Jan 2017 10:23:47 +0100 Subject: [PATCH 037/140] Style changes --- website/views/settings-view.php | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/website/views/settings-view.php b/website/views/settings-view.php index 029a32b..b7f554a 100644 --- a/website/views/settings-view.php +++ b/website/views/settings-view.php @@ -4,13 +4,11 @@ $settings = getSettings();
        - - $alertMessage -
        "; - } - ?> + +
        + +
        +
        Profiel Instellingen
          @@ -43,10 +41,10 @@ $settings = getSettings(); >
        • - + +
        • -- 2.49.1 From 4dc3b4f651d353b266973acebaad5f517cb97826 Mon Sep 17 00:00:00 2001 From: Lars van Hijfte Date: Tue, 31 Jan 2017 10:31:57 +0100 Subject: [PATCH 038/140] Mobile friendly --- website/public/js/admin.js | 1 - website/public/js/friendButtons.js | 3 -- website/public/js/header.js | 46 ++++++++++++++--------- website/public/styles/chat.css | 14 ++++++- website/public/styles/header.css | 9 ++++- website/public/styles/main.css | 10 +++++ website/public/styles/menu.css | 14 +++++++ website/public/styles/mobilefriendly.css | 47 ++++++++++++++++++++++++ website/public/styles/profile.css | 2 +- website/views/head.php | 2 + website/views/menu.php | 2 +- 11 files changed, 125 insertions(+), 25 deletions(-) create mode 100644 website/public/styles/mobilefriendly.css diff --git a/website/public/js/admin.js b/website/public/js/admin.js index 140c99a..36347c2 100644 --- a/website/public/js/admin.js +++ b/website/public/js/admin.js @@ -60,7 +60,6 @@ function adminSearch() { "API/adminSearchUsers.php", $("#admin-searchform").serialize() ).done(function (data) { - console.log(data); $("#usertable").html(data); }) } diff --git a/website/public/js/friendButtons.js b/website/public/js/friendButtons.js index d62e919..47c476a 100644 --- a/website/public/js/friendButtons.js +++ b/website/public/js/friendButtons.js @@ -48,9 +48,6 @@ function placeFriendButtons() { text2 = "Weiger"; icon2 = "fa-times"; break; - default: - console.log(friendshipStatus); - break; } $buttonContainer.append( diff --git a/website/public/js/header.js b/website/public/js/header.js index bdf5fe3..13e3e12 100644 --- a/website/public/js/header.js +++ b/website/public/js/header.js @@ -1,25 +1,37 @@ $(document).ready(function() { // Toggle menu $("#own-profile-picture, #open-notifications").click(function() { - if ($("#notification-center").css('right') == "-256px") { - // Make the menu visible and move the content to the left. - $("#chat-history").width("calc(100% - 587px)"); - $(".modal").width("calc(100% - 512px)"); - $(".content").css("margin-right", "256px"); - $("#notification-center").css("right", "0px"); + if ($("#notification-center").css('display') == "none") { + // Make the menu visible and move the content to the left. + $(".modal").width("calc(100% - 512px)"); + $(".content").css("margin-right", "256px"); + $("#notification-center").css("right", "0px"); + $("#notification-center").css("display", "block"); + $("#contact-menu").css("display", "block"); - // Add cookie so the menu stays open on other pages - document.cookie = "menu=open; path=/"; - } else { - // Make the menu invisible and move the content to the right. - $("#chat-history").width("calc(100% - 331px)"); - $(".modal").width("calc(100% - 256px)"); - $(".content").css("margin-right", "0px"); - $("#notification-center").css("right", "-256px"); + // Add cookie so the menu stays open on other pages + if (window.innerWidth > 1080) { + $("#chat-history").width("calc(100% - 587px)"); + document.cookie = "menu=open; path=/"; + } else { + document.cookie = "menu=closed; path=/"; + } + } else { + $(".modal").width("calc(100% - 256px)"); + $(".content").css("margin-right", "0px"); + $("#notification-center").css("display", "none"); - // Change menu cookie to close - document.cookie = "menu=closed; path=/"; - } + if (window.innerWidth > 1080) { + $("#chat-history").width("calc(100% - 331px)"); + } else { + // Make the menu invisible and move the content to the right. + $("#contact-menu").css("display", "none"); + } + + // Change menu cookie to close + document.cookie = "menu=closed; path=/"; + + } }); if (getCookie("menu") == "open") { diff --git a/website/public/styles/chat.css b/website/public/styles/chat.css index 85eb219..cb0f19f 100644 --- a/website/public/styles/chat.css +++ b/website/public/styles/chat.css @@ -146,8 +146,20 @@ body { text-align: right; } -@media only screen and (max-width: 1200px) { +@media only screen and (max-width: 1080px) { .chat-message-self, .chat-message-other { max-width: 75%; } + .chat { + left: 0; + width: 100%; + } + #chat-recent-panel { + left: 0; + width: 320px; + } + #chat-history { + left: 50%; + width: calc(100% - 390px); + } } \ No newline at end of file diff --git a/website/public/styles/header.css b/website/public/styles/header.css index 70e8c80..61727eb 100644 --- a/website/public/styles/header.css +++ b/website/public/styles/header.css @@ -26,7 +26,8 @@ header { } #header-search { - padding-left: 42px; + margin: 24px 0 24px 32px; + vertical-align: middle; } @@ -49,4 +50,10 @@ header div { #open-notifications { padding: 5px 20px 5px 0px; +} + +@media only screen and (max-width: 1080px) { + #header-logo { + display: none; + } } \ No newline at end of file diff --git a/website/public/styles/main.css b/website/public/styles/main.css index abb1604..baff345 100644 --- a/website/public/styles/main.css +++ b/website/public/styles/main.css @@ -293,4 +293,14 @@ div[data-title]:hover:after { -webkit-border-radius: 20px; border-radius: 20px; background: #4CAF50; +} + +@media only screen and (max-width: 1080px) { + body { + font-size: 28px!important; + } + button { + font-size: 28px; + } + } \ No newline at end of file diff --git a/website/public/styles/menu.css b/website/public/styles/menu.css index 303b9bc..a862d12 100644 --- a/website/public/styles/menu.css +++ b/website/public/styles/menu.css @@ -86,4 +86,18 @@ height: 100%; padding: 0; text-align: left; +} + +@media only screen and (max-width: 1080px) { + #contact-menu, #notification-center { + display: none; + background: rgba(0, 0, 0, 0.4); + width: calc(50% - 20px); + } + .content { + margin-left: 0; + } + #quick-links i { + font-size: 48px!important; + } } \ No newline at end of file diff --git a/website/public/styles/mobilefriendly.css b/website/public/styles/mobilefriendly.css new file mode 100644 index 0000000..86ffab8 --- /dev/null +++ b/website/public/styles/mobilefriendly.css @@ -0,0 +1,47 @@ +/* MAIN */ +body { + font-size: 28px!important; +} +button { + font-size: 28px; +} + +/* HEADER */ +#header-logo { + display: none; +} + +/* PROFILE */ +.post-box { + width: calc(100% - 65px); +} + +/* MENU */ +#contact-menu, #notification-center { + display: none; + background: rgba(0, 0, 0, 0.4); + width: calc(50% - 20px); +} +.content { + margin-left: 0; +} +#quick-links i { + font-size: 48px!important; +} + +/* CHAT */ +.chat-message-self, .chat-message-other { + max-width: 75%; +} +.chat { + left: 0; + width: 100%; +} +#chat-recent-panel { + left: 0; + width: 320px; +} +#chat-history { + left: 50%; + width: calc(100% - 390px); +} \ No newline at end of file diff --git a/website/public/styles/profile.css b/website/public/styles/profile.css index 03ab19f..37aaaa1 100644 --- a/website/public/styles/profile.css +++ b/website/public/styles/profile.css @@ -116,7 +116,7 @@ div.posts .post form textarea.newpost { } /* mobile */ -@media only screen and (max-width: 1000px) { +@media only screen and (max-width: 1080px) { .post-box { width: calc(100% - 65px); } diff --git a/website/views/head.php b/website/views/head.php index eb86d56..6e8ca0a 100644 --- a/website/views/head.php +++ b/website/views/head.php @@ -12,6 +12,8 @@ @import url("styles/header.css"); @import url("styles/menu.css"); @import url("styles/footer.css"); + + @import url("styles/mobilefriendly.css") screen and (orientation: portrait); +
        -- 2.49.1 From f26097f55fab9a19fa2fc59b087aa4c813f84b5f Mon Sep 17 00:00:00 2001 From: Lars van Hijfte Date: Tue, 31 Jan 2017 12:25:28 +0100 Subject: [PATCH 041/140] Fixed online status --- website/public/bits/friend-item.php | 2 +- website/public/group.php | 2 +- website/public/profile.php | 8 ++++---- website/public/styles/main.css | 10 +++++++++- website/public/styles/profile.css | 2 +- website/queries/friendship.php | 11 ++++++----- website/queries/user.php | 13 +++++++++++++ website/views/head.php | 5 ++++- website/views/profile.php | 4 ++-- 9 files changed, 41 insertions(+), 16 deletions(-) diff --git a/website/public/bits/friend-item.php b/website/public/bits/friend-item.php index a69d12a..40bc8a8 100644 --- a/website/public/bits/friend-item.php +++ b/website/public/bits/friend-item.php @@ -33,7 +33,7 @@ foreach($friends as $i => $friend) { } ?>'>
        - PF + PF
        fullname ?>
        = DATE_SUB(NOW(),INTERVAL 15 MINUTE) + WHEN TRUE THEN 'online' + WHEN FALSE THEN 'offline' + END AS `onlinestatus`, `role` FROM `user` @@ -28,11 +32,8 @@ function selectLimitedFriends($userID, $limit) { `friendship`.`user1ID` = `user`.`userID`) AND `user`.`role` != 'banned' AND `friendship`.`status` = 'confirmed' - ORDER BY - CASE - WHEN `friendship`.`user2ID` = `user`.`userID` THEN `friendship`.`chatLastVisted1` - WHEN `friendship`.`user1ID` = `user`.`userID` THEN `friendship`.`chatLastVisted2` - END + ORDER BY + `user`.`lastactivity` DESC LIMIT :limitCount "); diff --git a/website/queries/user.php b/website/queries/user.php index 0900d9f..b1bb93c 100644 --- a/website/queries/user.php +++ b/website/queries/user.php @@ -2,6 +2,19 @@ require_once ("connect.php"); +function updateLastActivity() { + $stmt = prepareQuery(" + UPDATE + `user` + SET + `lastactivity` = NOW() + WHERE + `userID` = :userID + "); + $stmt->bindParam(":userID", $_SESSION["userID"]); + return $stmt->execute(); +} + function getUserID($username) { $stmt = prepareQuery(" SELECT diff --git a/website/views/head.php b/website/views/head.php index 6e8ca0a..284abb4 100644 --- a/website/views/head.php +++ b/website/views/head.php @@ -19,9 +19,12 @@ require_once ("../queries/checkInput.php"); require_once ("../queries/connect.php"); +require_once ("../queries/user.php"); session_start(); if(!isset($_SESSION["userID"])){ header("location:login.php"); -} \ No newline at end of file +} else { + updateLastActivity(); +} diff --git a/website/views/profile.php b/website/views/profile.php index 90a368d..8cf555f 100644 --- a/website/views/profile.php +++ b/website/views/profile.php @@ -1,10 +1,10 @@
        - ">
        + " src="">
        -- 2.49.1 From f67dd019c46c67ca604423d00ac04b7c956a8ac7 Mon Sep 17 00:00:00 2001 From: Lars van Hijfte Date: Tue, 31 Jan 2017 12:47:24 +0100 Subject: [PATCH 042/140] Inputs are now mobile friendly --- website/public/styles/main.css | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/website/public/styles/main.css b/website/public/styles/main.css index 7909687..f2d7535 100644 --- a/website/public/styles/main.css +++ b/website/public/styles/main.css @@ -192,7 +192,7 @@ button.green { } button.gray{ - background-color: inherit; + background-color: #FFF; color: #333; } @@ -307,8 +307,9 @@ div[data-title]:hover:after { body { font-size: 28px!important; } - button { + button, input { font-size: 28px; + height: 42px; } } \ No newline at end of file -- 2.49.1 From c14a2770bd092b41a343a2a99f0606c444c75b3d Mon Sep 17 00:00:00 2001 From: "K. Nobel" Date: Tue, 31 Jan 2017 12:52:50 +0100 Subject: [PATCH 043/140] Fixed posting functions for groups. --- website/public/API/postPost.php | 57 +++++++++++++++++++++++++++------ website/queries/group_page.php | 31 +++++++++++++++++- 2 files changed, 77 insertions(+), 11 deletions(-) diff --git a/website/public/API/postPost.php b/website/public/API/postPost.php index b52e96b..40c18e1 100644 --- a/website/public/API/postPost.php +++ b/website/public/API/postPost.php @@ -2,16 +2,53 @@ session_start(); -require("../../queries/post.php"); -require("../../queries/connect.php"); -require("../../queries/checkInput.php"); +require_once("../../queries/post.php"); +require_once("../../queries/group_page.php"); +require_once("../../queries/connect.php"); +require_once("../../queries/checkInput.php"); -if (empty($_POST['newpost-title'])) { -} else { - makePost($_SESSION['userID'], - null, - test_input($_POST['newpost-title']), - test_input($_POST['newpost-content'])); +if (empty($_POST["title"]) or + empty($_POST["content"]) or + empty($_SESSION["userID"])) { + header('HTTP/1.1 500 Non enough arguments'); } -header("Location: ../profile.php"); \ No newline at end of file +if (empty($_POST["group"])) { + // User Post + makePost( + $_SESSION["userID"], + null, + test_input($_POST["title"]), + test_input($_POST["content"]) + ); +} else { + // Group Post + + // Check if the user is an admin or mod of the group. + if(!in_array(selectGroupRole($_POST["group"]), array('mod', 'admin'))) { + header('HTTP/1.1 500 Non enough rights'); + return; + } + + makePost( + $_SESSION["userID"], + $_POST["group"], + test_input($_POST["title"]), + test_input($_POST["content"]) + ); +} + + + + + + +//if (empty($_POST['newpost-title'])) { +//} else { +// makePost($_SESSION['userID'], +// null, +// test_input($_POST['newpost-title']), +// test_input($_POST['newpost-content'])); +//} +// +//header("Location: ../profile.php"); \ No newline at end of file diff --git a/website/queries/group_page.php b/website/queries/group_page.php index b3e454c..83911f8 100644 --- a/website/queries/group_page.php +++ b/website/queries/group_page.php @@ -11,6 +11,12 @@ function selectGroupByName($name) { `description`, `picture`, `status`, + ( + SELECT `role` + FROM `group_member` + WHERE `group_member`.`groupID` = `group_page`.`groupID` AND + `userID` = :userID + ) AS `role`, COUNT(`group_member`.`groupID`) as `members` FROM `group_page` @@ -22,13 +28,36 @@ function selectGroupByName($name) { name LIKE :name "); - $stmt->bindParam(':name', $name); + $stmt->bindParam(':name', $name, PDO::PARAM_STR); + $stmt->bindParam(':userID', $_SESSION["userID"], PDO::PARAM_INT); if (!$stmt->execute()) { return False; } return $stmt->fetch(); } +function selectGroupRole(int $groupID) { + $stmt = prepareQuery(" + SELECT + `role` + FROM + `group_member` + WHERE + `groupID` = :groupID AND + `userID` = :userID + "); + + $stmt->bindParam(':groupID', $groupID, PDO::PARAM_INT); + $stmt->bindParam(':userID', $_SESSION["userID"], PDO::PARAM_INT); + if(!$stmt->execute()) { + return False; + } + if($stmt->rowCount() == 0) { + return "none"; + } + return $stmt->fetch()["role"]; +} + function selectGroupMembers(int $groupID) { $stmt = prepareQuery(" SELECT -- 2.49.1 From 6b13db9c4fbfeb99ce903b8072c36ad2e60f7cc9 Mon Sep 17 00:00:00 2001 From: "K. Nobel" Date: Tue, 31 Jan 2017 12:53:45 +0100 Subject: [PATCH 044/140] Fixed posting on group pages. --- website/public/API/postPost.php | 2 +- website/public/group.php | 3 +++ website/public/js/masonry.js | 34 +++++++++++++++++++++++++++++---- website/views/group.php | 2 +- 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/website/public/API/postPost.php b/website/public/API/postPost.php index 40c18e1..7a33857 100644 --- a/website/public/API/postPost.php +++ b/website/public/API/postPost.php @@ -29,7 +29,7 @@ if (empty($_POST["group"])) { header('HTTP/1.1 500 Non enough rights'); return; } - + makePost( $_SESSION["userID"], $_POST["group"], diff --git a/website/public/group.php b/website/public/group.php index 2ef3493..5d9459e 100644 --- a/website/public/group.php +++ b/website/public/group.php @@ -34,6 +34,9 @@ include("../views/group.php"); include("../views/footer.php"); $masonry_mode = 0; +if ($group["role"] == "mod" OR $group["role"] == "admin") { + $masonry_mode = 2; +} ?> diff --git a/website/public/js/masonry.js b/website/public/js/masonry.js index cb82089..d73c33c 100644 --- a/website/public/js/masonry.js +++ b/website/public/js/masonry.js @@ -23,6 +23,28 @@ function requestPost(postID) { }); } +function postPost() { + title = $("input.newpost[name='title']").val(); + content = $("textarea.newpost[name='content']").val(); + + if (masonryMode == 2) { + $.post("API/postPost.php", { title: title, + content : content, + group : groupID }) + .done(function() { + masonry(masonryMode); + }); + } else { + $.post("API/postPost.php", { title: title, + content : content }) + .done(function() { + masonry(masonryMode); + }); + } + + +} + $(window).on("load", function() { $(".modal-close").click(function () { $(".modal").hide(); @@ -64,13 +86,17 @@ function masonry(mode) { columns[i] = [0, $column]; } - if(mode == 1) { + if(mode > 0) { $postInput = $("
        "); - $form = $(""); + $form = $(""); $postInput.append($form); - $form.append($("")); - $form.append($("")); $form.append($("")); columns[0][1].append($postInput); diff --git a/website/views/post-view.php b/website/views/post-view.php index 264d67c..d961334 100644 --- a/website/views/post-view.php +++ b/website/views/post-view.php @@ -24,7 +24,7 @@ echo("
        -
        +
        + +
        + +
        -- 2.49.1 From c0a64e9ffd4af652b488ac18a39f31831de13523 Mon Sep 17 00:00:00 2001 From: Marijn Jansen Date: Tue, 31 Jan 2017 16:19:15 +0100 Subject: [PATCH 057/140] 1337 bday --- website/views/settings-view.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/website/views/settings-view.php b/website/views/settings-view.php index b7f554a..b03133e 100644 --- a/website/views/settings-view.php +++ b/website/views/settings-view.php @@ -75,6 +75,9 @@ $settings = getSettings(); +
      • -- 2.49.1 From 52a4822477432218965aff2bf0b9b15018f4112e Mon Sep 17 00:00:00 2001 From: Hendrik Date: Tue, 31 Jan 2017 16:20:02 +0100 Subject: [PATCH 058/140] post-merge fix --- website/public/API/adminSearchUsers.php | 2 +- website/views/adminpanel-table.php | 2 +- website/views/adminpanel.php | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/website/public/API/adminSearchUsers.php b/website/public/API/adminSearchUsers.php index 58b170a..5f7944b 100644 --- a/website/public/API/adminSearchUsers.php +++ b/website/public/API/adminSearchUsers.php @@ -33,7 +33,7 @@ if (isset($_POST['groupstatus'])) { $groupstatus = $_POST["groupstatus"]; } -$userinfo = getRoleByID($_SESSION['userID'])->fetch(PDO::FETCH_ASSOC); +$userinfo = getRoleByID($_SESSION['userID']); if ($pagetype == "user") { include ("../../views/adminpanel-table.php"); diff --git a/website/views/adminpanel-table.php b/website/views/adminpanel-table.php index 9e6b9bc..3ae5da4 100644 --- a/website/views/adminpanel-table.php +++ b/website/views/adminpanel-table.php @@ -50,7 +50,7 @@ while($user = $q->fetch(PDO::FETCH_ASSOC)) { - - - -
      • \ No newline at end of file diff --git a/website/views/homeLoginRegister.php b/website/views/homeLoginRegister.php index 8fc0ec0..beffff8 100644 --- a/website/views/homeLoginRegister.php +++ b/website/views/homeLoginRegister.php @@ -58,7 +58,7 @@ $fb = new Facebook\Facebook([ 'app_secret' => $appSecret, 'default_graph_version' => 'v2.2', ]); -$redirect = "https://myhyvesbookplus.nl/~joey/login.php"; +$redirect = "https://myhyvesbookplus.nl/login.php"; $helper = $fb->getRedirectLoginHelper(); try { @@ -80,12 +80,6 @@ if(!isset($acces_token)){ $response = $fb->get('/me?fields=email,name,birthday'); $usernode = $response->getGraphUser(); -// echo $usernode->getName() . "
        "; - echo $usernode->getID() . "
        "; -// echo $usernode->getProperty("email") . "

        "; -// echo "Picture
        "; -// echo "

        "; - $nameSplit = explode(" ", $usernode->getName()); $fbName = $nameSplit[0]; $fbSurname = $nameSplit[1]; @@ -93,7 +87,6 @@ if(!isset($acces_token)){ $fbEmail = $usernode->getProperty("email"); // $image = 'https://graph.facebook.com/' . $usernode->getId() . '/picture?width=200'; - if (fbLogin($fbUserID) == 1) { $fbID = getfbUserID($fbUserID)["userID"]; $fbRole = getfbUserID($fbUserID)["role"]; -- 2.49.1 From 2b984805877c7519fac54db8e645aabb16e4cc19 Mon Sep 17 00:00:00 2001 From: Lars van Hijfte Date: Wed, 1 Feb 2017 13:07:06 +0100 Subject: [PATCH 070/140] BUG FIX: Menu now saves the cookie again --- website/public/js/admin.js | 3 -- website/public/js/chat.js | 1 - website/public/js/groupButtons.js | 1 + website/public/js/header.js | 68 ++++++++++++++++++------------- website/public/js/main.js | 1 + website/public/js/menu.js | 21 +++++++--- 6 files changed, 57 insertions(+), 38 deletions(-) diff --git a/website/public/js/admin.js b/website/public/js/admin.js index 2b78e0b..e0dc9f7 100644 --- a/website/public/js/admin.js +++ b/website/public/js/admin.js @@ -17,12 +17,10 @@ $(window).on("load", function () { because serialize doesn't take submit values. */ $('#admin-batchform > button').click(function () { $('#batchinput').prop('value', $(this).prop('value')); - console.log($('#batchinput').prop('value')); }); $('#admin-groupbatchform > button').click(function () { $('#groupbatchinput').prop('value', $(this).prop('value')); - console.log($('#batchinput').prop('value')); }); }); @@ -67,7 +65,6 @@ function searchFromOne() { } function adminSearch() { - console.log($("#admin-searchform").serialize()); $.post( "API/adminSearchUsers.php", $("#admin-searchform").serialize() diff --git a/website/public/js/chat.js b/website/public/js/chat.js index e332324..6a027c8 100644 --- a/website/public/js/chat.js +++ b/website/public/js/chat.js @@ -49,7 +49,6 @@ function addMessages(messages) { // Initialize message variables var thisDate = new Date(messages[i].creationdate.replace(/ /,"T")); var thisTime = thisDate.getHours() + ":" + thisDate.getMinutes(); - console.log(thisDate); var type; thisDate.setHours(0,0,0,0); diff --git a/website/public/js/groupButtons.js b/website/public/js/groupButtons.js index 0f1b6bf..e6ada67 100644 --- a/website/public/js/groupButtons.js +++ b/website/public/js/groupButtons.js @@ -25,6 +25,7 @@ function placeGroupButtons() { .done(function() { $buttonContainer.children().remove(); placeGroupButtons(); + updateMenus(); }).fail(function() { }); }); diff --git a/website/public/js/header.js b/website/public/js/header.js index 13e3e12..4feea40 100644 --- a/website/public/js/header.js +++ b/website/public/js/header.js @@ -1,40 +1,52 @@ $(document).ready(function() { // Toggle menu $("#own-profile-picture, #open-notifications").click(function() { - if ($("#notification-center").css('display') == "none") { - // Make the menu visible and move the content to the left. - $(".modal").width("calc(100% - 512px)"); - $(".content").css("margin-right", "256px"); - $("#notification-center").css("right", "0px"); - $("#notification-center").css("display", "block"); - $("#contact-menu").css("display", "block"); + if ($("#notification-center").css('display') == "none") { + // Make the menu visible and move the content to the left. + $(".modal").width("calc(100% - 512px)"); + $(".content").css("margin-right", "256px"); + $("#notification-center").css("right", "0px"); + $("#notification-center").css("display", "block"); + $("#contact-menu").css("display", "block"); - // Add cookie so the menu stays open on other pages - if (window.innerWidth > 1080) { - $("#chat-history").width("calc(100% - 587px)"); - document.cookie = "menu=open; path=/"; - } else { - document.cookie = "menu=closed; path=/"; - } + // Add cookie so the menu stays open on other pages + if (window.innerWidth > 1080) { + $("#chat-history").width("calc(100% - 587px)"); + document.cookie = "menu=open; path=/"; } else { - $(".modal").width("calc(100% - 256px)"); - $(".content").css("margin-right", "0px"); - $("#notification-center").css("display", "none"); - - if (window.innerWidth > 1080) { - $("#chat-history").width("calc(100% - 331px)"); - } else { - // Make the menu invisible and move the content to the right. - $("#contact-menu").css("display", "none"); - } - - // Change menu cookie to close document.cookie = "menu=closed; path=/"; - } + } else { + $(".modal").width("calc(100% - 256px)"); + $(".content").css("margin-right", "0px"); + $("#notification-center").css("display", "none"); + + if (window.innerWidth > 1080) { + $("#chat-history").width("calc(100% - 331px)"); + } else { + // Make the menu invisible and move the content to the right. + $("#contact-menu").css("display", "none"); + } + + // Change menu cookie to close + document.cookie = "menu=closed; path=/"; + } }); if (getCookie("menu") == "open") { - $("#own-profile-picture").click(); + // Make the menu visible and move the content to the left. + $(".modal").width("calc(100% - 512px)"); + $(".content").css("margin-right", "256px"); + $("#notification-center").css("right", "0px"); + $("#notification-center").css("display", "block"); + $("#contact-menu").css("display", "block"); + + // Add cookie so the menu stays open on other pages + if (window.innerWidth > 1080) { + $("#chat-history").width("calc(100% - 587px)"); + document.cookie = "menu=open; path=/"; + } else { + document.cookie = "menu=closed; path=/"; + } } }); diff --git a/website/public/js/main.js b/website/public/js/main.js index 2983fdb..a5f17de 100644 --- a/website/public/js/main.js +++ b/website/public/js/main.js @@ -53,6 +53,7 @@ function editFriendship(userID, value) { $.post("API/editFriendship.php", { usr: userID, action: value }) .done(function() { placeFriendButtons(); + updateMenus(); }); } diff --git a/website/public/js/menu.js b/website/public/js/menu.js index d15d678..5ca9c97 100644 --- a/website/public/js/menu.js +++ b/website/public/js/menu.js @@ -2,23 +2,28 @@ var menuFriendsData; var menuGroupsData; var notificationMessagesData; var notificationRequestsData; +var updatingMenus = 0; - +// On document load, load menus and loops loading menus every 10 seconds. $(document).ready(function() { + updatingMenus = 4; loadMenuFriends(5); loadNotificationFriends(); loadUnreadMessages(); loadMenuGroups(); - setInterval(updateMenus, 3000); + setInterval(updateMenus, 10000); }); // Update the menu and notification items. function updateMenus() { - loadMenuFriends(5); - loadNotificationFriends(); - loadUnreadMessages(); - loadMenuGroups(); + if (updatingMenus <= 0) { + updatingMenus = 4; + loadMenuFriends(5); + loadNotificationFriends(); + loadUnreadMessages(); + loadMenuGroups(); + } } @@ -38,6 +43,7 @@ function loadMenuFriends(limit) { $("#friends-menu-section").hide(); } } + updatingMenus --; }); } @@ -57,6 +63,7 @@ function loadMenuGroups() { $("#groups-menu-section").hide(); } } + updatingMenus --; }); } @@ -73,6 +80,7 @@ function loadNotificationFriends() { $("#friend-request-section").hide(); } } + updatingMenus --; }); } @@ -89,5 +97,6 @@ function loadUnreadMessages() { $("#unread-messages-section").hide(); } } + updatingMenus --; }); } \ No newline at end of file -- 2.49.1 From 9b89058484246925d399075fda21d1a9acbbd22d Mon Sep 17 00:00:00 2001 From: Hendrik Date: Wed, 1 Feb 2017 14:05:04 +0100 Subject: [PATCH 071/140] add infinite scroll on profile --- website/public/API/getPosts.php | 28 ++++--- website/public/js/masonry.js | 117 ++++++++++++++++++++---------- website/public/styles/profile.css | 5 ++ website/queries/post.php | 51 +++++++++++++ website/views/profile.php | 4 + 5 files changed, 156 insertions(+), 49 deletions(-) diff --git a/website/public/API/getPosts.php b/website/public/API/getPosts.php index 620a707..850c5ea 100644 --- a/website/public/API/getPosts.php +++ b/website/public/API/getPosts.php @@ -1,26 +1,30 @@ fetchAll(PDO::FETCH_ASSOC); + + for($i = 0; $i < sizeof($results); $i++) { + $results[$i]["nicetime"] = nicetime($results[$i]["creationdate"]); + } + + echo json_encode($results); } -$results = $posts->fetchAll(PDO::FETCH_ASSOC); - -for($i = 0; $i < sizeof($results); $i++) { - $results[$i]["nicetime"] = nicetime($results[$i]["creationdate"]); -} - -echo json_encode($results); \ No newline at end of file diff --git a/website/public/js/masonry.js b/website/public/js/masonry.js index 53018d3..4c40aad 100644 --- a/website/public/js/masonry.js +++ b/website/public/js/masonry.js @@ -45,6 +45,21 @@ function postPost() { } +var masonryMode = 0; +var windowWidth; +var columnCount; +var columns; +var postLimit; +var postAmount = 0; +var noposts = false; + +$(document).ready(function () { + windowWidth = $(window).width(); + columnCount = Math.floor($(".posts").width() / 250); + columns = new Array(columnCount); + postLimit = columnCount * 7; +}); + $(window).on("load", function() { $(".modal-close").click(function () { $(".modal").hide(); @@ -52,21 +67,28 @@ $(window).on("load", function() { $('#modal-response').hide(); $('.modal-default').show(); }); + + // http://stackoverflow.com/questions/9439725/javascript-how-to-detect-if-browser-window-is-scrolled-to-bottom + // $(window).on("scroll", function () { + // if ((window.innerHeight + window.pageYOffset) >= document.body.offsetHeight) { + // loadMorePosts(userID, groupID, postAmount, postLimit); + // } + // }); + window.onscroll = function(ev) { + if($(window).scrollTop() + $(window).height() == $(document).height() ) { + loadMorePosts(userID, groupID, postAmount, postLimit); + } + }; }); -var masonryMode = 0; -var windowWidth = $(window).width(); -var oldColumnCount = Math.floor($(".posts").width() / 250); - - $(window).resize(function() { clearTimeout(window.resizedFinished); window.resizeFinished = setTimeout(function() { if ($(window).width() != windowWidth) { windowWidth = $(window).width(); - if (oldColumnCount != Math.floor($(".posts").width() / 250)) { - oldColumnCount = Math.floor($(".posts").width() / 250); + if (columnCount != Math.floor($(".posts").width() / 250)) { + columnCount = Math.floor($(".posts").width() / 250); masonry(masonryMode); } } @@ -78,12 +100,10 @@ var $container = $(".posts"); function masonry(mode) { masonryMode = mode; $container.children().remove(); - columnCount = Math.floor($(".posts").width() / 250); /* * Initialise columns. */ - var columns = new Array(columnCount); for (i = 0; i < columnCount; i++) { $column = $("
        "); @@ -112,38 +132,61 @@ function masonry(mode) { /* * Function will find the column with the shortest height. */ - function getShortestColumn(columns) { - column = columns[0]; - for (i = 1; i < columnCount; i++) { - if (column[0] > columns[i][0]) { - column = columns[i]; - } - } - return column; - } /* * Get the posts from the server. */ - $.post("API/getPosts.php", { usr : userID, grp : groupID }) - .done(function(data) { - posts = JSON.parse(data); - - /* - * Rearange the objects. - */ - $.each(posts, function() { - $post = $("
        "); - $post.append($("

        ").html(this["title"])); - $post.append($("

        ").html(fancyText(this["content"]))); - $post.append($("

        ").text(this["nicetime"])); - $post.append($("

        ").text("comments: " + this["comments"] + ", niet slechts: " + this["niet_slechts"])); - - shortestColumn = getShortestColumn(columns); - shortestColumn[1].append($post); - shortestColumn[0] = shortestColumn[0] + $post.height() + margin; - }); - }); + loadMorePosts(userID, groupID, 0, postLimit); } +function getShortestColumn(columns) { + column = columns[0]; + + for (i = 1; i < columnCount; i++) { + if (column[0] > columns[i][0]) { + column = columns[i]; + } + } + return column; +} + +function loadMorePosts(uID, gID, offset, limit) { + if (noposts) { + return; + } + + console.log(uID, gID, offset, limit); + + + $.post("API/getPosts.php", { usr : uID, + grp : gID, + offset : offset, + limit : limit}) + .done(function(data) { + if (!data) { + $('.noposts').show(); + noposts = true; + return; + } + + posts = JSON.parse(data); + + /* + * Rearange the objects. + */ + $.each(posts, function() { + $post = $("

        "); + $post.append($("

        ").html(this["title"])); + $post.append($("

        ").html(fancyText(this["content"]))); + $post.append($("

        ").text(this["nicetime"])); + $post.append($("

        ").text("comments: " + this["comments"] + ", niet slechts: " + this["niet_slechts"])); + + shortestColumn = getShortestColumn(columns); + shortestColumn[1].append($post); + shortestColumn[0] = shortestColumn[0] + $post.height() + margin; + }); + }); + + postAmount += limit; +} \ No newline at end of file diff --git a/website/public/styles/profile.css b/website/public/styles/profile.css index 421e781..fd6f6fc 100644 --- a/website/public/styles/profile.css +++ b/website/public/styles/profile.css @@ -109,6 +109,11 @@ div.posts .post form textarea.newpost { font-size: 0.8em; } +.noposts { + display: none; + text-align: center; +} + @media only screen and (max-width: 1500px) { .post-box { width: calc(50% - 68px); diff --git a/website/queries/post.php b/website/queries/post.php index a175cda..db81892 100644 --- a/website/queries/post.php +++ b/website/queries/post.php @@ -46,6 +46,57 @@ function selectAllPosts($userID, $groupID) { } +function selectSomePosts($userID, $groupID, $offset, $limit) { + $stmt = prepareQuery(" + SELECT + `post`.`postID`, + `post`.`author`, + `title`, + CASE LENGTH(`post`.`content`) >= 150 AND `post`.`content` NOT LIKE 'bindParam(':userID', $userID, PDO::PARAM_INT); + $stmt->bindParam(':groupID', $groupID , PDO::PARAM_INT); + $stmt->bindParam(':offset', intval($offset), PDO::PARAM_INT); + $stmt->bindParam(':limit', intval($limit), PDO::PARAM_INT); + if(!$stmt->execute()) { + return False; + } + if($stmt->rowCount() == 0) { + return False; + } + return $stmt; + +} + function selectPostById($postID) { $stmt = prepareQuery(" SELECT diff --git a/website/views/profile.php b/website/views/profile.php index c72c01b..2bb117f 100644 --- a/website/views/profile.php +++ b/website/views/profile.php @@ -71,6 +71,10 @@

        +
        +

        Geen posts meer!

        +
        +

      -- 2.49.1 From d027333bd7dfa3170505566a0f93c6b5ef55d6d9 Mon Sep 17 00:00:00 2001 From: Hendrik Date: Thu, 2 Feb 2017 01:06:31 +0100 Subject: [PATCH 080/140] fix filter and pagenumber interaction in search --- website/public/API/searchPageNumber.php | 14 ++++++++--- website/queries/friendship.php | 31 +++++++++++++++++++++++++ website/queries/group_member.php | 23 ++++++++++++++++++ website/views/search-view.php | 7 +++++- 4 files changed, 71 insertions(+), 4 deletions(-) diff --git a/website/public/API/searchPageNumber.php b/website/public/API/searchPageNumber.php index 4a76516..9a12d79 100644 --- a/website/public/API/searchPageNumber.php +++ b/website/public/API/searchPageNumber.php @@ -6,6 +6,8 @@ require_once ("../../queries/connect.php"); require_once ("../../queries/checkInput.php"); require_once ("../../queries/user.php"); require_once ("../../queries/group_page.php"); +require_once ("../../queries/friendship.php"); +require_once ("../../queries/group_member.php"); $user_perpage = $group_perpage = 20; @@ -25,14 +27,20 @@ if (isset($_POST['search'])) { $search = test_input($_POST['search']); } -$user_count = countSomeUsers($search)->fetchColumn(); -$group_count = countSomeGroups($search)->fetchColumn(); - $filter = "all"; if (isset($_POST['filter'])) { $filter = test_input($_POST['filter']); } +if ($filter == "all") { + $user_count = countSomeUsers($search)->fetchColumn(); + $group_count = countSomeGroups($search)->fetchColumn(); +} else { + $user_count = countSomeFriends($search); + $group_count = countSomeOwnGroups($search); +} + + $option = "user"; if (isset($_POST['option'])) { $option = test_input($_POST['option']); diff --git a/website/queries/friendship.php b/website/queries/friendship.php index 450fd20..49d8047 100644 --- a/website/queries/friendship.php +++ b/website/queries/friendship.php @@ -274,4 +274,35 @@ function searchSomeFriends($n, $m, $search) { $stmt->bindParam(':m', $m, PDO::PARAM_INT); $stmt->execute(); return json_encode($stmt->fetchAll()); +} + +function countSomeFriends($search) { + $stmt = prepareQuery(" + SELECT + COUNT(*) + FROM + `user` + INNER JOIN + `friendship` + WHERE + ((`friendship`.`user1ID` = :userID AND + `friendship`.`user2ID` = `user`.`userID` OR + `friendship`.`user2ID` = :userID AND + `friendship`.`user1ID` = `user`.`userID`) AND + `user`.`role` != 'banned' AND + `friendship`.`status` = 'confirmed') AND + (`username` LIKE :keyword OR + `fname` LIKE :keyword OR + `lname` LIKE :keyword) + ORDER BY + `fname`, + `lname`, + `username` + "); + + $search = "%$search%"; + $stmt->bindParam(':keyword', $search); + $stmt->bindParam(':userID', $_SESSION["userID"], PDO::PARAM_INT); + $stmt->execute(); + return $stmt->fetchColumn(); } \ No newline at end of file diff --git a/website/queries/group_member.php b/website/queries/group_member.php index cea4dde..8b6bf75 100644 --- a/website/queries/group_member.php +++ b/website/queries/group_member.php @@ -54,3 +54,26 @@ function searchSomeOwnGroups($n, $m, $search) { return json_encode($stmt->fetchAll()); } + +function countSomeOwnGroups($search) { + $stmt = prepareQuery(" + SELECT + COUNT(*) + FROM + `group_page` + INNER JOIN + `group_member` + WHERE + `group_member`.`userID` = :userID AND + `group_member`.`groupID` = `group_page`.`groupID` AND + `group_page`.`status` != 'hidden' AND + `name` LIKE :keyword + "); + + $search = "%$search%"; + $stmt->bindParam(':keyword', $search); + $stmt->bindParam(':userID', $_SESSION["userID"], PDO::PARAM_INT); + $stmt->execute(); + + return $stmt->fetchColumn(); +} \ No newline at end of file diff --git a/website/views/search-view.php b/website/views/search-view.php index e42f985..f00fd3c 100644 --- a/website/views/search-view.php +++ b/website/views/search-view.php @@ -48,7 +48,12 @@ $group_n = ($group_currentpage - 1) * $group_perpage; - -- 2.49.1 From e299ef59e8e5e46d87fde39c1b152b34aa92807a Mon Sep 17 00:00:00 2001 From: Marijn Jansen Date: Thu, 2 Feb 2017 10:28:12 +0100 Subject: [PATCH 081/140] Added show profile into settings --- website/public/js/post.js | 2 -- website/queries/settings.php | 7 +++++-- website/views/settings-view.php | 8 ++++++++ 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/website/public/js/post.js b/website/public/js/post.js index f176950..4009023 100644 --- a/website/public/js/post.js +++ b/website/public/js/post.js @@ -34,6 +34,4 @@ function deletePost(postID) { }); closeModal(); masonry(masonryMode); - - } \ No newline at end of file diff --git a/website/queries/settings.php b/website/queries/settings.php index 03f794f..dfd65a0 100644 --- a/website/queries/settings.php +++ b/website/queries/settings.php @@ -18,7 +18,8 @@ function getSettings() { `bio`, `profilepicture`, `showBday`, - `showEmail` + `showEmail`, + `showProfile` FROM `user` WHERE @@ -64,7 +65,8 @@ function updateSettings() { `birthdate` = :bday, `bio` = :bio, `showEmail` = :showEmail, - `showBday` = :showBday + `showBday` = :showBday, + `showProfile` = :showProfile WHERE `userID` = :userID "); @@ -79,6 +81,7 @@ function updateSettings() { $stmt->bindValue(":bio", test_input($_POST["bio"])); $stmt->bindValue(":showEmail", (array_key_exists("showEmail", $_POST) ? "1" : "0")); $stmt->bindValue(":showBday", (array_key_exists("showBday", $_POST) ? "1" : "0")); + $stmt->bindValue(":showProfile", (array_key_exists("showProfile", $_POST) ? "1" : "0")); $stmt->bindValue(":userID", $_SESSION["userID"]); $stmt->execute(); diff --git a/website/views/settings-view.php b/website/views/settings-view.php index e3cfd36..f72e243 100644 --- a/website/views/settings-view.php +++ b/website/views/settings-view.php @@ -96,6 +96,14 @@ $settings = getSettings(); >
    • +
    • + + + > +
    • ")); - $form.append($("")); + $form.append($("")); columns[0][1].append($postInput); columns[0][0] = $postInput.height() + margin; diff --git a/website/public/styles/profile.css b/website/public/styles/profile.css index 1bacafa..2370da8 100644 --- a/website/public/styles/profile.css +++ b/website/public/styles/profile.css @@ -108,7 +108,7 @@ div.posts .post form input, div.posts .post form textarea { width: calc(100% - 15px); } -div.posts .post form input[type="submit"] { +div.posts .post form input[type="submit"], .post button{ width: 100%; } diff --git a/website/views/post-view.php b/website/views/post-view.php index da1c86f..f8fe902 100644 --- a/website/views/post-view.php +++ b/website/views/post-view.php @@ -30,7 +30,7 @@ $fullname = $post['fname'] . " " . $post['lname'] . " (" . $post['username'] . "

      - + "; + ""; } // Add ogg video's else if (link.match(/(https?:\/\/.[^ ]*\.(?:ogg))/ig)) { return ""; + ""; } // Add youtube video's else if (link.match(/(https?:\/\/.(www.)?youtube|youtu.be)*watch/ig)) { diff --git a/website/public/styles/main.css b/website/public/styles/main.css index 226a96d..650a30f 100644 --- a/website/public/styles/main.css +++ b/website/public/styles/main.css @@ -116,7 +116,7 @@ p { @media only screen and (max-width: 1400px) { .item-box { - width: calc(100% - 50px); + width: calc(100% - 50px)!important; } } diff --git a/website/public/styles/settings.css b/website/public/styles/settings.css index 933e7fd..6a2c2f2 100644 --- a/website/public/styles/settings.css +++ b/website/public/styles/settings.css @@ -32,6 +32,11 @@ text-align: right; } +.settings-password, .settings-email { + width: calc(50% - 60px); + display: inline-flex; +} + .settings-password label, .settings-email label { text-align: left; } diff --git a/website/views/head.php b/website/views/head.php index 284abb4..c4d13a5 100644 --- a/website/views/head.php +++ b/website/views/head.php @@ -1,4 +1,8 @@ - + + + + + MyHyvesbook+ -- 2.49.1 From 327a6a8f5cb5f8ca04508548dd3f6d3062e5264d Mon Sep 17 00:00:00 2001 From: Lars van Hijfte Date: Thu, 2 Feb 2017 12:52:03 +0100 Subject: [PATCH 086/140] BUG FIX: username doesn't cut off in link --- website/public/bits/friend-item.php | 2 +- website/queries/friendship.php | 13 ++++++++----- website/queries/user.php | 3 ++- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/website/public/bits/friend-item.php b/website/public/bits/friend-item.php index 181f9b6..6a0c868 100644 --- a/website/public/bits/friend-item.php +++ b/website/public/bits/friend-item.php @@ -41,7 +41,7 @@ foreach($friends as $i => $friend) { fullname ?>
      username)) { - echo $friend->username; + echo $friend->usernameshort; } else if (isset($friend->content)) { echo $friend->content; } diff --git a/website/queries/friendship.php b/website/queries/friendship.php index e1a8c53..6ea6313 100644 --- a/website/queries/friendship.php +++ b/website/queries/friendship.php @@ -10,7 +10,8 @@ function selectLimitedFriends($userID, $limit) { $stmt = prepareQuery(" SELECT `userID`, - LEFT(`username`, 12) as `username`, + LEFT(`username`, 12) as `usernameshort`, + `username`, LEFT(CONCAT(`user`.`fname`, ' ', `user`.`lname`), 12) as `fullname`, IFNULL( `profilepicture`, @@ -50,7 +51,8 @@ function selectAllFriends($userID) { $stmt = prepareQuery(" SELECT `userID`, - LEFT(`username`, 12) as `username`, + LEFT(`username`, 12) as `usernameshort`, + `username`, LEFT(CONCAT(`user`.`fname`, ' ', `user`.`lname`), 12) as `fullname`, IFNULL( `profilepicture`, @@ -85,7 +87,8 @@ function selectAllFriendRequests() { $stmt = prepareQuery(" SELECT `userID`, - LEFT(`username`, 12) as `username`, + LEFT(`username`, 12) as `usernameshort`, + `username`, LEFT(CONCAT(`user`.`fname`, ' ', `user`.`lname`), 12) as `fullname`, IFNULL( `profilepicture`, @@ -235,8 +238,8 @@ function searchSomeFriends($n, $m, $search) { $stmt = prepareQuery(" SELECT `userID`, - - LEFT(`username`, 12) as `username`, + LEFT(`username`, 12) as `usernameshort`, + `username`, LEFT(CONCAT(`user`.`fname`, ' ', `user`.`lname`), 12) as `fullname`, IFNULL( `profilepicture`, diff --git a/website/queries/user.php b/website/queries/user.php index 72205ba..1e54763 100644 --- a/website/queries/user.php +++ b/website/queries/user.php @@ -349,7 +349,8 @@ function searchSomeUsers($n, $m, $search) { $stmt = prepareQuery(" SELECT `userID`, - LEFT(`username`, 12) as `username`, + LEFT(`username`, 12) as `usernameshort`, + `username`, IFNULL( `profilepicture`, '../img/avatar-standard.png' -- 2.49.1 From 86b02973e4887022619cff121379f9fd5da50998 Mon Sep 17 00:00:00 2001 From: "K. Nobel" Date: Thu, 2 Feb 2017 13:02:00 +0100 Subject: [PATCH 087/140] Fixed visibility on profiles --- website/public/profile.php | 6 ++++++ website/queries/user.php | 4 ++++ website/views/profile.php | 7 +++++-- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/website/public/profile.php b/website/public/profile.php index 05c661d..d9a317c 100644 --- a/website/public/profile.php +++ b/website/public/profile.php @@ -21,13 +21,19 @@ include_once("../queries/calcAge.php"); if(empty($_GET["username"])) { $userID = $_SESSION["userID"]; + $showProfile = True; } else { $userID = getUserID($_GET["username"]); + $showProfile = False; } $user = selectUser($_SESSION["userID"], $userID); $profile_friends = selectAllFriends($userID); $profile_groups = selectAllUserGroups($userID); +$showProfile = $showProfile || $user["showProfile"] || ($user["status"] == 'confirmed'); +echo " friendship status: " . $user["status"]; +echo " showprofile: $showProfile"; +echo " userID: " . $user["userID"]; if ($userID == $_SESSION["userID"]) { diff --git a/website/queries/user.php b/website/queries/user.php index 33a85a1..74b0aa1 100644 --- a/website/queries/user.php +++ b/website/queries/user.php @@ -65,6 +65,10 @@ function selectUser($me, $other) { `role`, `fname`, `lname`, + `showBday`, + `showEmail`, + `showProfile`, + `status`, CASE `status` IS NULL WHEN TRUE THEN 0 WHEN FALSE THEN diff --git a/website/views/profile.php b/website/views/profile.php index 2bb117f..1e88af8 100644 --- a/website/views/profile.php +++ b/website/views/profile.php @@ -15,16 +15,18 @@

      - " . $user["bio"] . "

      "; } ?>
      - 50) { + 50 and $showProfile) { echo "

      Bio:

      " . $user["bio"] . "

      "; } ?> +

      Informatie

      @@ -85,4 +87,5 @@

      + \ No newline at end of file -- 2.49.1 From 9d675dd897b01d2a5e4e13a124ab9944b2b63a46 Mon Sep 17 00:00:00 2001 From: "K. Nobel" Date: Thu, 2 Feb 2017 13:11:05 +0100 Subject: [PATCH 088/140] Fixed default image for group members. --- website/queries/group_page.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/website/queries/group_page.php b/website/queries/group_page.php index 511ff4d..b66ca54 100644 --- a/website/queries/group_page.php +++ b/website/queries/group_page.php @@ -81,7 +81,10 @@ function selectGroupMembers(int $groupID) { `username`, `fname`, `lname`, - `profilepicture` + IFNULL( + `profilepicture`, + '../img/avatar-standard.png' + ) AS profilepicture FROM `group_member` LEFT JOIN -- 2.49.1 From 044ed6a9d34345e54778ef1795611a51402521c1 Mon Sep 17 00:00:00 2001 From: Joey Lai Date: Thu, 2 Feb 2017 13:19:39 +0100 Subject: [PATCH 089/140] Added noscript --- website/public/styles/index.css | 8 +++++++- website/queries/checkInput.php | 2 +- website/views/facebookRegisterModal.php | 3 +-- website/views/login-view.php | 7 +++++++ 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/website/public/styles/index.css b/website/public/styles/index.css index 196485e..c7a0aa8 100644 --- a/website/public/styles/index.css +++ b/website/public/styles/index.css @@ -133,6 +133,12 @@ label { color: red; } +.login_containerNoscript { + padding: 4px; + text-align: center; + color: red; +} + @keyframes animatezoom { from {transform: scale(0)} to {transform: scale(1)} @@ -150,7 +156,7 @@ label { margin: 16px auto; overflow-y: auto; padding: 20px; - width: 600px; + width: 650px; } select{ diff --git a/website/queries/checkInput.php b/website/queries/checkInput.php index 8722418..69274ce 100644 --- a/website/queries/checkInput.php +++ b/website/queries/checkInput.php @@ -132,7 +132,7 @@ function validateFBEmail($variable){ } else if (!filter_var($variable, FILTER_VALIDATE_EMAIL)) { throw new emailException("Geldige email invullen"); } else if (getExistingFBEmail() == 1){ - throw new emailException("Email bestaal al!"); + throw new emailException("Uw email wordt al gebruikt voor een ander account!"); } else if (strlen($variable) > 255) { throw new emailException("Mag maximaal 50 karakters!"); } diff --git a/website/views/facebookRegisterModal.php b/website/views/facebookRegisterModal.php index 7db44b0..7271d63 100644 --- a/website/views/facebookRegisterModal.php +++ b/website/views/facebookRegisterModal.php @@ -55,7 +55,6 @@ * - + * - diff --git a/website/views/login-view.php b/website/views/login-view.php index 4f85b0a..98ce71c 100644 --- a/website/views/login-view.php +++ b/website/views/login-view.php @@ -1,3 +1,9 @@ +
      -- 2.49.1 From 417124a1fed22f85cd86615e83df488455baeb30 Mon Sep 17 00:00:00 2001 From: Lars van Hijfte Date: Thu, 2 Feb 2017 14:13:20 +0100 Subject: [PATCH 094/140] BUG FIX: added 0 in chat time if needed --- website/public/js/chat.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/website/public/js/chat.js b/website/public/js/chat.js index 1141334..a3ff430 100644 --- a/website/public/js/chat.js +++ b/website/public/js/chat.js @@ -59,7 +59,7 @@ function addMessages(messages) { for(var i in messages) { // Initialize message variables. var thisDate = new Date(messages[i].creationdate.replace(/ /,"T")); - var thisTime = thisDate.getHours() + ":" + thisDate.getMinutes(); + var thisTime = thisDate.getHours() + ":" + ('0' + thisDate.getMinutes()).slice(-2); var type; thisDate.setHours(0,0,0,0); @@ -81,6 +81,8 @@ function addMessages(messages) {
      '; } previousDate = thisDate; + previousTime = thisTime; + previousType = type; messagesText += '
      '; // If it is not the first message, and has a different date/time/type then the previous message, } else if (type != previousType || thisTime != previousTime || thisDate.getTime() > previousDate.getTime()) { -- 2.49.1 From 4a7a91ecd964f1cb0827765078314d04ac6534dc Mon Sep 17 00:00:00 2001 From: "K. Nobel" Date: Thu, 2 Feb 2017 14:20:17 +0100 Subject: [PATCH 095/140] Fixed bug (not showing profile when on own profile) --- website/public/profile.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/website/public/profile.php b/website/public/profile.php index d9a317c..aa4cf7c 100644 --- a/website/public/profile.php +++ b/website/public/profile.php @@ -21,19 +21,14 @@ include_once("../queries/calcAge.php"); if(empty($_GET["username"])) { $userID = $_SESSION["userID"]; - $showProfile = True; } else { $userID = getUserID($_GET["username"]); - $showProfile = False; } $user = selectUser($_SESSION["userID"], $userID); $profile_friends = selectAllFriends($userID); $profile_groups = selectAllUserGroups($userID); -$showProfile = $showProfile || $user["showProfile"] || ($user["status"] == 'confirmed'); -echo " friendship status: " . $user["status"]; -echo " showprofile: $showProfile"; -echo " userID: " . $user["userID"]; +$showProfile = $user["showProfile"] || ($user["status"] == 'confirmed') || $_SESSION["userID"] == $userID; if ($userID == $_SESSION["userID"]) { -- 2.49.1 From 188741ddf5ded574767a0115f06af8bd2a97487b Mon Sep 17 00:00:00 2001 From: Lars van Hijfte Date: Thu, 2 Feb 2017 14:22:13 +0100 Subject: [PATCH 096/140] BUG FIX: link in fancy text now opens in new tab --- website/public/js/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/public/js/main.js b/website/public/js/main.js index b6ab703..30cd3ed 100644 --- a/website/public/js/main.js +++ b/website/public/js/main.js @@ -31,7 +31,7 @@ function fancyText(text) { } // Add links else { - return "" + link + ""; + return "" + link + ""; } }); -- 2.49.1 From 1672ce6086deed96f1325a3044e9fe9c632adaf6 Mon Sep 17 00:00:00 2001 From: Lars van Hijfte Date: Thu, 2 Feb 2017 14:23:36 +0100 Subject: [PATCH 097/140] Changed offline status to 5 minutes after inactive --- website/queries/friendship.php | 8 ++++---- website/queries/user.php | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/website/queries/friendship.php b/website/queries/friendship.php index 7edada9..3dcd53b 100644 --- a/website/queries/friendship.php +++ b/website/queries/friendship.php @@ -17,7 +17,7 @@ function selectLimitedFriends($userID, $limit) { `profilepicture`, '../img/avatar-standard.png' ) AS profilepicture, - CASE `lastactivity` >= DATE_SUB(NOW(),INTERVAL 15 MINUTE) + CASE `lastactivity` >= DATE_SUB(NOW(),INTERVAL 5 MINUTE) WHEN TRUE THEN 'online' WHEN FALSE THEN 'offline' END AS `onlinestatus`, @@ -58,7 +58,7 @@ function selectAllFriends($userID) { `profilepicture`, '../img/avatar-standard.png' ) AS profilepicture, - CASE `lastactivity` >= DATE_SUB(NOW(),INTERVAL 15 MINUTE) + CASE `lastactivity` >= DATE_SUB(NOW(),INTERVAL 5 MINUTE) WHEN TRUE THEN 'online' WHEN FALSE THEN 'offline' END AS `onlinestatus`, @@ -94,7 +94,7 @@ function selectAllFriendRequests() { `profilepicture`, '../img/avatar-standard.png' ) AS profilepicture, - CASE `lastactivity` >= DATE_SUB(NOW(),INTERVAL 15 MINUTE) + CASE `lastactivity` >= DATE_SUB(NOW(),INTERVAL 5 MINUTE) WHEN TRUE THEN 'online' WHEN FALSE THEN 'offline' END AS `onlinestatus`, @@ -245,7 +245,7 @@ function searchSomeFriends($n, $m, $search) { `profilepicture`, '../img/avatar-standard.png' ) AS profilepicture, - CASE `lastactivity` >= DATE_SUB(NOW(),INTERVAL 15 MINUTE) + CASE `lastactivity` >= DATE_SUB(NOW(),INTERVAL 5 MINUTE) WHEN TRUE THEN 'online' WHEN FALSE THEN 'offline' END AS `onlinestatus`, diff --git a/website/queries/user.php b/website/queries/user.php index e8bda13..7b8ef3f 100644 --- a/website/queries/user.php +++ b/website/queries/user.php @@ -62,7 +62,7 @@ function selectUser($me, $other) { ) AS profilepicture, `bio`, `user`.`creationdate`, - CASE `lastactivity` >= DATE_SUB(NOW(),INTERVAL 15 MINUTE) + CASE `lastactivity` >= DATE_SUB(NOW(),INTERVAL 5 MINUTE) WHEN TRUE THEN 'online' WHEN FALSE THEN 'offline' END AS `onlinestatus`, @@ -131,7 +131,7 @@ function select20UsersFromN($n) { `username`, `role`, `bancomment`, - CASE `lastactivity` >= DATE_SUB(NOW(),INTERVAL 15 MINUTE) + CASE `lastactivity` >= DATE_SUB(NOW(),INTERVAL 5 MINUTE) WHEN TRUE THEN 'online' WHEN FALSE THEN 'offline' END AS `onlinestatus` @@ -156,7 +156,7 @@ function search20UsersFromN($n, $keyword) { `username`, `role`, `bancomment`, - CASE `lastactivity` >= DATE_SUB(NOW(),INTERVAL 15 MINUTE) + CASE `lastactivity` >= DATE_SUB(NOW(),INTERVAL 5 MINUTE) WHEN TRUE THEN 'online' WHEN FALSE THEN 'offline' END AS `onlinestatus` @@ -184,7 +184,7 @@ function search20UsersFromNByStatus($n, $keyword, $status) { `username`, `role`, `bancomment`, - CASE `lastactivity` >= DATE_SUB(NOW(),INTERVAL 15 MINUTE) + CASE `lastactivity` >= DATE_SUB(NOW(),INTERVAL 5 MINUTE) WHEN TRUE THEN 'online' WHEN FALSE THEN 'offline' END AS `onlinestatus` @@ -218,7 +218,7 @@ function searchSomeUsersByStatus($n, $m, $search, $status) { `username`, `role`, `bancomment`, - CASE `lastactivity` >= DATE_SUB(NOW(),INTERVAL 15 MINUTE) + CASE `lastactivity` >= DATE_SUB(NOW(),INTERVAL 5 MINUTE) WHEN TRUE THEN 'online' WHEN FALSE THEN 'offline' END AS `onlinestatus` @@ -362,7 +362,7 @@ function searchSomeUsers($n, $m, $search) { '../img/avatar-standard.png' ) AS profilepicture, LEFT(CONCAT(`user`.`fname`, ' ', `user`.`lname`), 12) as `fullname`, - CASE `lastactivity` >= DATE_SUB(NOW(),INTERVAL 15 MINUTE) + CASE `lastactivity` >= DATE_SUB(NOW(),INTERVAL 5 MINUTE) WHEN TRUE THEN 'online' WHEN FALSE THEN 'offline' END AS `onlinestatus` -- 2.49.1 From 6fc2f715176a34529d129a0f1a79d4d57f9ae659 Mon Sep 17 00:00:00 2001 From: Lars van Hijfte Date: Thu, 2 Feb 2017 14:27:23 +0100 Subject: [PATCH 098/140] Added meta data in the login page --- website/views/login_head.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/website/views/login_head.php b/website/views/login_head.php index e319a9d..bb7d7cf 100644 --- a/website/views/login_head.php +++ b/website/views/login_head.php @@ -1,5 +1,8 @@ - + + + + MyHyvesbook+ Date: Thu, 2 Feb 2017 14:50:51 +0100 Subject: [PATCH 099/140] Added "add group" under group menu --- website/views/menu.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/website/views/menu.php b/website/views/menu.php index dab8fce..1c1cf01 100644 --- a/website/views/menu.php +++ b/website/views/menu.php @@ -12,6 +12,8 @@ + +
      @@ -122,6 +122,7 @@ if (isset($_GET["groupstatus"])) { + Maak Owner"; + value=\"owner\">Maak Eigenaar"; } ?> @@ -139,9 +140,9 @@ if (isset($_GET["groupstatus"])) { onsubmit="adminUpdate(this); return false;"> - - - + + +
      -- 2.49.1 From cfa7c870f08417b80d5d7c285207deb0e94db228 Mon Sep 17 00:00:00 2001 From: Hendrik Date: Thu, 2 Feb 2017 15:13:35 +0100 Subject: [PATCH 104/140] fix profile error color --- website/public/styles/profile.css | 4 ++++ website/views/profile.php | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/website/public/styles/profile.css b/website/public/styles/profile.css index dbb3d24..46906d2 100644 --- a/website/public/styles/profile.css +++ b/website/public/styles/profile.css @@ -5,6 +5,10 @@ background-color: firebrick; } +.alerttext { + color: white; +} + .user-box { text-align: center; } diff --git a/website/views/profile.php b/website/views/profile.php index 7348642..4139099 100644 --- a/website/views/profile.php +++ b/website/views/profile.php @@ -1,6 +1,6 @@
      - +
      -- 2.49.1 From 8a3cfebf55bbc8380034c25741f52682beb2b9aa Mon Sep 17 00:00:00 2001 From: "K. Nobel" Date: Thu, 2 Feb 2017 15:34:45 +0100 Subject: [PATCH 105/140] Redirect to 404 from profile and group --- website/public/group.php | 9 ++++++++- website/public/profile.php | 7 ++++++- website/queries/group_page.php | 7 ++++++- website/queries/user.php | 4 +++- 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/website/public/group.php b/website/public/group.php index bb393e3..84726fa 100644 --- a/website/public/group.php +++ b/website/public/group.php @@ -13,9 +13,16 @@ include_once("../queries/group_page.php"); -$group = selectGroupByName($_GET["groupname"]); +if(!$group = selectGroupByName($_GET["groupname"])) { + header("HTTP/1.0 404 Not Found"); + header("Location: error/404.php"); + die(); +} + + $members = selectGroupMembers($group["groupID"]); + /* * This view adds the main layout over the screen. * Header, menu, footer. diff --git a/website/public/profile.php b/website/public/profile.php index aa4cf7c..126c87f 100644 --- a/website/public/profile.php +++ b/website/public/profile.php @@ -25,7 +25,12 @@ if(empty($_GET["username"])) { $userID = getUserID($_GET["username"]); } -$user = selectUser($_SESSION["userID"], $userID); +if(!$user = selectUser($_SESSION["userID"], $userID)) { + header("HTTP/1.0 404 Not Found"); + header("Location: error/404.php"); + die(); +} + $profile_friends = selectAllFriends($userID); $profile_groups = selectAllUserGroups($userID); $showProfile = $user["showProfile"] || ($user["status"] == 'confirmed') || $_SESSION["userID"] == $userID; diff --git a/website/queries/group_page.php b/website/queries/group_page.php index f2f028f..a6676c4 100644 --- a/website/queries/group_page.php +++ b/website/queries/group_page.php @@ -33,7 +33,12 @@ function selectGroupByName($name) { if (!$stmt->execute()) { return False; } - return $stmt->fetch(); + $row = $stmt->fetch(); + if($row["groupID"] == null) { + return False; + } + + return $row; } function selectGroupRole(int $groupID) { diff --git a/website/queries/user.php b/website/queries/user.php index 972937d..836c956 100644 --- a/website/queries/user.php +++ b/website/queries/user.php @@ -101,7 +101,9 @@ function selectUser($me, $other) { $stmt->bindParam(':me', $me, PDO::PARAM_INT); $stmt->bindParam(':other', $other, PDO::PARAM_INT); - $stmt->execute(); + if(!$stmt->execute() || $stmt->rowCount() == 0) { + return False; + } return $stmt->fetch(); } -- 2.49.1 From 1c53eab2fa77c02aaeb7340a38b053d38c0cf335 Mon Sep 17 00:00:00 2001 From: "K. Nobel" Date: Thu, 2 Feb 2017 15:50:12 +0100 Subject: [PATCH 106/140] Fixed user group list on profile page. --- website/queries/user.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/queries/user.php b/website/queries/user.php index 06487be..422edc4 100644 --- a/website/queries/user.php +++ b/website/queries/user.php @@ -122,7 +122,7 @@ function selectAllUserGroups($userID) { `group_page`.`groupID` = `group_member`.`groupID` WHERE `userID` = :userID AND - `role` = 'member' + `role` IN ('member', 'mod', 'admin') "); $stmt->bindParam(':userID', $userID, PDO::PARAM_INT); -- 2.49.1 From afb45d6709c6ddf640bac34844ac4e3ac8f38055 Mon Sep 17 00:00:00 2001 From: Hendrik Date: Thu, 2 Feb 2017 15:51:27 +0100 Subject: [PATCH 107/140] add closing of modal on escape key and clicking outside --- website/public/js/masonry.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/website/public/js/masonry.js b/website/public/js/masonry.js index a628e96..107f710 100644 --- a/website/public/js/masonry.js +++ b/website/public/js/masonry.js @@ -83,6 +83,21 @@ $(window).on("load", function() { loadMorePosts(userID, groupID, postAmount, postLimit); } }; + + $(document).keyup(function(e) { + if (e.keyCode == 27) { + closeModal(); + } + }); + + $('.modal').click(function() { + closeModal(); + }); + + $('.modal-content').click(function(event){ + event.stopPropagation(); + }); + }); function closeModal() { -- 2.49.1 From 380d8fa83a7ea8780f09fd8c1a8df7965b8f45b1 Mon Sep 17 00:00:00 2001 From: Marijn Jansen Date: Thu, 2 Feb 2017 16:01:45 +0100 Subject: [PATCH 108/140] Group Shit --- website/public/createGroup.php | 36 +++++++++++++++ website/public/groupAdmin.php | 46 ++++++++++++++++++++ website/queries/createGroup.php | 37 ++++++++++++++++ website/queries/groupAdmin.php | 61 ++++++++++++++++++++++++++ website/queries/picture.php | 12 ++--- website/views/createGroup.php | 42 ++++++++++++++++++ website/views/groupAdmin.php | 77 +++++++++++++++++++++++++++++++++ website/views/menu.php | 2 +- 8 files changed, 306 insertions(+), 7 deletions(-) create mode 100644 website/public/createGroup.php create mode 100644 website/public/groupAdmin.php create mode 100644 website/queries/createGroup.php create mode 100644 website/queries/groupAdmin.php create mode 100644 website/views/createGroup.php create mode 100644 website/views/groupAdmin.php diff --git a/website/public/createGroup.php b/website/public/createGroup.php new file mode 100644 index 0000000..ffeb6e3 --- /dev/null +++ b/website/public/createGroup.php @@ -0,0 +1,36 @@ + + + + + + + + + + + diff --git a/website/public/groupAdmin.php b/website/public/groupAdmin.php new file mode 100644 index 0000000..13ff7e0 --- /dev/null +++ b/website/public/groupAdmin.php @@ -0,0 +1,46 @@ + + + + + + + + +getClass(); + $alertMessage = $w->getMessage(); + } +} + +/* Add your view files here. */ +include("../views/groupAdmin.php"); + +/* This adds the footer. */ +include("../views/footer.php"); +?> + + diff --git a/website/queries/createGroup.php b/website/queries/createGroup.php new file mode 100644 index 0000000..20ee28b --- /dev/null +++ b/website/queries/createGroup.php @@ -0,0 +1,37 @@ +bindValue(':name', test_input($_POST["groupName"]), PDO::PARAM_STR); + $createGroup->bindValue(':description', test_input($_POST["bio"])); + $createGroup->execute(); + + $getGroupID = prepareQuery(" + SELECT + `groupID` + FROM + `group_page` + WHERE + `name` LIKE :name"); + $getGroupID->bindValue(':name', test_input($_POST["groupName"]), PDO::PARAM_STR); + $getGroupID->execute(); + $groupID = $getGroupID->fetch()["groupID"]; + + $makeUserAdmin = prepareQuery(" + INSERT INTO + `group_member` (userID, groupID, role) + VALUES (:userID, :groupID, 'admin') + "); + $makeUserAdmin->bindValue(":userID", $_SESSION["userID"]); + $makeUserAdmin->bindValue("groupID", $groupID); + $makeUserAdmin->execute(); + + updateAvatar($groupID); +} \ No newline at end of file diff --git a/website/queries/groupAdmin.php b/website/queries/groupAdmin.php new file mode 100644 index 0000000..ae2abd3 --- /dev/null +++ b/website/queries/groupAdmin.php @@ -0,0 +1,61 @@ +bindParam(":groupID", $groupID); + $stmt->execute(); + return $stmt->fetch(); +} + +function updateGroupSettings(int $groupID) +{ + if (!checkGroupAdmin($groupID, $_SESSION["userID"])) { + throw new AngryAlert("Je hebt geen rechten in deze groep"); + } + $stmt = prepareQuery(" + UPDATE + `group_page` + SET + `name` = :name, + `description` = :bio + WHERE + `groupID` = :groupID + "); + $stmt->bindValue(":bio", test_input($_POST["bio"])); + $stmt->bindValue(":name", test_input($_POST["name"])); + $stmt->bindValue(":groupID", test_input($_POST["groupID"])); + $stmt->execute(); + if ($stmt->rowCount()) { + throw new HappyAlert("Groep aangepast!"); + } else { + throw new AngryAlert("Er is iets mis gegaan"); + } +} + +function checkGroupAdmin(int $groupID, int $userID) : bool { + $stmt = prepareQuery(" + SELECT + `role` + FROM + `group_member` + WHERE + `groupID` = :groupID AND + `userID` = :userID + "); + $stmt->bindValue(":userID", $userID); + $stmt->bindValue(":groupID", $groupID); + $stmt->execute(); + if (!$stmt->rowCount()) { + return false; + } + $role = $stmt->fetch()["role"]; + return ($role == "admin"); +} \ No newline at end of file diff --git a/website/queries/picture.php b/website/queries/picture.php index 8e99d9a..ba27f72 100644 --- a/website/queries/picture.php +++ b/website/queries/picture.php @@ -6,7 +6,7 @@ * @throws AngryAlert * @throws HappyAlert */ -function updateAvatar(bool $group = false) { +function updateAvatar(int $group = 0) { $publicDir = "/var/www/html/public/"; $tmpImg = $_FILES["pp"]["tmp_name"]; $avatarDir = $group ? "uploads/groupavatar/" : "uploads/profilepictures/"; @@ -16,17 +16,17 @@ function updateAvatar(bool $group = false) { if ($_FILES["pp"]["size"] > 4000000) { throw new AngryAlert("Bestand is te groot, maximaal 4MB toegestaan."); } - $relativePath = $avatarDir . $_SESSION["userID"] . "_avatar.gif"; - $group ? removeOldGroupAvatar($_POST["groupID"]) : removeOldUserAvatar(); + $relativePath = $group ? $avatarDir . $group . "_avatar.gif" : $avatarDir . $_SESSION["userID"] . "_avatar.gif"; + $group ? removeOldGroupAvatar($group) : removeOldUserAvatar(); move_uploaded_file($tmpImg, $publicDir . $relativePath); } else { - $relativePath = $avatarDir . $_SESSION["userID"] . "_avatar.png"; + $relativePath = $group ? $avatarDir . $group . "_avatar.png": $avatarDir . $_SESSION["userID"] . "_avatar.png"; $scaledImg = scaleAvatar($tmpImg); - $group ? removeOldGroupAvatar($_POST["groupID"]) : removeOldUserAvatar(); + $group ? removeOldGroupAvatar($group) : removeOldUserAvatar(); imagepng($scaledImg, $publicDir . $relativePath); } - $group ? setGroupAvatarToDatabase("../" . $relativePath, $_POST["groupID"]) : setUserAvatarToDatabase("../" . $relativePath); + $group ? setGroupAvatarToDatabase("../" . $relativePath, $group) : setUserAvatarToDatabase("../" . $relativePath); throw new HappyAlert("Profielfoto veranderd."); } diff --git a/website/views/createGroup.php b/website/views/createGroup.php new file mode 100644 index 0000000..736fc45 --- /dev/null +++ b/website/views/createGroup.php @@ -0,0 +1,42 @@ + + +
      +
      +
      +
      Maak een groep!
      +
        +
      • + + +
      • +
      • + + +
      • +
      • + + +
      • +
      • + + +
      • +
      +
      +
      +
      diff --git a/website/views/groupAdmin.php b/website/views/groupAdmin.php new file mode 100644 index 0000000..66b38f5 --- /dev/null +++ b/website/views/groupAdmin.php @@ -0,0 +1,77 @@ + +
      +
      + +
      + +
      + +
      +
      Groep Instellingen
      + "> +
        +
      • + + " + > +
      • +
      • + + + +
      • +
      • + + +
      • +
      +
      +
      +
      Verander groepsafbeelding.
      + "> +
        +
      • + + " + class="group-picture" + > +
      • +
      • + + +
      • +
      • + + +
      • +
      +
      +
      +
      \ No newline at end of file diff --git a/website/views/menu.php b/website/views/menu.php index dab8fce..03e0f56 100644 --- a/website/views/menu.php +++ b/website/views/menu.php @@ -14,7 +14,7 @@
    +
    + +
    \ No newline at end of file -- 2.49.1 From 74e91ed7cb18acebaabd5b6356f87aec25830977 Mon Sep 17 00:00:00 2001 From: Marijn Jansen Date: Thu, 2 Feb 2017 21:14:25 +0100 Subject: [PATCH 114/140] Add mods/admin to a group. --- website/public/groupAdmin.php | 27 ++++++++++++++----- website/queries/groupAdmin.php | 48 ++++++++++++++++++++++++++++++++++ website/queries/settings.php | 15 +++++++++++ website/views/groupAdmin.php | 29 ++++++++++++++++++++ 4 files changed, 113 insertions(+), 6 deletions(-) diff --git a/website/public/groupAdmin.php b/website/public/groupAdmin.php index 13ff7e0..6095149 100644 --- a/website/public/groupAdmin.php +++ b/website/public/groupAdmin.php @@ -23,12 +23,27 @@ $alertClass; $alertMessage; if ($_SERVER["REQUEST_METHOD"] == "POST") { try { - if ($_POST["form"] == "group") { - updateGroupSettings($_POST["groupID"]); - } else if ($_POST["form"] == "picture") { - if (checkGroupAdmin($_POST["groupID"], $_SESSION["userID"])) { - updateAvatar($_POST["groupID"]); - } + switch ($_POST["form"]) { + case "group": + updateGroupSettings($_POST["groupID"]); + break; + case "picture": + if (checkGroupAdmin($_POST["groupID"], $_SESSION["userID"])) { + updateAvatar($_POST["groupID"]); + } + break; + case "mod": + if (!array_key_exists("userID", $_POST)) { + throw new AngryAlert("Geen gebruiker geselecteerd."); + } + upgradeUser($_POST["groupID"], $_POST["userID"], "mod"); + break; + case "admin": + if (!array_key_exists("userID", $_POST)) { + throw new AngryAlert("Geen gebruiker geselecteerd."); + } + upgradeUser($_POST["groupID"], $_POST["userID"], "admin"); + break; } } catch (AlertMessage $w) { $alertClass = $w->getClass(); diff --git a/website/queries/groupAdmin.php b/website/queries/groupAdmin.php index ae2abd3..e3580b6 100644 --- a/website/queries/groupAdmin.php +++ b/website/queries/groupAdmin.php @@ -58,4 +58,52 @@ function checkGroupAdmin(int $groupID, int $userID) : bool { } $role = $stmt->fetch()["role"]; return ($role == "admin"); +} + +function getAllGroupMembers(int $groupID) { + $stmt = prepareQuery(" + SELECT + `username`, + `user`.`userID`, + CONCAT(`fname`, ' ', `lname`) AS `fullname`, + `group_member`.`role` + FROM + `group_member` + LEFT JOIN + `user` + ON + `group_member`.`userID` = `user`.`userID` + WHERE + `groupID` = :groupID AND `group_member`.`role` = 'member' + "); + + $stmt->bindParam(':groupID', $groupID); + if (!$stmt->execute()) { + return False; + } + return $stmt->fetchAll(); +} + +function upgradeUser(int $groupID, int $userID, string $role) { + if (!checkGroupAdmin($groupID, $_SESSION["userID"])) { + throw new AngryAlert("Geen toestemming om te wijzigen"); + } + + $stmt = prepareQuery(" + UPDATE + `group_member` + SET + `role` = :role + WHERE + `userID` = :userID AND `groupID` = :groupID + "); + $stmt->bindValue(":groupID", $groupID); + $stmt->bindValue(":userID", $userID); + $stmt->bindValue(":role", $role); + $stmt->execute(); + if ($stmt->rowCount()) { + throw new HappyAlert("Permissie aangepast!"); + } else { + throw new AngryAlert("Er is iets mis gegaan"); + } } \ No newline at end of file diff --git a/website/queries/settings.php b/website/queries/settings.php index 9b17d17..26237ec 100644 --- a/website/queries/settings.php +++ b/website/queries/settings.php @@ -148,6 +148,10 @@ function doChangePassword() { } } +/** + * Changes the users email if it is valid. + * @throws AngryAlert + */ function changeEmail() { if (test_input($_POST["email"]) == test_input($_POST["email-confirm"])) { @@ -164,6 +168,11 @@ function changeEmail() { } } +/** + * Checks if an emailadres is available in the database. + * @param $email + * @throws AngryAlert + */ function emailIsAvailableInDatabase($email) { $stmt = prepareQuery(" SELECT @@ -181,6 +190,12 @@ function emailIsAvailableInDatabase($email) { } } +/** + * Does the actual changing of an email-adress. + * @param $email + * @throws AngryAlert + * @throws HappyAlert + */ function doChangeEmail($email) { $stmt = prepareQuery(" UPDATE diff --git a/website/views/groupAdmin.php b/website/views/groupAdmin.php index a28553e..54fbee8 100644 --- a/website/views/groupAdmin.php +++ b/website/views/groupAdmin.php @@ -85,6 +85,35 @@ $groupinfo = getGroupSettings($_GET["groupID"]);
  • +
    +
    Voeg een admin/mod toe
    +
      + + " type="hidden"> + + + + + +
    +
    • -- 2.49.1 From 7e4107ac8b357bc1335c9657293182a5ce18720c Mon Sep 17 00:00:00 2001 From: Lars van Hijfte Date: Fri, 3 Feb 2017 00:13:23 +0100 Subject: [PATCH 115/140] Added fancy buttons in profile --- website/public/js/friendButtons.js | 28 +++++++++++++++------------- website/public/js/groupButtons.js | 12 ++++++------ website/public/styles/post-popup.css | 12 ------------ website/public/styles/profile.css | 19 ++++++++++++------- website/views/post-view.php | 4 ++-- website/views/profile.php | 14 ++++++++++---- 6 files changed, 45 insertions(+), 44 deletions(-) diff --git a/website/public/js/friendButtons.js b/website/public/js/friendButtons.js index 47c476a..303ccf9 100644 --- a/website/public/js/friendButtons.js +++ b/website/public/js/friendButtons.js @@ -19,24 +19,24 @@ function placeFriendButtons() { case "0": value1 = "request"; class1 = "green"; - text1 = "Bevriend"; - icon1 = "fa-handshake-o"; + text1 = "Word vrienden"; + icon1 = "fa-user-plus"; break; case "1": value1 = userID; class1 = "green"; text1 = "Chat"; - icon1 = "fa-comment-o"; + icon1 = "fa-comment"; value2 = "delete"; class2 = "red"; - text2 = "Verwijder"; - icon2 = "fa-times"; + text2 = "Ontvriend"; + icon2 = "fa-user-times"; break; case "2": value1 = "delete"; class1 = "red"; text1 = "Trek verzoek in"; - icon1 = "fa-cross"; + icon1 = "fa-times"; break; case "3": value1 = "accept"; @@ -51,16 +51,18 @@ function placeFriendButtons() { } $buttonContainer.append( - ""); + "
      "); $buttonContainer.append( - ""); + "
      "); - $buttonContainer.children().click(function() { + $buttonContainer.find("button").click(function() { if (isNaN(this.value)) editFriendship(userID, this.value); else if (this.value != "") diff --git a/website/public/js/groupButtons.js b/website/public/js/groupButtons.js index 549277d..caf3ab8 100644 --- a/website/public/js/groupButtons.js +++ b/website/public/js/groupButtons.js @@ -5,23 +5,23 @@ function placeGroupButtons() { if (data == 'none') { $buttonContainer.append( - ""); } else if (data == 'request') { $buttonContainer.append( - ""); } else if (data == 'admin') { $buttonContainer.append( - "" ); } else { $buttonContainer.append( - ""); } diff --git a/website/public/styles/post-popup.css b/website/public/styles/post-popup.css index 9493b83..e82129b 100644 --- a/website/public/styles/post-popup.css +++ b/website/public/styles/post-popup.css @@ -92,16 +92,4 @@ .deleteButton { background-color: firebrick; float: right; -} - -.deleteButton i { - display: inline-block; -} - -.deleteButton:hover span { - display: inline-block; -} - -.deleteButton span { - display: none; } \ No newline at end of file diff --git a/website/public/styles/profile.css b/website/public/styles/profile.css index 18e105e..8a93d12 100644 --- a/website/public/styles/profile.css +++ b/website/public/styles/profile.css @@ -27,16 +27,21 @@ display: inline-block; } +.friend-button-container div, .status-buttons-container div { + width: 200px; + display: inline-block; +} + .friend-button-container button, .status-buttons-container button, .group-button-container button { display: block; + float: right; margin: 7px 0; font-size: 18px; } - -.friend-button-container button, .status-buttons-container button, .group-button-fixed { - width: 200px; +.status-buttons-container button { + float: left; } .group-button-container button { @@ -76,19 +81,19 @@ border: none; } -.group-button-fancy span { +.fancy-button span { display: none; } -.group-button-fancy:hover { +.fancy-button:hover { text-align: right; } -.group-button-fancy i { +.fancy-button i { display: inline-block; } -.group-button-fancy:hover span { +.fancy-button:hover span { display: inline-block; margin-right: 5px; } diff --git a/website/views/post-view.php b/website/views/post-view.php index 717e6a8..fadc791 100644 --- a/website/views/post-view.php +++ b/website/views/post-view.php @@ -13,11 +13,11 @@ $fullname = $post['fname'] . " " . $post['lname'] . " (" . $post['username'] . "
    -
    diff --git a/website/views/profile.php b/website/views/profile.php index 62157f4..0cb5cc2 100644 --- a/website/views/profile.php +++ b/website/views/profile.php @@ -7,10 +7,16 @@ <?= $user[" class="profile-picture main-picture " src="">
    - - +
    + +
    +
    + +

    :)

    -- 2.49.1 From 6d739a4480019709d6abe9addea37ade0ebbc34d Mon Sep 17 00:00:00 2001 From: Lars van Hijfte Date: Fri, 3 Feb 2017 00:24:38 +0100 Subject: [PATCH 116/140] Chat is now only loading the last 100 messages --- website/queries/private_message.php | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/website/queries/private_message.php b/website/queries/private_message.php index 3b88563..f2df887 100644 --- a/website/queries/private_message.php +++ b/website/queries/private_message.php @@ -6,18 +6,23 @@ function getOldChatMessages($user2ID) { if (getFriendshipStatus($user2ID) == 1) { $stmt = prepareQuery(" SELECT - * + * FROM - `private_message` - WHERE - `origin` = :user1 AND - `destination` = :user2 OR - `origin` = :user2 AND - `destination` = :user1 + (SELECT + * + FROM + `private_message` + WHERE + `origin` = :user1 AND + `destination` = :user2 OR + `origin` = :user2 AND + `destination` = :user1 + ORDER BY + `messageID` DESC + LIMIT + 100) sub ORDER BY - `creationdate` ASC - LIMIT - 100 + `messageID` ASC "); $stmt->bindParam(":user1", $user1ID); @@ -76,7 +81,7 @@ function getNewChatMessages($lastID, $destination) { `destination` = :user1) AND `messageID` > :lastID ORDER BY - `creationdate` ASC + `messageID` ASC "); $stmt->bindParam(':user1', $_SESSION["userID"]); -- 2.49.1 From 1a3efe9669089acffc404151616d26b1d3f9d984 Mon Sep 17 00:00:00 2001 From: Joey Lai Date: Fri, 3 Feb 2017 10:12:37 +0100 Subject: [PATCH 117/140] Fixed W3Validation and url GETs --- website/public/fb-callback.php | 71 -------------- website/public/register(stash).php | 116 ----------------------- website/public/styles/index.css | 6 -- website/queries/checkInput.php | 6 +- website/queries/login.php | 7 +- website/views/facebookRegisterModal.php | 8 +- website/{public => views}/fbRegister.php | 0 website/views/forgotPasswordModal.php | 4 +- website/views/homeLoginRegister.php | 38 ++++---- website/views/login-view.php | 13 ++- website/{public => views}/register.php | 0 website/views/registerModal.php | 13 +-- 12 files changed, 43 insertions(+), 239 deletions(-) delete mode 100644 website/public/fb-callback.php delete mode 100644 website/public/register(stash).php rename website/{public => views}/fbRegister.php (100%) rename website/{public => views}/register.php (100%) diff --git a/website/public/fb-callback.php b/website/public/fb-callback.php deleted file mode 100644 index 0ed0369..0000000 --- a/website/public/fb-callback.php +++ /dev/null @@ -1,71 +0,0 @@ - $appID, // Replace {app-id} with your app id - 'app_secret' => $appSecret, - 'default_graph_version' => 'v2.2', -]); - -$helper = $fb->getRedirectLoginHelper(); - -try { - $accessToken = $helper->getAccessToken(); -} catch(Facebook\Exceptions\FacebookResponseException $e) { - // When Graph returns an error - echo 'Graph returned an error: ' . $e->getMessage(); - exit; -} catch(Facebook\Exceptions\FacebookSDKException $e) { - // When validation fails or other local issues - echo 'Facebook SDK returned an error: ' . $e->getMessage(); - exit; -} - -if (! isset($accessToken)) { - if ($helper->getError()) { - header('HTTP/1.0 401 Unauthorized'); - echo "Error: " . $helper->getError() . "\n"; - echo "Error Code: " . $helper->getErrorCode() . "\n"; - echo "Error Reason: " . $helper->getErrorReason() . "\n"; - echo "Error Description: " . $helper->getErrorDescription() . "\n"; - } else { - header('HTTP/1.0 400 Bad Request'); - echo 'Bad request'; - } - exit; -} - -// Logged in -echo '

    Access Token

    '; -var_dump($accessToken->getValue()); - -// The OAuth 2.0 client handler helps us manage access tokens -$oAuth2Client = $fb->getOAuth2Client(); - -// Get the access token metadata from /debug_token -$tokenMetadata = $oAuth2Client->debugToken($accessToken); -echo '

    Metadata

    '; -var_dump($tokenMetadata); - -// Validation (these will throw FacebookSDKException's when they fail) -$tokenMetadata->validateAppId($appID); // Replace {app-id} with your app id -// If you know the user ID this access token belongs to, you can validate it here -//$tokenMetadata->validateUserId('123'); -$tokenMetadata->validateExpiration(); - -if (! $accessToken->isLongLived()) { - // Exchanges a short-lived access token for a long-lived one - try { - $accessToken = $oAuth2Client->getLongLivedAccessToken($accessToken); - } catch (Facebook\Exceptions\FacebookSDKException $e) { - echo "

    Error getting long-lived access token: " . $helper->getMessage() . "

    \n\n"; - exit; - } - - echo '

    Long-lived

    '; - var_dump($accessToken->getValue()); -} - -$_SESSION['fb_access_token'] = (string) $accessToken; - -// User is logged in with a long-lived access token. -// You can redirect them to a members-only page. -//header('Location: https://example.com/members.php'); \ No newline at end of file diff --git a/website/public/register(stash).php b/website/public/register(stash).php deleted file mode 100644 index 99ebc02..0000000 --- a/website/public/register(stash).php +++ /dev/null @@ -1,116 +0,0 @@ - - - - -getMessage(); - } - - try { - $surname = test_input(($_POST["surname"])); - checkInputChoice($surname, "lettersAndSpaces"); - } - catch(lettersAndSpacesException $e){ - $correct = false; - $surnameErr = $e->getMessage(); - } - - try{ - $day_date = test_input(($_POST["day_date"])); - $month_date = test_input(($_POST["month_date"])); - $year_date = test_input(($_POST["year_date"])); - $bday = $year_date . "-" . $month_date . "-" . $day_date; - checkInputChoice($bday, "bday"); - } catch(bdayException $e){ - $correct = false; - $bdayErr = $e->getMessage(); - } - - try{ - $username = str_replace(' ', '', test_input(($_POST["username"]))); - checkInputChoice($username, "username"); - } catch(usernameException $e){ - $correct = false; - $usernameErr = $e->getMessage(); - } - - try{ - $password = str_replace(' ', '', test_input(($_POST["password"]))); - checkInputChoice($password, "longerEight"); - matchPassword(); - } catch(passwordException $e){ - $correct = false; - $passwordErr = $e->getMessage(); - } catch(confirmPasswordException $e){ - $correct = false; - $confirmPasswordErr = $e->getMessage(); - } - - try{ - $location = test_input(($_POST["location"])); - checkInputChoice($location, "lettersAndSpaces"); - } catch(lettersAndSpacesException $e){ - $correct = false; - $locationErr = $e->getMessage(); - } - - try{ - $email = test_input(($_POST["email"])); - checkInputChoice($email, "email"); - $confirmEmail = test_input(($_POST["confirmEmail"])); - matchEmail(); - } catch(emailException $e){ - $correct = false; - $emailErr = $e->getMessage(); - } catch(confirmEmailException $e){ - $correct = false; - $confirmEmailErr = $e->getMessage(); - } - - try{ - $captcha = $_POST['g-recaptcha-response']; - checkCaptcha($captcha); - } catch(captchaException $e){ - $correct = false; - $captchaErr = $e->getMessage(); - } - - try { - getIp(); - registerCheck($correct); - sendConfirmEmailUsername($username); - } catch(registerException $e){ - $genericErr = $e->getMessage(); - } - } -/* This view adds register view */ -include("../views/register-view.php"); -?> - - diff --git a/website/public/styles/index.css b/website/public/styles/index.css index c7a0aa8..68191ad 100644 --- a/website/public/styles/index.css +++ b/website/public/styles/index.css @@ -198,12 +198,6 @@ ul { animation-duration: 0.4s } -/* Add Animation */ -@-webkit-keyframes animatetop { - from {top:-300px; opacity:0} - to {top:0; opacity:1} -} - @keyframes animatetop { from {top:-300px; opacity:0} to {top:0; opacity:1} diff --git a/website/queries/checkInput.php b/website/queries/checkInput.php index 69274ce..247050b 100644 --- a/website/queries/checkInput.php +++ b/website/queries/checkInput.php @@ -68,7 +68,7 @@ function validateBday($variable){ } } -// Checks for date +/* Checks for date */ function validateDate($date, $format) { $d = DateTime::createFromFormat($format, $date); @@ -124,7 +124,7 @@ function validateEmail($variable){ throw new emailException("Mag maximaal 50 karakters!"); } } -//255 + /* checks if an input is a valid email. */ function validateFBEmail($variable){ if (empty($variable)) { @@ -138,6 +138,7 @@ function validateFBEmail($variable){ } } +/* checks if email is the same */ function matchEmail(){ if (strtolower($_POST["email"]) != strtolower($_POST["confirmEmail"])){ throw new confirmEmailException("Emails matchen niet!"); @@ -153,7 +154,6 @@ function resetEmail($variable){ } } - /* checks if two passwords matches. */ function matchPassword(){ if ($_POST["password"] != $_POST["confirmpassword"]) { diff --git a/website/queries/login.php b/website/queries/login.php index 27c1f3b..3480991 100644 --- a/website/queries/login.php +++ b/website/queries/login.php @@ -1,5 +1,6 @@ @@ -75,8 +77,9 @@ function validateLogin($username, $password, $url){ $_SESSION["userID"] = $userID; if(!isset($url) or $url == "") { header("location: profile.php"); + echo "succes"; } else{ - header("location: $url"); + header("location: ".$url); } } diff --git a/website/views/facebookRegisterModal.php b/website/views/facebookRegisterModal.php index 7271d63..a38a3a3 100644 --- a/website/views/facebookRegisterModal.php +++ b/website/views/facebookRegisterModal.php @@ -1,7 +1,6 @@
    - * +
    - + diff --git a/website/public/fbRegister.php b/website/views/fbRegister.php similarity index 100% rename from website/public/fbRegister.php rename to website/views/fbRegister.php diff --git a/website/views/forgotPasswordModal.php b/website/views/forgotPasswordModal.php index 2ebdbb9..ebb9d64 100644 --- a/website/views/forgotPasswordModal.php +++ b/website/views/forgotPasswordModal.php @@ -4,7 +4,6 @@ diff --git a/website/views/homeLoginRegister.php b/website/views/homeLoginRegister.php index 55277e7..ad7be40 100644 --- a/website/views/homeLoginRegister.php +++ b/website/views/homeLoginRegister.php @@ -11,16 +11,16 @@ if(isset($_SESSION["userID"])){ // Facebook variables $appID = "353857824997532"; $appSecret = "db47e91ffbfd355fdd11b4b65eade851"; -$fbUsername = $fbPassword = $fbConfirmpassword = ""; +$fbUsername = $fbPassword = $fbConfirmpassword = $fbName = $fbSurname = $fbBday = $fbEmail = $fbUserID = ""; $fbUsernameErr = $fbPasswordErr = $fbConfirmpasswordErr = $fbEmailErr = $fbBdayErr = ""; $fbCorrect = true; -$fbName = $fbSurname = $fbBday = $fbEmail = $fbUserID = ""; // Register variables $name = $surname = $bday = $username = $password = $confirmpassword = $location = $housenumber = $email = $confirmEmail = $captcha = $ip = ""; $genericErr = $nameErr = $surnameErr = $bdayErr = $usernameErr = $passwordErr = $confirmpasswordErr = $locationErr = $housenumberErr = $emailErr = $confirmEmailErr = $captchaErr = ""; $correct = true; +// Bday dates $day_date = $month_date = $year_date = ""; $fbDay_date = $fbMonth_date = $fbYear_date = ""; @@ -28,22 +28,14 @@ $fbDay_date = $fbMonth_date = $fbYear_date = ""; $user = $psw = $remember =""; $loginErr = $resetErr = $fbRegisterErr =""; -//if ($_SERVER["REQUEST_METHOD"] == "GET") { -// try { -// $user = ($_POST["user"]); -// validateLogin($_POST["user"], $_POST["psw"], "https://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"); -// } catch(loginException $e) { -// $loginErr = $e->getMessage(); -// } -//} - if ($_SERVER["REQUEST_METHOD"] == "POST") { + $url = $_POST["url"]; // Checks for which button is pressed switch ($_POST["submit"]) { case "login": try { $user = ($_POST["user"]); - validateLogin($_POST["user"], $_POST["psw"], $_POST["url"]); + validateLogin($_POST["user"], $_POST["psw"], $url); } catch(loginException $e) { $loginErr = $e->getMessage(); } @@ -62,18 +54,22 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") { } break; case "register": - include("register.php"); + include("../views/register.php"); break; case "fbRegister": - include("fbRegister.php"); + include("../views/fbRegister.php"); break; } } + +// Get facebook information with facebook PHP SDK. $fb = new Facebook\Facebook([ 'app_id' => $appID, 'app_secret' => $appSecret, 'default_graph_version' => 'v2.2', ]); + +// Redirect back to login.php after logging/canceling with facebook. $redirect = "https://myhyvesbookplus.nl/login.php"; $helper = $fb->getRedirectLoginHelper(); @@ -88,6 +84,7 @@ try { exit; } +// If theres no facebook account logged in, ask for permission. if(!isset($acces_token)){ $permission=["email", "user_birthday"]; $loginurl=$helper->getLoginUrl($redirect,$permission); @@ -96,13 +93,14 @@ if(!isset($acces_token)){ $response = $fb->get('/me?fields=email,name,birthday'); $usernode = $response->getGraphUser(); + // Get facebook information $nameSplit = explode(" ", $usernode->getName()); $fbName = $nameSplit[0]; $fbSurname = $nameSplit[1]; $fbUserID = $usernode->getID(); $fbEmail = $usernode->getProperty("email"); -// $image = 'https://graph.facebook.com/' . $usernode->getId() . '/picture?width=200'; + // If there is an account, check if the account is banned or frozen. if (fbLogin($fbUserID) == 1) { $fbID = getfbUserID($fbUserID)["userID"]; $fbRole = getfbUserID($fbUserID)["role"]; @@ -110,16 +108,20 @@ if(!isset($acces_token)){ echo ""; + } else if($fbRole == "frozen"){ $_SESSION["userID"] = $fbID; echo ""; + window.onload=frozenAlert(); + window.location.href= 'profile.php'; + "; + } else { $_SESSION["userID"] = $fbID; header("location: profile.php"); + } + // Registration with faceobook if theres no account. } else { echo " diff --git a/website/views/login_head.php b/website/views/login_head.php index 9e580df..e8e3a84 100644 --- a/website/views/login_head.php +++ b/website/views/login_head.php @@ -3,6 +3,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyHyvesbook+ Date: Fri, 3 Feb 2017 11:47:16 +0100 Subject: [PATCH 134/140] Added fbModal button --- website/public/js/loginRegisterModals.js | 5 ++++- website/views/facebookRegisterModal.php | 6 ++++++ website/views/homeLoginRegister.php | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/website/public/js/loginRegisterModals.js b/website/public/js/loginRegisterModals.js index 373fb7e..104dd02 100644 --- a/website/public/js/loginRegisterModals.js +++ b/website/public/js/loginRegisterModals.js @@ -7,7 +7,7 @@ var facebookModal = document.getElementById("fbModal"); // Get the button that opens the modal var registerBtn = document.getElementById("registerBtn"); var btn = document.getElementById("myBtn"); - +var fbBtn = document.getElementById("fbBtn"); // Get the element that closes the modal var span = document.getElementsByClassName("close")[0]; @@ -24,6 +24,9 @@ btn.onclick = function () { registerBtn.onclick = function () { registerModal.style.display = "block"; } +fbBtn.onclick = function () { + facebookModal.style.display = "block"; +} /** * WHen the user clicks on (X), close the modal diff --git a/website/views/facebookRegisterModal.php b/website/views/facebookRegisterModal.php index a38a3a3..17ce7ef 100644 --- a/website/views/facebookRegisterModal.php +++ b/website/views/facebookRegisterModal.php @@ -1,3 +1,9 @@ +Facebook registreer'; + +} +?> -- 2.49.1 From fb5f76c4993cab6d41ab7be8c246452a2f49a207 Mon Sep 17 00:00:00 2001 From: Lars van Hijfte Date: Fri, 3 Feb 2017 12:32:57 +0100 Subject: [PATCH 137/140] ? --- website/public/js/profile.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 website/public/js/profile.js diff --git a/website/public/js/profile.js b/website/public/js/profile.js deleted file mode 100644 index e69de29..0000000 -- 2.49.1 From 1ac6a7da87e1637e195e596f111df74c8742d8af Mon Sep 17 00:00:00 2001 From: Lars van Hijfte Date: Fri, 3 Feb 2017 12:40:33 +0100 Subject: [PATCH 138/140] Changed admin checkbox buttons --- website/public/styles/adminpanel.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website/public/styles/adminpanel.css b/website/public/styles/adminpanel.css index 888b4ca..d04d8fa 100644 --- a/website/public/styles/adminpanel.css +++ b/website/public/styles/adminpanel.css @@ -1,9 +1,9 @@ .admin-panel input[type="radio"], input[type="checkbox"] { vertical-align: middle; - height: 28px; - width: 28px; - margin: 2px; + height: 14px; + width: 14px; + margin: 7px; } .table-checkbox { -- 2.49.1 From 4643dfcddb4f8ef314168cb0851c811d559d57bd Mon Sep 17 00:00:00 2001 From: Joey Lai Date: Fri, 3 Feb 2017 12:42:30 +0100 Subject: [PATCH 139/140] Fixed comments and links --- website/queries/register.php | 31 +++++++++++++++++++++++++++++ website/queries/requestpassword.php | 18 +++++++++++++++-- website/views/homeLoginRegister.php | 2 +- 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/website/queries/register.php b/website/queries/register.php index 3dcbed4..7f91dfa 100644 --- a/website/queries/register.php +++ b/website/queries/register.php @@ -1,5 +1,9 @@ rowCount(); } +/** + * Registers a new account with facebook register + */ function fbRegisterAccount() { $stmt = prepareQuery(" INSERT INTO @@ -158,6 +184,11 @@ function fbRegisterAccount() { return $stmt->execute(); } +/** + * Checks which dates need to be selected when there is an invalid registration. + * @param $date + * @param $value + */ function submitselect($date, $value){ if ($date == $value){ echo "selected"; diff --git a/website/queries/requestpassword.php b/website/queries/requestpassword.php index a54bd7d..daad355 100644 --- a/website/queries/requestpassword.php +++ b/website/queries/requestpassword.php @@ -1,6 +1,10 @@ getRedirectLoginHelper(); try { -- 2.49.1 From 7cc6450e6afde743509fcc83b3e8dadf0415509e Mon Sep 17 00:00:00 2001 From: "K. Nobel" Date: Fri, 3 Feb 2017 13:19:00 +0100 Subject: [PATCH 140/140] Added comments to javascript code. --- website/public/js/friendButtons.js | 8 +++++- website/public/js/groupButtons.js | 5 ++++ website/public/js/masonry.js | 44 +++++++++++++++++++----------- 3 files changed, 40 insertions(+), 17 deletions(-) diff --git a/website/public/js/friendButtons.js b/website/public/js/friendButtons.js index 47c476a..440dfe5 100644 --- a/website/public/js/friendButtons.js +++ b/website/public/js/friendButtons.js @@ -1,6 +1,8 @@ +// Show the right friendship buttonsto the user. function placeFriendButtons() { $.post("API/getFriendshipStatus.php", { usr: userID }) .done(function(data) { + //save the friendship status var friendshipStatus = data; var $buttonContainer = $("div.friend-button-container"); $("#start-profile-chat").hide(); @@ -22,6 +24,7 @@ function placeFriendButtons() { text1 = "Bevriend"; icon1 = "fa-handshake-o"; break; + // Users are friends. case "1": value1 = userID; class1 = "green"; @@ -32,12 +35,14 @@ function placeFriendButtons() { text2 = "Verwijder"; icon2 = "fa-times"; break; + // This user sent request. case "2": value1 = "delete"; class1 = "red"; text1 = "Trek verzoek in"; icon1 = "fa-cross"; break; + // Other user sent request. case "3": value1 = "accept"; class1 = "green"; @@ -50,6 +55,7 @@ function placeFriendButtons() { break; } + // Append buttons to the container. $buttonContainer.append( ""); - + // Gets triggered when a friend button is triggered. $buttonContainer.children().click(function() { if (isNaN(this.value)) editFriendship(userID, this.value); diff --git a/website/public/js/groupButtons.js b/website/public/js/groupButtons.js index e6ada67..ab86e8c 100644 --- a/website/public/js/groupButtons.js +++ b/website/public/js/groupButtons.js @@ -3,16 +3,20 @@ function placeGroupButtons() { .done(function(data) { var $buttonContainer = $("div.group-button-container"); + // Append the right group button to the button container. + // When user is not a member if(data == 'none') { $buttonContainer.append( ""); + // when user sent a request to become a member. } else if(data == 'request') { $buttonContainer.append( ""); + // When user is a member of the group. } else { $buttonContainer.append( ""); } + // Gets triggered when a group button is clicked. $buttonContainer.children().click(function() { $.post("API/editMembership.php", { grp: groupID, role: this.value }) .done(function() { diff --git a/website/public/js/masonry.js b/website/public/js/masonry.js index a628e96..eeb5cf7 100644 --- a/website/public/js/masonry.js +++ b/website/public/js/masonry.js @@ -1,3 +1,4 @@ +// Vertical margin between two posts. margin = 20; // scrolling modal taken from http://stackoverflow.com/questions/10476632/how-to-scroll-the-page-when-a-modal-dialog-is-longer-than-the-screen @@ -11,9 +12,12 @@ function scrollbarMargin(width, overflow) { }); } +// Get post from the server. function requestPost(postID) { + // Make the modal view visible. $(".modal").show(); + // Send get request to the server to load the post. $.get("API/loadPost.php", { postID : postID }).done(function(data) { $('.modal-default').hide(); var scrollBarWidth = window.innerWidth - document.body.offsetWidth; @@ -23,11 +27,14 @@ function requestPost(postID) { }); } +// Create a new post. function postPost() { title = $("input.newpost[name='title']").val(); content = $("textarea.newpost[name='content']").val(); + // Masonrymode 2: when on group page and user is an admin. if (masonryMode == 2) { + // Create the new group post. $.post("API/postPost.php", { title: title, content : content, group : groupID }) @@ -42,6 +49,7 @@ function postPost() { } }); } else { + // Create the new user post. $.post("API/postPost.php", { title: title, content : content }) .done(function(data) { @@ -68,6 +76,7 @@ var postAmount = 0; var noposts = false; $(document).ready(function () { + // Initialise variables for masonry. windowWidth = $(window).width(); columnCount = Math.floor($(".posts").width() / 250); columns = new Array(columnCount); @@ -78,6 +87,7 @@ $(window).on("load", function() { $(".modal-close").click(function (){closeModal()}); // http://stackoverflow.com/questions/9439725/javascript-how-to-detect-if-browser-window-is-scrolled-to-bottom + // Infinite scroll. window.onscroll = function(ev) { if($(window).scrollTop() + $(window).height() == $(document).height() ) { loadMorePosts(userID, groupID, postAmount, postLimit); @@ -85,6 +95,7 @@ $(window).on("load", function() { }; }); +// Hide modal view from the screen. function closeModal() { $(".modal").hide(); scrollbarMargin(0, 'auto'); @@ -92,23 +103,30 @@ function closeModal() { $('.modal-default').show(); } +// Will fire when user resizes the window. $(window).resize(function() { clearTimeout(window.resizedFinished); window.resizeFinished = setTimeout(function() { + // Check if the width of the screen changed. if ($(window).width() != windowWidth) { + // Save width. windowWidth = $(window).width(); - + // Check if there fit more or less columns in the new width. if (columnCount != Math.floor($(".posts").width() / 250)) { columnCount = Math.floor($(".posts").width() / 250); + // Respawn the masonry grid. masonry(masonryMode); } } }, 250); }); +// Select the container for masonry. var $container = $(".posts"); +// Spawn the masonry grid. function masonry(mode) { + // save the masonry mode. masonryMode = mode; $container.children().remove(); @@ -116,10 +134,7 @@ function masonry(mode) { noposts = false; postAmount = 0; - /* - * Initialise columns. - */ - + // Initialise columns. for (i = 0; i < columnCount; i++) { $column = $("
    "); $column.width(100/columnCount + "%"); @@ -127,11 +142,13 @@ function masonry(mode) { columns[i] = [0, $column]; } + // Place the form for new posts. if(mode > 0) { $postInput = $("
    "); $form = $(""); $postInput.append($form); + //Add extra input for group posts. if(mode == 2) { $form.append($("")); } @@ -144,17 +161,11 @@ function masonry(mode) { columns[0][0] = $postInput.height() + margin; } - /* - * Function will find the column with the shortest height. - */ - - - /* - * Get the posts from the server. - */ + // Get the posts from the server. loadMorePosts(userID, groupID, 0, postLimit); } +// Find the column with the shortest hight. function getShortestColumn(columns) { column = columns[0]; @@ -166,17 +177,20 @@ function getShortestColumn(columns) { return column; } +// Load certain range of posts. function loadMorePosts(uID, gID, offset, limit) { if (noposts) { return; } + // Get a list of posts from the server. $.post("API/getPosts.php", { usr : uID, grp : gID, offset : offset, limit : limit}) .done(function(data) { if (!data) { + // No posts were found, show noposts bar to user. $('.noposts').show(); noposts = true; return; @@ -184,9 +198,7 @@ function loadMorePosts(uID, gID, offset, limit) { posts = JSON.parse(data); - /* - * Rearange the objects. - */ + // Rearange the objects. $.each(posts, function() { $post = $("
    "); $post.append($("

    ").html(this["title"])); -- 2.49.1