stuff
This commit is contained in:
parent
53e5116cff
commit
daf21c8873
19 changed files with 593 additions and 956 deletions
|
@ -89,8 +89,11 @@ class Comment
|
||||||
->where('vote_comment', $this->id)
|
->where('vote_comment', $this->id)
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
|
$this->upvotes = 0;
|
||||||
|
$this->downvotes = 0;
|
||||||
|
|
||||||
foreach ($votes as $vote) {
|
foreach ($votes as $vote) {
|
||||||
if ($vote->vote_state) {
|
if (intval($vote->vote_state) !== 0) {
|
||||||
$this->upvotes += 1;
|
$this->upvotes += 1;
|
||||||
} else {
|
} else {
|
||||||
$this->downvotes += 1;
|
$this->downvotes += 1;
|
||||||
|
@ -129,8 +132,44 @@ class Comment
|
||||||
return User::construct($this->user);
|
return User::construct($this->user);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function vote()
|
public function vote($user, $vote)
|
||||||
{
|
{
|
||||||
// can't be fucked to implement this right now
|
$vote = $vote ? '1' : '0';
|
||||||
|
|
||||||
|
// Attempt to get previous vote
|
||||||
|
$previous = DB::table('comment_votes')
|
||||||
|
->where('vote_user', $user)
|
||||||
|
->where('vote_comment', $this->id)
|
||||||
|
->get();
|
||||||
|
|
||||||
|
// Check if anything was returned
|
||||||
|
if ($previous) {
|
||||||
|
// Check if the vote that's being casted is the same
|
||||||
|
if ($previous[0]->vote_state == $vote) {
|
||||||
|
// Delete the vote
|
||||||
|
DB::table('comment_votes')
|
||||||
|
->where('vote_user', $user)
|
||||||
|
->where('vote_comment', $this->id)
|
||||||
|
->delete();
|
||||||
|
} else {
|
||||||
|
// Otherwise update the vote
|
||||||
|
DB::table('comment_votes')
|
||||||
|
->where('vote_user', $user)
|
||||||
|
->where('vote_comment', $this->id)
|
||||||
|
->update([
|
||||||
|
'vote_state' => $vote,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Create a vote
|
||||||
|
DB::table('comment_votes')
|
||||||
|
->insert([
|
||||||
|
'vote_user' => $user,
|
||||||
|
'vote_comment' => $this->id,
|
||||||
|
'vote_state' => $vote,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->getVotes();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,248 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Holds the holds the comment handler class.
|
|
||||||
*
|
|
||||||
* @package Sakura
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Sakura;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles and serves comments on pages.
|
|
||||||
* Needs a reimplementation.
|
|
||||||
*
|
|
||||||
* @package Sakura
|
|
||||||
* @author Julian van de Groep <me@flash.moe>
|
|
||||||
*/
|
|
||||||
class Comments
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The array containing the comments.
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
public $comments = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The comment category.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
public $category;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The amount of comments.
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
public $count = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param mixed $category The category that comments should be fetched from.
|
|
||||||
*/
|
|
||||||
public function __construct($category)
|
|
||||||
{
|
|
||||||
// Set category
|
|
||||||
$this->category = $category;
|
|
||||||
|
|
||||||
// Get the comments and assign them to $comments
|
|
||||||
$comments = DB::table('comments')
|
|
||||||
->where('comment_category', $this->category)
|
|
||||||
->where('comment_reply_to', 0)
|
|
||||||
->orderBy('comment_id', 'desc')
|
|
||||||
->get();
|
|
||||||
|
|
||||||
// Feed them into the sorter
|
|
||||||
$this->comments = $this->sortComments($comments);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sort the comments.
|
|
||||||
*
|
|
||||||
* @param array $comments Array containing comments.
|
|
||||||
*
|
|
||||||
* @return array Array containing the sorted comments.
|
|
||||||
*/
|
|
||||||
public function sortComments($comments)
|
|
||||||
{
|
|
||||||
// Create storage array
|
|
||||||
$layer = [];
|
|
||||||
|
|
||||||
// Sort comments
|
|
||||||
foreach ($comments as $comment) {
|
|
||||||
// Temporary hackjob to get rid of the old database layer, will reimplement later
|
|
||||||
$comment = get_object_vars($comment);
|
|
||||||
|
|
||||||
// Attach the poster
|
|
||||||
$comment['comment_poster'] = User::construct($comment['comment_poster']);
|
|
||||||
$comment['comment_text'] = BBcode::parseEmoticons(Utils::cleanString($comment['comment_text']));
|
|
||||||
|
|
||||||
// Get likes and dislikes
|
|
||||||
$votes = $this->getVotes($comment['comment_id']);
|
|
||||||
$comment['comment_likes'] = 0;
|
|
||||||
$comment['comment_dislikes'] = 0;
|
|
||||||
|
|
||||||
// Store amount in their respective variables
|
|
||||||
foreach ($votes as $vote) {
|
|
||||||
$vote = get_object_vars($vote);
|
|
||||||
if ($vote['vote_state']) {
|
|
||||||
$comment['comment_likes'] += 1;
|
|
||||||
} else {
|
|
||||||
$comment['comment_dislikes'] += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add post to posts array
|
|
||||||
$layer[$comment['comment_id']] = $comment;
|
|
||||||
|
|
||||||
// Up the comment count
|
|
||||||
$this->count += 1;
|
|
||||||
|
|
||||||
// Attempt to get replies from the database
|
|
||||||
$replies = DB::table('comments')
|
|
||||||
->where('comment_category', $this->category)
|
|
||||||
->where('comment_reply_to', $comment['comment_id'])
|
|
||||||
->orderBy('comment_id', 'desc')
|
|
||||||
->get();
|
|
||||||
|
|
||||||
// Check if this was a reply to something
|
|
||||||
if ($replies) {
|
|
||||||
// Save the replies
|
|
||||||
$layer[$comment['comment_id']]['comment_replies'] = $this->sortComments($replies);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $layer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a single comment.
|
|
||||||
*
|
|
||||||
* @param int $cid ID of the comment.
|
|
||||||
*
|
|
||||||
* @return array The comment.
|
|
||||||
*/
|
|
||||||
public function getComment($cid)
|
|
||||||
{
|
|
||||||
// Get from database
|
|
||||||
$comment = DB::table('comments')
|
|
||||||
->where('comment_id', $cid)
|
|
||||||
->get();
|
|
||||||
|
|
||||||
return $comment ? get_object_vars($comment[0]) : [];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the votes for a comment.
|
|
||||||
*
|
|
||||||
* @param int $cid ID of the comment.
|
|
||||||
*
|
|
||||||
* @return array The votes.
|
|
||||||
*/
|
|
||||||
public function getVotes($cid)
|
|
||||||
{
|
|
||||||
// Get from database
|
|
||||||
$comment = DB::table('comment_votes')
|
|
||||||
->where('vote_comment', $cid)
|
|
||||||
->get();
|
|
||||||
|
|
||||||
return $comment;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creating a new comment.
|
|
||||||
*
|
|
||||||
* @param int $uid ID of the user creating the comment.
|
|
||||||
* @param int $reply ID of the comment that is being replied to.
|
|
||||||
* @param string $content Contents of the comment.
|
|
||||||
*
|
|
||||||
* @return array Response identifier.
|
|
||||||
*/
|
|
||||||
public function makeComment($uid, $reply, $content)
|
|
||||||
{
|
|
||||||
// Check if the comment is long enough
|
|
||||||
if (strlen($content) < Config::get('comment_min_length')) {
|
|
||||||
return [0, 'TOO_SHORT'];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the comment isn't too long
|
|
||||||
if (strlen($content) > Config::get('comment_max_length')) {
|
|
||||||
return [0, 'TOO_LONG'];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert into database
|
|
||||||
DB::table('comments')
|
|
||||||
->insert([
|
|
||||||
'comment_category' => $this->category,
|
|
||||||
'comment_timestamp' => time(),
|
|
||||||
'comment_poster' => (int) $uid,
|
|
||||||
'comment_reply_to' => (int) $reply,
|
|
||||||
'comment_text' => $content,
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Return success
|
|
||||||
return [1, 'SUCCESS'];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Making a vote.
|
|
||||||
*
|
|
||||||
* @param int $uid User making this vote.
|
|
||||||
* @param int $cid ID of the comment that is being voted on.
|
|
||||||
* @param int $mode Positive or negative vote.
|
|
||||||
*
|
|
||||||
* @return bool Always returns true.
|
|
||||||
*/
|
|
||||||
public function makeVote($uid, $cid, $mode)
|
|
||||||
{
|
|
||||||
// Attempt to get previous vote
|
|
||||||
$vote = DB::table('comment_votes')
|
|
||||||
->where('vote_user', $uid)
|
|
||||||
->where('vote_comment', $cid)
|
|
||||||
->get();
|
|
||||||
|
|
||||||
// Check if anything was returned
|
|
||||||
if ($vote) {
|
|
||||||
// Check if the vote that's being casted is the same
|
|
||||||
if ($vote[0]->vote_state == $mode) {
|
|
||||||
// Delete the vote
|
|
||||||
DB::table('comment_votes')
|
|
||||||
->where('vote_user', $uid)
|
|
||||||
->where('vote_comment', $cid)
|
|
||||||
->delete();
|
|
||||||
} else {
|
|
||||||
// Otherwise update the vote
|
|
||||||
DB::table('comment_votes')
|
|
||||||
->where('vote_user', $uid)
|
|
||||||
->where('vote_comment', $cid)
|
|
||||||
->update([
|
|
||||||
'vote_state' => $mode,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Create a vote
|
|
||||||
DB::table('comment_votes')
|
|
||||||
->insert([
|
|
||||||
'vote_user' => $uid,
|
|
||||||
'vote_comment' => $cid,
|
|
||||||
'vote_state' => $mode,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove a comment
|
|
||||||
*
|
|
||||||
* @param int $cid ID of the comment to remove.
|
|
||||||
*/
|
|
||||||
public function removeComment($cid)
|
|
||||||
{
|
|
||||||
// Remove from database
|
|
||||||
DB::table('comments')
|
|
||||||
->where('comment_id', $cid)
|
|
||||||
->delete();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -8,7 +8,8 @@
|
||||||
namespace Sakura\Controllers;
|
namespace Sakura\Controllers;
|
||||||
|
|
||||||
use Sakura\Comment;
|
use Sakura\Comment;
|
||||||
use Sakura\Template;
|
use Sakura\Config;
|
||||||
|
use Sakura\Perms\Site;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles comment stuff.
|
* Handles comment stuff.
|
||||||
|
@ -21,9 +22,14 @@ class CommentsController extends Controller
|
||||||
public function post($category = '', $reply = 0)
|
public function post($category = '', $reply = 0)
|
||||||
{
|
{
|
||||||
global $currentUser;
|
global $currentUser;
|
||||||
|
|
||||||
// Set json content type
|
$session = $_POST['session'] ?? '';
|
||||||
header('Content-Type: application/json; charset=utf-8');
|
|
||||||
|
// Check if the user can comment
|
||||||
|
if ($session !== session_id()) {
|
||||||
|
$error = "Your session expired, refresh the page!";
|
||||||
|
return $this->json(compact('error'));
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the user can comment
|
// Check if the user can comment
|
||||||
if (!$currentUser->permission(Site::CREATE_COMMENTS)) {
|
if (!$currentUser->permission(Site::CREATE_COMMENTS)) {
|
||||||
|
@ -32,25 +38,26 @@ class CommentsController extends Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks
|
// Checks
|
||||||
$length = strlen($content);
|
$text = $_POST['text'] ?? '';
|
||||||
|
$length = strlen($text);
|
||||||
$tooShort = $length < Config::get('comment_min_length');
|
$tooShort = $length < Config::get('comment_min_length');
|
||||||
$tooLong = $length > Config::get('comment_max_length');
|
$tooLong = $length > Config::get('comment_max_length');
|
||||||
|
|
||||||
if ($tooShort || $tooLong) {
|
if ($tooShort || $tooLong) {
|
||||||
$fill = $tooShort ? "short" : "long";
|
$fill = $tooShort ? "short" : "long";
|
||||||
$error = "Your comment is too {$fill}!";
|
$error = "Your comment is too {$fill}!";
|
||||||
|
|
||||||
return $this->json(compact('error'));
|
return $this->json(compact('error'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$text = isset($_POST['text']) ? $_POST['text'] : '';
|
$text = $_POST['text'] ?? '';
|
||||||
|
|
||||||
$comment = new Comment;
|
$comment = new Comment;
|
||||||
|
|
||||||
$comment->category = $category;
|
$comment->category = $category;
|
||||||
$comment->time = time();
|
$comment->time = time();
|
||||||
$comment->reply = (int) $reply;
|
$comment->reply = (int) $reply;
|
||||||
$comment->user = $currentUser->id;
|
$comment->user = (int) $currentUser->id;
|
||||||
$comment->text = $text;
|
$comment->text = $text;
|
||||||
|
|
||||||
$comment->save();
|
$comment->save();
|
||||||
|
@ -58,18 +65,60 @@ class CommentsController extends Controller
|
||||||
return $this->json($comment);
|
return $this->json($comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function edit($id = 0)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function delete($id = 0)
|
public function delete($id = 0)
|
||||||
{
|
{
|
||||||
//
|
global $currentUser;
|
||||||
|
|
||||||
|
// Check if the user can delete comments
|
||||||
|
if (!$currentUser->permission(Site::DELETE_COMMENTS)) {
|
||||||
|
$error = "You aren't allowed to delete comments!";
|
||||||
|
return $this->json(compact('error'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$comment = new Comment($id);
|
||||||
|
|
||||||
|
if (!$comment->id) {
|
||||||
|
$error = "This comment doesn't exist!";
|
||||||
|
return $this->json(compact('error'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($currentUser->id !== $comment->user) {
|
||||||
|
$error = "You aren't allowed to delete the comments of other people!";
|
||||||
|
return $this->json(compact('error'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$deleted = $comment->id;
|
||||||
|
|
||||||
|
$comment->delete();
|
||||||
|
|
||||||
|
return $this->json(compact('deleted'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function vote($id = 0)
|
public function vote($id = 0)
|
||||||
{
|
{
|
||||||
//
|
global $currentUser;
|
||||||
|
|
||||||
|
$vote = $_REQUEST['vote'] ?? 0;
|
||||||
|
$vote = $vote != 0;
|
||||||
|
|
||||||
|
// Check if the user can delete comments
|
||||||
|
if (!$currentUser->permission(Site::VOTE_COMMENTS)) {
|
||||||
|
$error = "You aren't allowed to vote on comments!";
|
||||||
|
return $this->json(compact('error'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$comment = new Comment($id);
|
||||||
|
|
||||||
|
if (!$comment->id) {
|
||||||
|
$error = "This comment doesn't exist!";
|
||||||
|
return $this->json(compact('error'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$comment->vote($currentUser->id, $vote);
|
||||||
|
|
||||||
|
$upvotes = $comment->upvotes;
|
||||||
|
$downvotes = $comment->downvotes;
|
||||||
|
|
||||||
|
return $this->json(compact('upvotes', 'downvotes'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,10 @@ namespace Sakura\Controllers;
|
||||||
*/
|
*/
|
||||||
class Controller
|
class Controller
|
||||||
{
|
{
|
||||||
private function json($object)
|
public function json($object)
|
||||||
{
|
{
|
||||||
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
|
|
||||||
return json_encode(
|
return json_encode(
|
||||||
$object,
|
$object,
|
||||||
JSON_FORCE_OBJECT | JSON_NUMERIC_CHECK | JSON_BIGINT_AS_STRING
|
JSON_FORCE_OBJECT | JSON_NUMERIC_CHECK | JSON_BIGINT_AS_STRING
|
||||||
|
|
139
libraries/Controllers/FriendsController.php
Normal file
139
libraries/Controllers/FriendsController.php
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Holds the friends controller.
|
||||||
|
*
|
||||||
|
* @package Sakura
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Sakura\Controllers;
|
||||||
|
|
||||||
|
use Sakura\Notification;
|
||||||
|
use Sakura\Perms\Site;
|
||||||
|
use Sakura\Router;
|
||||||
|
use Sakura\User;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Friendly controller.
|
||||||
|
*
|
||||||
|
* @package Sakura
|
||||||
|
* @author Julian van de Groep <me@flash.moe>
|
||||||
|
*/
|
||||||
|
class FriendsController extends Controller
|
||||||
|
{
|
||||||
|
private function addNotification($friend, $user, $title, $text = "")
|
||||||
|
{
|
||||||
|
$alert = new Notification;
|
||||||
|
|
||||||
|
$alert->user = $friend->id;
|
||||||
|
$alert->time = time();
|
||||||
|
$alert->title = $title;
|
||||||
|
$alert->text = $text;
|
||||||
|
$alert->image = Router::route('file.avatar', $user->id);
|
||||||
|
$alert->timeout = 60000;
|
||||||
|
$alert->link = Router::route('user.profile', $user->id);
|
||||||
|
|
||||||
|
$alert->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function add($id = 0)
|
||||||
|
{
|
||||||
|
global $currentUser;
|
||||||
|
|
||||||
|
$session = $_POST['session'] ?? '';
|
||||||
|
|
||||||
|
// Check if the user can comment
|
||||||
|
if ($session !== session_id()) {
|
||||||
|
$error = "Your session expired, refresh the page!";
|
||||||
|
return $this->json(compact('error'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$friend = User::construct($id);
|
||||||
|
|
||||||
|
if ($friend->permission(Site::DEACTIVATED)
|
||||||
|
|| $currentUser->permission(Site::DEACTIVATED)) {
|
||||||
|
$error = "The user you tried to add does not exist!";
|
||||||
|
return $this->json(compact('error'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($friend->id === $currentUser->id) {
|
||||||
|
$error = "You can't be friends with yourself, stop trying to bend reality!";
|
||||||
|
return $this->json(compact('error'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($currentUser->isFriends($friend->id)) {
|
||||||
|
$error = "You are already friends with this person!";
|
||||||
|
return $this->json(compact('error'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add friend
|
||||||
|
$currentUser->addFriend($friend->id);
|
||||||
|
|
||||||
|
$level = $currentUser->isFriends($friend->id);
|
||||||
|
|
||||||
|
$mutual = $level === 2;
|
||||||
|
|
||||||
|
$alertTitle = $mutual
|
||||||
|
? "{$currentUser->username} accepted your friend request!"
|
||||||
|
: "{$currentUser->username} added you as a friend!";
|
||||||
|
|
||||||
|
$alertText = $mutual
|
||||||
|
? ""
|
||||||
|
: "Click here to add them as well.";
|
||||||
|
|
||||||
|
$this->addNotification(
|
||||||
|
$friend,
|
||||||
|
$currentUser,
|
||||||
|
$alertTitle,
|
||||||
|
$alertText
|
||||||
|
);
|
||||||
|
|
||||||
|
$message = $mutual
|
||||||
|
? "You are now mutual friends with {$friend->username}!"
|
||||||
|
: "A friend request has been sent to {$friend->username}!";
|
||||||
|
|
||||||
|
return $this->json(compact('message', 'level'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function remove($id = 0)
|
||||||
|
{
|
||||||
|
global $currentUser;
|
||||||
|
|
||||||
|
$session = $_POST['session'] ?? '';
|
||||||
|
|
||||||
|
// Check if the user can comment
|
||||||
|
if ($session !== session_id()) {
|
||||||
|
$error = "Your session expired, refresh the page!";
|
||||||
|
return $this->json(compact('error'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$friend = User::construct($id);
|
||||||
|
|
||||||
|
if ($friend->permission(Site::DEACTIVATED)
|
||||||
|
|| $currentUser->permission(Site::DEACTIVATED)) {
|
||||||
|
$error = "The user you tried to remove does not exist!";
|
||||||
|
return $this->json(compact('error'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$currentUser->isFriends($friend->id)) {
|
||||||
|
$error = "You aren't even friends with that person!";
|
||||||
|
return $this->json(compact('error'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add friend
|
||||||
|
$currentUser->removeFriend($friend->id);
|
||||||
|
|
||||||
|
$level = $currentUser->isFriends($friend->id);
|
||||||
|
|
||||||
|
$alertTitle = "{$currentUser->username} removed you from their friends!";
|
||||||
|
|
||||||
|
$this->addNotification(
|
||||||
|
$friend,
|
||||||
|
$currentUser,
|
||||||
|
$alertTitle
|
||||||
|
);
|
||||||
|
|
||||||
|
$message = "Removed {$friend->username} from your friends!";
|
||||||
|
|
||||||
|
return $this->json(compact('message', 'level'));
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,9 +29,6 @@ class NotificationsController extends Controller
|
||||||
// TODO: add friend on/offline messages
|
// TODO: add friend on/offline messages
|
||||||
global $currentUser;
|
global $currentUser;
|
||||||
|
|
||||||
// Set json content type
|
|
||||||
header('Content-Type: application/json; charset=utf-8');
|
|
||||||
|
|
||||||
return $this->json($currentUser->notifications());
|
return $this->json($currentUser->notifications());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -546,24 +546,12 @@ class User
|
||||||
* Add a new friend.
|
* Add a new friend.
|
||||||
*
|
*
|
||||||
* @param int $uid The ID of the friend.
|
* @param int $uid The ID of the friend.
|
||||||
*
|
|
||||||
* @return array Status indicator.
|
|
||||||
*/
|
*/
|
||||||
public function addFriend($uid)
|
public function addFriend($uid)
|
||||||
{
|
{
|
||||||
// Create the foreign object
|
// Create the foreign object
|
||||||
$user = User::construct($uid);
|
$user = User::construct($uid);
|
||||||
|
|
||||||
// Validate that the user exists
|
|
||||||
if ($user->permission(Site::DEACTIVATED)) {
|
|
||||||
return [0, 'USER_NOT_EXIST'];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the user already has this user a friend
|
|
||||||
if ($this->isFriends($uid)) {
|
|
||||||
return [0, 'ALREADY_FRIENDS'];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add friend
|
// Add friend
|
||||||
DB::table('friends')
|
DB::table('friends')
|
||||||
->insert([
|
->insert([
|
||||||
|
@ -571,9 +559,6 @@ class User
|
||||||
'friend_id' => $uid,
|
'friend_id' => $uid,
|
||||||
'friend_timestamp' => time(),
|
'friend_timestamp' => time(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Return true because yay
|
|
||||||
return [1, $user->isFriends($this->id) ? 'FRIENDS' : 'NOT_MUTUAL'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -581,19 +566,12 @@ class User
|
||||||
*
|
*
|
||||||
* @param int $uid The friend Id
|
* @param int $uid The friend Id
|
||||||
* @param bool $deleteRequest Delete the open request as well (remove you from their friends list).
|
* @param bool $deleteRequest Delete the open request as well (remove you from their friends list).
|
||||||
*
|
|
||||||
* @return array Status indicator.
|
|
||||||
*/
|
*/
|
||||||
public function removeFriend($uid, $deleteRequest = false)
|
public function removeFriend($uid, $deleteRequest = false)
|
||||||
{
|
{
|
||||||
// Create the foreign object
|
// Create the foreign object
|
||||||
$user = User::construct($uid);
|
$user = User::construct($uid);
|
||||||
|
|
||||||
// Validate that the user exists
|
|
||||||
if ($user->permission(Site::DEACTIVATED)) {
|
|
||||||
return [0, 'USER_NOT_EXIST'];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove friend
|
// Remove friend
|
||||||
DB::table('friends')
|
DB::table('friends')
|
||||||
->where('user_id', $this->id)
|
->where('user_id', $this->id)
|
||||||
|
@ -607,9 +585,6 @@ class User
|
||||||
->where('friend_id', $this->id)
|
->where('friend_id', $this->id)
|
||||||
->delete();
|
->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return true because yay
|
|
||||||
return [1, 'REMOVED'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -367,91 +367,6 @@ function replaceTag(tag) {
|
||||||
function safeTagsReplace(str) {
|
function safeTagsReplace(str) {
|
||||||
return str.replace(/[&<>]/g, replaceTag);
|
return str.replace(/[&<>]/g, replaceTag);
|
||||||
}
|
}
|
||||||
// Open a comment reply field
|
|
||||||
function commentReply(id, session, category, action, avatar) {
|
|
||||||
// Find subject post
|
|
||||||
var replyingTo = document.getElementById('comment-' + id);
|
|
||||||
// Check if it actually exists
|
|
||||||
if ((typeof replyingTo).toLowerCase() === 'undefined') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Attempt to get previously created box
|
|
||||||
var replyBox = document.getElementById('comment-reply-container-' + id);
|
|
||||||
// Remove it if it already exists
|
|
||||||
if (replyBox) {
|
|
||||||
Sakura.removeById('comment-reply-container-' + id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Container
|
|
||||||
var replyContainer = document.createElement('li');
|
|
||||||
replyContainer.id = 'comment-reply-container-' + id;
|
|
||||||
// Form
|
|
||||||
var replyForm = document.createElement('form');
|
|
||||||
replyForm.id = 'comment-reply-' + id;
|
|
||||||
replyForm.action = action;
|
|
||||||
replyForm.method = 'post';
|
|
||||||
// Session
|
|
||||||
var replyInput = document.createElement('input');
|
|
||||||
replyInput.type = 'hidden';
|
|
||||||
replyInput.name = 'session';
|
|
||||||
replyInput.value = session;
|
|
||||||
replyForm.appendChild(replyInput);
|
|
||||||
// Category
|
|
||||||
var replyInput = document.createElement('input');
|
|
||||||
replyInput.type = 'hidden';
|
|
||||||
replyInput.name = 'category';
|
|
||||||
replyInput.value = category;
|
|
||||||
replyForm.appendChild(replyInput);
|
|
||||||
// Reply ID
|
|
||||||
var replyInput = document.createElement('input');
|
|
||||||
replyInput.type = 'hidden';
|
|
||||||
replyInput.name = 'replyto';
|
|
||||||
replyInput.value = id.toString();
|
|
||||||
replyForm.appendChild(replyInput);
|
|
||||||
// Mode
|
|
||||||
var replyInput = document.createElement('input');
|
|
||||||
replyInput.type = 'hidden';
|
|
||||||
replyInput.name = 'mode';
|
|
||||||
replyInput.value = 'comment';
|
|
||||||
replyForm.appendChild(replyInput);
|
|
||||||
// Comment container
|
|
||||||
var replyDiv = document.createElement('div');
|
|
||||||
replyDiv.className = 'comment';
|
|
||||||
// Avatar
|
|
||||||
var replyAvatar = document.createElement('div');
|
|
||||||
replyAvatar.className = 'comment-avatar';
|
|
||||||
replyAvatar.style.backgroundImage = 'url(' + avatar + ')';
|
|
||||||
replyDiv.appendChild(replyAvatar);
|
|
||||||
// Pointer
|
|
||||||
var replyPoint = document.createElement('div');
|
|
||||||
replyPoint.className = 'comment-pointer';
|
|
||||||
replyDiv.appendChild(replyPoint);
|
|
||||||
// Textarea
|
|
||||||
var replyText = document.createElement('textarea');
|
|
||||||
replyText.className = 'comment-content';
|
|
||||||
replyText.name = 'comment';
|
|
||||||
replyDiv.appendChild(replyText);
|
|
||||||
// Submit
|
|
||||||
var replySubmit = document.createElement('input');
|
|
||||||
replySubmit.className = 'comment-submit';
|
|
||||||
replySubmit.type = 'submit';
|
|
||||||
replySubmit.name = 'submit';
|
|
||||||
replySubmit.value = "\uf1d8";
|
|
||||||
replyDiv.appendChild(replySubmit);
|
|
||||||
// Append to form
|
|
||||||
replyForm.appendChild(replyDiv);
|
|
||||||
// Append form to container
|
|
||||||
replyContainer.appendChild(replyForm);
|
|
||||||
// Insert the HTML
|
|
||||||
if (replyingTo.children[1].children.length > 0) {
|
|
||||||
replyingTo.children[1].insertBefore(replyContainer, replyingTo.children[1].firstChild);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
replyingTo.children[1].appendChild(replyContainer);
|
|
||||||
}
|
|
||||||
// Prepare AJAX submission
|
|
||||||
prepareAjaxForm(replyForm.id, 'Replying...');
|
|
||||||
}
|
|
||||||
// Inserting text into text box
|
// Inserting text into text box
|
||||||
// Borrowed from http://stackoverflow.com/questions/1064089/inserting-a-text-where-cursor-is-using-javascript-jquery (therefore not in Typescript format, fix this later)
|
// Borrowed from http://stackoverflow.com/questions/1064089/inserting-a-text-where-cursor-is-using-javascript-jquery (therefore not in Typescript format, fix this later)
|
||||||
function insertText(areaId, text) {
|
function insertText(areaId, text) {
|
||||||
|
|
|
@ -451,109 +451,6 @@ function safeTagsReplace(str: string): string {
|
||||||
return str.replace(/[&<>]/g, replaceTag);
|
return str.replace(/[&<>]/g, replaceTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open a comment reply field
|
|
||||||
function commentReply(id: number, session: string, category: string, action: string, avatar: string): void {
|
|
||||||
// Find subject post
|
|
||||||
var replyingTo: HTMLElement = document.getElementById('comment-' + id);
|
|
||||||
|
|
||||||
// Check if it actually exists
|
|
||||||
if ((typeof replyingTo).toLowerCase() === 'undefined') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attempt to get previously created box
|
|
||||||
var replyBox: HTMLElement = document.getElementById('comment-reply-container-' + id);
|
|
||||||
|
|
||||||
// Remove it if it already exists
|
|
||||||
if (replyBox) {
|
|
||||||
Sakura.removeById('comment-reply-container-' + id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Container
|
|
||||||
var replyContainer: HTMLLIElement = document.createElement('li');
|
|
||||||
replyContainer.id = 'comment-reply-container-' + id;
|
|
||||||
|
|
||||||
// Form
|
|
||||||
var replyForm: HTMLFormElement = document.createElement('form');
|
|
||||||
replyForm.id = 'comment-reply-' + id;
|
|
||||||
replyForm.action = action;
|
|
||||||
replyForm.method = 'post';
|
|
||||||
|
|
||||||
// Session
|
|
||||||
var replyInput: HTMLInputElement = document.createElement('input');
|
|
||||||
replyInput.type = 'hidden';
|
|
||||||
replyInput.name = 'session';
|
|
||||||
replyInput.value = session;
|
|
||||||
replyForm.appendChild(replyInput);
|
|
||||||
|
|
||||||
// Category
|
|
||||||
var replyInput: HTMLInputElement = document.createElement('input');
|
|
||||||
replyInput.type = 'hidden';
|
|
||||||
replyInput.name = 'category';
|
|
||||||
replyInput.value = category;
|
|
||||||
replyForm.appendChild(replyInput);
|
|
||||||
|
|
||||||
// Reply ID
|
|
||||||
var replyInput: HTMLInputElement = document.createElement('input');
|
|
||||||
replyInput.type = 'hidden';
|
|
||||||
replyInput.name = 'replyto';
|
|
||||||
replyInput.value = id.toString();
|
|
||||||
replyForm.appendChild(replyInput);
|
|
||||||
|
|
||||||
// Mode
|
|
||||||
var replyInput: HTMLInputElement = document.createElement('input');
|
|
||||||
replyInput.type = 'hidden';
|
|
||||||
replyInput.name = 'mode';
|
|
||||||
replyInput.value = 'comment';
|
|
||||||
replyForm.appendChild(replyInput);
|
|
||||||
|
|
||||||
// Comment container
|
|
||||||
var replyDiv: HTMLDivElement = document.createElement('div');
|
|
||||||
replyDiv.className = 'comment';
|
|
||||||
|
|
||||||
// Avatar
|
|
||||||
var replyAvatar: HTMLDivElement = document.createElement('div');
|
|
||||||
replyAvatar.className = 'comment-avatar';
|
|
||||||
replyAvatar.style.backgroundImage = 'url(' + avatar + ')';
|
|
||||||
replyDiv.appendChild(replyAvatar);
|
|
||||||
|
|
||||||
// Pointer
|
|
||||||
var replyPoint: HTMLDivElement = document.createElement('div');
|
|
||||||
replyPoint.className = 'comment-pointer';
|
|
||||||
replyDiv.appendChild(replyPoint);
|
|
||||||
|
|
||||||
// Textarea
|
|
||||||
var replyText: HTMLTextAreaElement = document.createElement('textarea');
|
|
||||||
replyText.className = 'comment-content';
|
|
||||||
replyText.name = 'comment';
|
|
||||||
replyDiv.appendChild(replyText);
|
|
||||||
|
|
||||||
// Submit
|
|
||||||
var replySubmit: HTMLInputElement = document.createElement('input');
|
|
||||||
replySubmit.className = 'comment-submit';
|
|
||||||
replySubmit.type = 'submit';
|
|
||||||
replySubmit.name = 'submit';
|
|
||||||
replySubmit.value = "\uf1d8";
|
|
||||||
replyDiv.appendChild(replySubmit);
|
|
||||||
|
|
||||||
// Append to form
|
|
||||||
replyForm.appendChild(replyDiv);
|
|
||||||
|
|
||||||
// Append form to container
|
|
||||||
replyContainer.appendChild(replyForm);
|
|
||||||
|
|
||||||
// Insert the HTML
|
|
||||||
if (replyingTo.children[1].children.length > 0) {
|
|
||||||
replyingTo.children[1].insertBefore(replyContainer, replyingTo.children[1].firstChild);
|
|
||||||
} else {
|
|
||||||
replyingTo.children[1].appendChild(replyContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare AJAX submission
|
|
||||||
prepareAjaxForm(replyForm.id, 'Replying...');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inserting text into text box
|
// Inserting text into text box
|
||||||
// Borrowed from http://stackoverflow.com/questions/1064089/inserting-a-text-where-cursor-is-using-javascript-jquery (therefore not in Typescript format, fix this later)
|
// Borrowed from http://stackoverflow.com/questions/1064089/inserting-a-text-where-cursor-is-using-javascript-jquery (therefore not in Typescript format, fix this later)
|
||||||
function insertText(areaId, text) {
|
function insertText(areaId, text) {
|
||||||
|
|
|
@ -7,413 +7,14 @@
|
||||||
namespace Sakura;
|
namespace Sakura;
|
||||||
|
|
||||||
use Sakura\Perms\Site;
|
use Sakura\Perms\Site;
|
||||||
use Sakura\Router;
|
|
||||||
|
|
||||||
// Legacy support!!!!!!!!!
|
// Legacy support!!!!!!!!!
|
||||||
$renderData = [];
|
$renderData = [];
|
||||||
|
|
||||||
// If this we're requesting notifications this page won't require templating
|
|
||||||
if (isset($_REQUEST['request-notifications']) && $_REQUEST['request-notifications']) {
|
|
||||||
define('SAKURA_NO_TPL', true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Include components
|
// Include components
|
||||||
require_once str_replace(basename(__DIR__), '', dirname(__FILE__)) . 'sakura.php';
|
require_once str_replace(basename(__DIR__), '', dirname(__FILE__)) . 'sakura.php';
|
||||||
|
|
||||||
// Notifications (decommissioned)
|
if (isset($_POST['submit']) && isset($_POST['submit'])) {
|
||||||
if (isset($_REQUEST['request-notifications']) && $_REQUEST['request-notifications']) {
|
|
||||||
// Create the notification container array
|
|
||||||
$notifications = [];
|
|
||||||
|
|
||||||
// Check if the user is logged in
|
|
||||||
if (Users::checkLogin()
|
|
||||||
&& isset($_REQUEST['time'])
|
|
||||||
&& $_REQUEST['time'] > (time() - 1000)
|
|
||||||
&& isset($_REQUEST['session']) && $_REQUEST['session'] == session_id()) {
|
|
||||||
// Get the user's notifications from the past forever but exclude read notifications
|
|
||||||
$alerts = $currentUser->notifications();
|
|
||||||
|
|
||||||
// Add the proper values to the array
|
|
||||||
foreach ($alerts as $alert) {
|
|
||||||
// Add the notification to the display array
|
|
||||||
$notifications[$alert->id] = [
|
|
||||||
'read' => $alert->read,
|
|
||||||
'title' => $alert->title,
|
|
||||||
'text' => $alert->text,
|
|
||||||
'link' => $alert->link,
|
|
||||||
'img' => $alert->image,
|
|
||||||
'timeout' => $alert->timeout,
|
|
||||||
'sound' => $alert->sound,
|
|
||||||
];
|
|
||||||
|
|
||||||
$alert->toggleRead();
|
|
||||||
$alert->save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if friendOnline is set (so it doesn't tell you all your friends all online on first visit)
|
|
||||||
$onlineFriends = isset($_SESSION['friendsOnline']) ? $_SESSION['friendsOnline'] : [];
|
|
||||||
$onlineNotify = isset($_SESSION['friendsOnline']);
|
|
||||||
|
|
||||||
// Set friendsOnline
|
|
||||||
if (!$onlineNotify) {
|
|
||||||
$_SESSION['friendsOnline'] = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Populate the array
|
|
||||||
foreach ($currentUser->friends(1) as $friend) {
|
|
||||||
// Online status
|
|
||||||
$online = $friend->isOnline();
|
|
||||||
|
|
||||||
// If true check if they're already in the array
|
|
||||||
if ($online && !in_array($friend->id, $onlineFriends)) {
|
|
||||||
// Add user to the online array
|
|
||||||
$_SESSION['friendsOnline'][$friend->id] = $friend->id;
|
|
||||||
|
|
||||||
// Add the notification to the display array
|
|
||||||
if ($onlineNotify) {
|
|
||||||
$notifications[] = [
|
|
||||||
'read' => 0,
|
|
||||||
'title' => $friend->username . ' is online.',
|
|
||||||
'text' => '',
|
|
||||||
'link' => '',
|
|
||||||
'img' => Router::route('file.avatar', $friend->id),
|
|
||||||
'timeout' => 2000,
|
|
||||||
'sound' => false,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
} elseif (!$online && in_array($friend->id, $onlineFriends)) {
|
|
||||||
// Remove the person from the array
|
|
||||||
unset($_SESSION['friendsOnline'][$friend->id]);
|
|
||||||
|
|
||||||
// Add the notification to the display array
|
|
||||||
if ($onlineNotify) {
|
|
||||||
$notifications[] = [
|
|
||||||
'read' => 0,
|
|
||||||
'title' => $friend->username . ' is offline.',
|
|
||||||
'text' => '',
|
|
||||||
'link' => '',
|
|
||||||
'img' => Router::route('file.avatar', $friend->id),
|
|
||||||
'timeout' => 2000,
|
|
||||||
'sound' => false,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set header, convert the array to json, print it and exit
|
|
||||||
echo json_encode($notifications, JSON_NUMERIC_CHECK);
|
|
||||||
exit;
|
|
||||||
} elseif (isset($_REQUEST['comment-action']) && $_REQUEST['comment-action']) {
|
|
||||||
// Referrer
|
|
||||||
$redirect = (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : Router::route('main.index'));
|
|
||||||
|
|
||||||
// Continue
|
|
||||||
$continue = true;
|
|
||||||
|
|
||||||
// Match session ids for the same reason
|
|
||||||
if (!Users::checkLogin()) {
|
|
||||||
$renderData['page'] = [
|
|
||||||
'redirect' => $redirect,
|
|
||||||
'message' => 'You must be logged in to do that!',
|
|
||||||
'success' => 0,
|
|
||||||
];
|
|
||||||
|
|
||||||
// Prevent
|
|
||||||
$continue = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Match session ids for the same reason
|
|
||||||
if (!isset($_REQUEST['session']) || $_REQUEST['session'] != session_id()) {
|
|
||||||
$renderData['page'] = [
|
|
||||||
'redirect' => $redirect,
|
|
||||||
'message' => 'Invalid session, please try again.',
|
|
||||||
'success' => 0,
|
|
||||||
];
|
|
||||||
|
|
||||||
// Prevent
|
|
||||||
$continue = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Match session ids for the same reason
|
|
||||||
if (!isset($_REQUEST['category'])) {
|
|
||||||
$renderData['page'] = [
|
|
||||||
'redirect' => $redirect,
|
|
||||||
'message' => 'No category was set.',
|
|
||||||
'success' => 0,
|
|
||||||
];
|
|
||||||
|
|
||||||
// Prevent
|
|
||||||
$continue = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Select the right action
|
|
||||||
if ($continue) {
|
|
||||||
$comments = new Comments($_REQUEST['category']);
|
|
||||||
|
|
||||||
switch (isset($_REQUEST['mode']) ? $_REQUEST['mode'] : false) {
|
|
||||||
case 'vote':
|
|
||||||
$comment = $comments->getComment(isset($_REQUEST['id']) ? $_REQUEST['id'] : 0);
|
|
||||||
|
|
||||||
// Check if the comment was actually made by the current user
|
|
||||||
if (!$comment) {
|
|
||||||
$renderData['page'] = [
|
|
||||||
'redirect' => $redirect,
|
|
||||||
'message' => 'The requested comment does not exist.',
|
|
||||||
'success' => 0,
|
|
||||||
];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the user can delete comments
|
|
||||||
if (!$currentUser->permission(Site::VOTE_COMMENTS)) {
|
|
||||||
$renderData['page'] = [
|
|
||||||
'redirect' => $redirect,
|
|
||||||
'message' => 'You aren\'t allowed to vote on comments.',
|
|
||||||
'success' => 0,
|
|
||||||
];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$comments->makeVote(
|
|
||||||
$currentUser->id,
|
|
||||||
isset($_REQUEST['id']) ? $_REQUEST['id'] : 0,
|
|
||||||
isset($_REQUEST['state']) && $_REQUEST['state'] ? '1' : '0'
|
|
||||||
);
|
|
||||||
|
|
||||||
$renderData['page'] = [
|
|
||||||
'redirect' => $redirect,
|
|
||||||
'message' => 'Your vote has been cast!',
|
|
||||||
'success' => 1,
|
|
||||||
];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'delete':
|
|
||||||
$comment = $comments->getComment(isset($_REQUEST['id']) ? $_REQUEST['id'] : 0);
|
|
||||||
|
|
||||||
// Check if the comment was actually made by the current user
|
|
||||||
if (!$comment) {
|
|
||||||
$renderData['page'] = [
|
|
||||||
'redirect' => $redirect,
|
|
||||||
'message' => 'The requested comment does not exist.',
|
|
||||||
'success' => 0,
|
|
||||||
];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the user can delete comments
|
|
||||||
if (!$currentUser->permission(Site::DELETE_COMMENTS)) {
|
|
||||||
$renderData['page'] = [
|
|
||||||
'redirect' => $redirect,
|
|
||||||
'message' => 'You aren\'t allowed to delete comments.',
|
|
||||||
'success' => 0,
|
|
||||||
];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the comment was actually made by the current user
|
|
||||||
if ($comment['comment_poster'] !== $currentUser->id) {
|
|
||||||
$renderData['page'] = [
|
|
||||||
'redirect' => $redirect,
|
|
||||||
'message' => 'You can\'t delete the comments of others.',
|
|
||||||
'success' => 0,
|
|
||||||
];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$comments->removeComment(isset($_REQUEST['id']) ? $_REQUEST['id'] : 0);
|
|
||||||
|
|
||||||
$renderData['page'] = [
|
|
||||||
'redirect' => $redirect,
|
|
||||||
'message' => 'The comment has been deleted!',
|
|
||||||
'success' => 1,
|
|
||||||
];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'comment':
|
|
||||||
// Check if the user can delete comments
|
|
||||||
if (!$currentUser->permission(Site::CREATE_COMMENTS)) {
|
|
||||||
$renderData['page'] = [
|
|
||||||
'redirect' => $redirect,
|
|
||||||
'message' => 'You aren\'t allowed to comment.',
|
|
||||||
'success' => 0,
|
|
||||||
];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attempt to make a new comment
|
|
||||||
$comment = $comments->makeComment($currentUser->id, $_POST['replyto'], $_POST['comment']);
|
|
||||||
|
|
||||||
// Messages
|
|
||||||
$messages = [
|
|
||||||
'TOO_SHORT' => 'The comment you\'re trying to make is too short!',
|
|
||||||
'TOO_LONG' => 'The comment you\'re trying to make is too long!',
|
|
||||||
'SUCCESS' => 'Posted!',
|
|
||||||
];
|
|
||||||
|
|
||||||
$renderData['page'] = [
|
|
||||||
'redirect' => $redirect,
|
|
||||||
'message' => $messages[$comment[1]],
|
|
||||||
'success' => $comment[0],
|
|
||||||
];
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
$renderData['page'] = [
|
|
||||||
'redirect' => $redirect,
|
|
||||||
'message' => 'Unknown action.',
|
|
||||||
'success' => 0,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print page contents or if the AJAX request is set only display the render data
|
|
||||||
if (isset($_REQUEST['ajax'])) {
|
|
||||||
echo $renderData['page']['message'] . '|' .
|
|
||||||
$renderData['page']['success'] . '|' .
|
|
||||||
$renderData['page']['redirect'];
|
|
||||||
} else {
|
|
||||||
// If not allowed print the restricted page
|
|
||||||
Template::vars($renderData);
|
|
||||||
|
|
||||||
// Print page contents
|
|
||||||
echo Template::render('global/information');
|
|
||||||
}
|
|
||||||
exit;
|
|
||||||
} elseif (isset($_REQUEST['friend-action']) && $_REQUEST['friend-action'] && Users::checkLogin()) {
|
|
||||||
// Continue
|
|
||||||
$continue = true;
|
|
||||||
|
|
||||||
// Referrer
|
|
||||||
$redirect = (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : Router::route('main.index'));
|
|
||||||
|
|
||||||
// Compare time and session so we know the link isn't forged
|
|
||||||
if (!isset($_REQUEST['add']) && !isset($_REQUEST['remove'])) {
|
|
||||||
if (!isset($_REQUEST['ajax'])) {
|
|
||||||
header('Location: ' . $redirect);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$renderData['page'] = [
|
|
||||||
|
|
||||||
'redirect' => $redirect,
|
|
||||||
'message' => 'One of the required operators isn\'t set.',
|
|
||||||
'success' => 0,
|
|
||||||
|
|
||||||
];
|
|
||||||
|
|
||||||
// Prevent
|
|
||||||
$continue = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compare time and session so we know the link isn't forged
|
|
||||||
if ($continue && $_REQUEST[(isset($_REQUEST['add']) ? 'add' : 'remove')] == $currentUser->id) {
|
|
||||||
$renderData['page'] = [
|
|
||||||
|
|
||||||
'redirect' => $redirect,
|
|
||||||
'message' => 'You can\'t be friends with yourself, stop trying to bend reality.',
|
|
||||||
'success' => 0,
|
|
||||||
|
|
||||||
];
|
|
||||||
|
|
||||||
// Prevent
|
|
||||||
$continue = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compare time and session so we know the link isn't forged
|
|
||||||
if (!isset($_REQUEST['time']) || $_REQUEST['time'] < time() - 1000) {
|
|
||||||
$renderData['page'] = [
|
|
||||||
|
|
||||||
'redirect' => $redirect,
|
|
||||||
'message' => 'Timestamps differ too much, refresh the page and try again.',
|
|
||||||
'success' => 0,
|
|
||||||
|
|
||||||
];
|
|
||||||
|
|
||||||
// Prevent
|
|
||||||
$continue = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Match session ids for the same reason
|
|
||||||
if (!isset($_REQUEST['session']) || $_REQUEST['session'] != session_id()) {
|
|
||||||
$renderData['page'] = [
|
|
||||||
|
|
||||||
'redirect' => $redirect,
|
|
||||||
'message' => 'Invalid session, please try again.',
|
|
||||||
'success' => 0,
|
|
||||||
|
|
||||||
];
|
|
||||||
|
|
||||||
// Prevent
|
|
||||||
$continue = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Continue if nothing fucked up
|
|
||||||
if ($continue) {
|
|
||||||
// Execute the action
|
|
||||||
$action = (isset($_REQUEST['add']) ?
|
|
||||||
$currentUser->addFriend($_REQUEST['add']) :
|
|
||||||
$currentUser->removeFriend($_REQUEST['remove'], true));
|
|
||||||
|
|
||||||
// Set the messages
|
|
||||||
$messages = [
|
|
||||||
'USER_NOT_EXIST' => 'The user you tried to add doesn\'t exist.',
|
|
||||||
'ALREADY_FRIENDS' => 'You are already friends with this person!',
|
|
||||||
'FRIENDS' => 'You are now mutual friends!',
|
|
||||||
'NOT_MUTUAL' => 'A friend request has been sent to this person.',
|
|
||||||
'ALREADY_REMOVED' => 'You aren\'t friends with this person.',
|
|
||||||
'REMOVED' => 'Removed this person from your friends list.',
|
|
||||||
];
|
|
||||||
|
|
||||||
// Notification strings
|
|
||||||
$notifStrings = [
|
|
||||||
'FRIENDS' => ['%s accepted your friend request!', 'You can now do mutual friend things!'],
|
|
||||||
'NOT_MUTUAL' => ['%s added you as a friend!', 'Click here to add them as well.'],
|
|
||||||
'REMOVED' => ['%s removed you from their friends.', 'You can no longer do friend things now ;_;'],
|
|
||||||
];
|
|
||||||
|
|
||||||
// Add page specific things
|
|
||||||
$renderData['page'] = [
|
|
||||||
'redirect' => $redirect,
|
|
||||||
'message' => $messages[$action[1]],
|
|
||||||
'success' => $action[0],
|
|
||||||
];
|
|
||||||
|
|
||||||
// Create a notification
|
|
||||||
if (array_key_exists($action[1], $notifStrings)) {
|
|
||||||
// Get the current user's profile data
|
|
||||||
$user = User::construct($currentUser->id);
|
|
||||||
$friend = User::construct($_REQUEST[(isset($_REQUEST['add']) ? 'add' : 'remove')]);
|
|
||||||
|
|
||||||
$alert = new Notification;
|
|
||||||
|
|
||||||
$alert->user = $friend->id;
|
|
||||||
$alert->time = time();
|
|
||||||
$alert->sound = true;
|
|
||||||
$alert->title = sprintf($notifStrings[$action[1]][0], $user->username);
|
|
||||||
$alert->text = $notifStrings[$action[1]][1];
|
|
||||||
$alert->image = Router::route('file.avatar', $user->id);
|
|
||||||
$alert->timeout = 60000;
|
|
||||||
$alert->link = Router::route('user.profile', $user->id);
|
|
||||||
|
|
||||||
$alert->save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print page contents or if the AJAX request is set only display the render data
|
|
||||||
if (isset($_REQUEST['ajax'])) {
|
|
||||||
echo $renderData['page']['message'] . '|' .
|
|
||||||
$renderData['page']['success'] . '|' .
|
|
||||||
$renderData['page']['redirect'];
|
|
||||||
} else {
|
|
||||||
// If not allowed print the restricted page
|
|
||||||
Template::vars($renderData);
|
|
||||||
|
|
||||||
// Print page contents
|
|
||||||
echo Template::render('global/information');
|
|
||||||
}
|
|
||||||
exit;
|
|
||||||
} elseif (isset($_POST['submit']) && isset($_POST['submit'])) {
|
|
||||||
$continue = true;
|
$continue = true;
|
||||||
|
|
||||||
// Set redirector
|
// Set redirector
|
||||||
|
|
14
routes.php
14
routes.php
|
@ -108,7 +108,15 @@ Router::group(['prefix' => 'notifications'], function () {
|
||||||
|
|
||||||
// Comments
|
// Comments
|
||||||
Router::group(['prefix' => 'comments', 'before' => 'loginCheck'], function () {
|
Router::group(['prefix' => 'comments', 'before' => 'loginCheck'], function () {
|
||||||
Router::post('/{category:c}/post/{reply:i}?', 'CommentsController@post', 'comments.post');
|
Router::post('/{category:c}/post/{reply:i}?', 'CommentsController@post', 'comments.category.post');
|
||||||
|
Router::post('/{id:i}/delete', 'CommentsController@delete', 'comments.comment.delete');
|
||||||
|
Router::post('/{id:i}/vote', 'CommentsController@vote', 'comments.comment.vote');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Comments
|
||||||
|
Router::group(['prefix' => 'friends', 'before' => 'loginCheck'], function () {
|
||||||
|
Router::post('/{id:i}/add', 'FriendsController@add', 'friends.add');
|
||||||
|
Router::post('/{id:i}/remove', 'FriendsController@remove', 'friends.remove');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Files
|
// Files
|
||||||
|
@ -136,7 +144,7 @@ Router::group(['prefix' => 'settings', 'before' => 'loginCheck'], function () {
|
||||||
Router::get('/', function () {
|
Router::get('/', function () {
|
||||||
$route = Router::route('settings.general.home');
|
$route = Router::route('settings.general.home');
|
||||||
return header("Location: {$route}");
|
return header("Location: {$route}");
|
||||||
});
|
}, 'settings.index');
|
||||||
|
|
||||||
// General section
|
// General section
|
||||||
Router::group(['prefix' => 'general'], function () {
|
Router::group(['prefix' => 'general'], function () {
|
||||||
|
@ -203,7 +211,7 @@ Router::group(['prefix' => 'settings', 'before' => 'loginCheck'], function () {
|
||||||
return header("Location: {$route}");
|
return header("Location: {$route}");
|
||||||
});
|
});
|
||||||
|
|
||||||
Router::get('/email', 'Settings.AccountController@avatar', 'settings.account.email');
|
Router::get('/email', 'Settings.AccountController@email', 'settings.account.email');
|
||||||
Router::get('/username', 'Settings.AccountController@username', 'settings.account.username');
|
Router::get('/username', 'Settings.AccountController@username', 'settings.account.username');
|
||||||
Router::get('/title', 'Settings.AccountController@title', 'settings.account.title');
|
Router::get('/title', 'Settings.AccountController@title', 'settings.account.title');
|
||||||
Router::get('/password', 'Settings.AccountController@password', 'settings.account.password');
|
Router::get('/password', 'Settings.AccountController@password', 'settings.account.password');
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
namespace Sakura;
|
namespace Sakura;
|
||||||
|
|
||||||
// Define Sakura version
|
// Define Sakura version
|
||||||
define('SAKURA_VERSION', 20160328);
|
define('SAKURA_VERSION', 20160330);
|
||||||
|
|
||||||
// Define Sakura Path
|
// Define Sakura Path
|
||||||
define('ROOT', __DIR__ . '/');
|
define('ROOT', __DIR__ . '/');
|
||||||
|
|
|
@ -6,13 +6,13 @@
|
||||||
<div class="comment-controls">
|
<div class="comment-controls">
|
||||||
<ul>
|
<ul>
|
||||||
{% if comment.userData.id == user.id %}
|
{% if comment.userData.id == user.id %}
|
||||||
<li><a href="{{ urls.format('COMMENT_DELETE', [comment.id, comment.category, session_id()])}}" class="clean fa fa-trash-o comment-deletion-link" title="Delete" id="comment-action-delete-{{ comment.id }}"></a></li>
|
<li><a href="javascript:void(0);" onclick="commentDelete({{ comment.id }});" class="clean fa fa-trash-o" title="Delete"></a></li>
|
||||||
{% else %}
|
{% else %}
|
||||||
<li><a href="{{ urls.format('USER_REPORT', [comment.userData.id]) }}" class="clean fa fa-exclamation-circle" title="Report" id="comment-action-report-{{ comment.id }}"></a></li>
|
<li><a href="{{ urls.format('USER_REPORT', [comment.userData.id]) }}" class="clean fa fa-exclamation-circle" title="Report"></a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<li><a href="javascript:void(0);" onclick="commentReply({{ comment.id }}, '{{ session_id() }}', '{{ comment.category }}', '{{ urls.format('COMMENT_POST') }}', '{{ route('file.avatar', user.id) }}');" class="clean fa fa-reply" title="Reply" id="comment-action-reply-{{ comment.id }}"></a></li>
|
<li><a href="javascript:void(0);" onclick="commentReply({{ comment.id }}, '{{ session_id() }}', '{{ route('file.avatar', user.id) }}');" class="clean fa fa-reply" title="Reply" id="comment-action-reply-{{ comment.id }}"></a></li>
|
||||||
<li class="shown voting like"><a href="{{ urls.format('COMMENT_VOTE', [comment.id, 1, comment.category, session_id()])}}" class="clean comment-like-link" id="comment-action-like-{{ comment.id }}"><span class="fa fa-thumbs-up"></span> <span id="comment-{{ comment.id }}-likes">{{ comment.upvotes }}</span></a></li>
|
<li class="shown voting like"><a href="javascript:void(0);" onclick="commentVote({{ comment.id }}, 1);" class="clean"><span class="fa fa-thumbs-up"></span> <span id="comment-{{ comment.id }}-likes">{{ comment.upvotes }}</span></a></li>
|
||||||
<li class="shown voting dislike"><a id="comment-action-dislike-{{ comment.id }}" href="{{ urls.format('COMMENT_VOTE', [comment.id, 0, comment.category, session_id()])}}" class="clean comment-dislike-link"><span class="fa fa-thumbs-down"></span> <span id="comment-{{ comment.id }}-dislikes">{{ comment.downvotes }}</span></a></li>
|
<li class="shown voting dislike"><a href="javascript:void(0);" onclick="commentVote({{ comment.id }}, 0);" class="clean"><span class="fa fa-thumbs-down"></span> <span id="comment-{{ comment.id }}-dislikes">{{ comment.downvotes }}</span></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="clear"></div>
|
<div class="clear"></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ul>
|
<ul class="comment-replies">
|
||||||
{% for comment in comment.replies %}
|
{% for comment in comment.replies %}
|
||||||
{% include 'elements/comment.twig' %}
|
{% include 'elements/comment.twig' %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
@ -1,23 +1,12 @@
|
||||||
<div id="comments">
|
<div id="comments">
|
||||||
<div class="comment-input-section">
|
<div class="comment-input-section">
|
||||||
{% if session.checkLogin %}
|
{% if session.checkLogin %}
|
||||||
<form action="{{ urls.format('COMMENT_POST') }}" method="post" id="commentsForm">
|
<div class="comment">
|
||||||
<input type="hidden" name="session" value="{{ session_id() }}" />
|
<div class="comment-avatar" style="background-image: url('{{ route('file.avatar', user.id) }}');"></div>
|
||||||
<input type="hidden" name="category" value="{{ commentsCategory }}" />
|
<div class="comment-pointer"></div>
|
||||||
<input type="hidden" name="replyto" value="0" />
|
<textarea class="comment-content" name="text" placeholder="Join the conversation..."></textarea>
|
||||||
<input type="hidden" name="mode" value="comment" />
|
<button class="comment-submit new" name="session" value="{{ session_id() }}" onclick="commentPost(this.parentNode, '{{ route('comments.category.post', commentsCategory) }}');"></button>
|
||||||
<div class="comment">
|
</div>
|
||||||
<div class="comment-avatar" style="background-image: url('{{ route('file.avatar', user.id) }}');"></div>
|
|
||||||
<div class="comment-pointer"></div>
|
|
||||||
<textarea class="comment-content" name="comment" placeholder="Join the conversation..."></textarea>
|
|
||||||
<input class="comment-submit new" name="submit" type="submit" value="" />
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<script type="text/javascript">
|
|
||||||
window.addEventListener("load", function() {
|
|
||||||
prepareAjaxForm('commentsForm', 'Posting comment...');
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{% else %}
|
{% else %}
|
||||||
<h1 class="stylised" style="text-align: center; padding: 10px 0">Log in to comment!</h1>
|
<h1 class="stylised" style="text-align: center; padding: 10px 0">Log in to comment!</h1>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -37,18 +26,276 @@
|
||||||
|
|
||||||
{% block js %}
|
{% block js %}
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
var deletionLinks = document.querySelectorAll('.comment-deletion-link');
|
var commentClient = new AJAX();
|
||||||
var likeLinks = document.querySelectorAll('.comment-like-link');
|
|
||||||
var dislikeLinks = document.querySelectorAll('.comment-dislike-link');
|
|
||||||
|
|
||||||
for(var link in deletionLinks) {
|
commentClient.contentType("application/x-www-form-urlencoded");
|
||||||
prepareAjaxLink(deletionLinks[link].id, 'submitPost', ', true, "Deleting..."');
|
|
||||||
|
function commentPost(element, url) {
|
||||||
|
var text = element.querySelector('[name="text"]'),
|
||||||
|
session = element.querySelector('[name="session"]');
|
||||||
|
|
||||||
|
commentClient.setSend({"text":text.value,"session":session.value});
|
||||||
|
|
||||||
|
text.value = '';
|
||||||
|
|
||||||
|
commentClient.setUrl(url);
|
||||||
|
|
||||||
|
commentClient.addCallback(200, function () {
|
||||||
|
var resp = JSON.parse(commentClient.response());
|
||||||
|
|
||||||
|
if (resp.error) {
|
||||||
|
ajaxBusyView(true, resp.error, 'fail');
|
||||||
|
|
||||||
|
setTimeout(function () {
|
||||||
|
ajaxBusyView(false);
|
||||||
|
}, 1500);
|
||||||
|
} else {
|
||||||
|
commentAdd(resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
commentClient.setRawSend("");
|
||||||
|
});
|
||||||
|
|
||||||
|
commentClient.start(HTTPMethods.POST);
|
||||||
}
|
}
|
||||||
for(var link in dislikeLinks) {
|
|
||||||
prepareAjaxLink(likeLinks[link].id, 'submitPost', ', true, "Voting..."');
|
function commentAdd(obj) {
|
||||||
|
var container = document.createElement('li');
|
||||||
|
container.id = "comment-" + obj.id;
|
||||||
|
|
||||||
|
var inner = document.createElement('div');
|
||||||
|
inner.className = 'comment';
|
||||||
|
|
||||||
|
var avatar = document.createElement('a');
|
||||||
|
avatar.className = 'comment-avatar clean';
|
||||||
|
avatar.href = "{{ route('user.profile', 1) }}".replace(1, obj.user);
|
||||||
|
avatar.style.backgroundImage = "url('{{ route('file.avatar', 1) }}')".replace(1, obj.user);
|
||||||
|
inner.appendChild(avatar);
|
||||||
|
|
||||||
|
var pointer = document.createElement('div');
|
||||||
|
pointer.className = 'comment-pointer';
|
||||||
|
inner.appendChild(pointer);
|
||||||
|
|
||||||
|
var content = document.createElement('div');
|
||||||
|
content.className = 'comment-content';
|
||||||
|
|
||||||
|
var controls = document.createElement('div');
|
||||||
|
controls.className = 'comment-controls';
|
||||||
|
|
||||||
|
var controlsInner = document.createElement('ul');
|
||||||
|
|
||||||
|
if (Sakura.cookie('id') == obj.user) {
|
||||||
|
var controlsTrashContainer = document.createElement('li');
|
||||||
|
var controlsTrash = document.createElement('a');
|
||||||
|
controlsTrash.href = 'javascript:void(0);';
|
||||||
|
controlsTrash.title = 'Delete';
|
||||||
|
controlsTrash.className = 'clean fa fa-trash-o';
|
||||||
|
controlsTrash.setAttribute('onclick', 'commentDelete(' + obj.id + ');');
|
||||||
|
controlsTrashContainer.appendChild(controlsTrash);
|
||||||
|
controlsInner.appendChild(controlsTrashContainer);
|
||||||
|
} else {
|
||||||
|
var controlsReportContainer = document.createElement('li');
|
||||||
|
var controlsReport = document.createElement('a');
|
||||||
|
controlsReport.href = '#';
|
||||||
|
controlsReport.title = 'Report';
|
||||||
|
controlsReport.className = 'clean fa fa-trash-o';
|
||||||
|
controlsReportContainer.appendChild(controlsReport);
|
||||||
|
controlsInner.appendChild(controlsReportContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
var controlsReplyContainer = document.createElement('li');
|
||||||
|
var controlsReply = document.createElement('a');
|
||||||
|
controlsReply.href = 'javascript:void(0);';
|
||||||
|
controlsReply.title = 'Reply';
|
||||||
|
controlsReply.className = 'clean fa fa-reply';
|
||||||
|
controlsReply.setAttribute('onclick', 'commentReply(' + obj.id + ', "{{ session_id() }}", "{{ route("file.avatar", user.id) }}");');
|
||||||
|
controlsReplyContainer.appendChild(controlsReply);
|
||||||
|
controlsInner.appendChild(controlsReplyContainer);
|
||||||
|
|
||||||
|
var controlsLikeContainer = document.createElement('li');
|
||||||
|
controlsLikeContainer.className = 'shown voting like';
|
||||||
|
var controlsLike = document.createElement('a');
|
||||||
|
controlsLike.href = 'javascript:void(0);';
|
||||||
|
controlsLike.setAttribute('onclick', 'commentVote(' + obj.id + ', 1);');
|
||||||
|
controlsLike.className = 'clean';
|
||||||
|
var controlsLikeIcon = document.createElement('span');
|
||||||
|
controlsLikeIcon.className = 'fa fa-thumbs-up';
|
||||||
|
controlsLike.appendChild(controlsLikeIcon);
|
||||||
|
controlsLike.innerHTML += "\r\n";
|
||||||
|
var controlsLikeCount = document.createElement('span');
|
||||||
|
controlsLikeCount.id = 'comment-' + obj.id + '-likes';
|
||||||
|
controlsLikeCount.innerText = obj.upvotes;
|
||||||
|
controlsLike.appendChild(controlsLikeCount);
|
||||||
|
controlsLikeContainer.appendChild(controlsLike);
|
||||||
|
controlsInner.appendChild(controlsLikeContainer);
|
||||||
|
|
||||||
|
var controlsDislikeContainer = document.createElement('li');
|
||||||
|
controlsDislikeContainer.className = 'shown voting dislike';
|
||||||
|
var controlsDislike = document.createElement('a');
|
||||||
|
controlsDislike.href = 'javascript:void(0);';
|
||||||
|
controlsDislike.setAttribute('onclick', 'commentVote(' + obj.id + ', 0);');
|
||||||
|
controlsDislike.className = 'clean';
|
||||||
|
var controlsDislikeIcon = document.createElement('span');
|
||||||
|
controlsDislikeIcon.className = 'fa fa-thumbs-down';
|
||||||
|
controlsDislike.appendChild(controlsDislikeIcon);
|
||||||
|
controlsDislike.innerHTML += "\r\n";
|
||||||
|
var controlsDislikeCount = document.createElement('span');
|
||||||
|
controlsDislikeCount.id = 'comment-' + obj.id + '-dislikes';
|
||||||
|
controlsDislikeCount.innerText = obj.upvotes;
|
||||||
|
controlsDislike.appendChild(controlsDislikeCount);
|
||||||
|
controlsDislikeContainer.appendChild(controlsDislike);
|
||||||
|
controlsInner.appendChild(controlsDislikeContainer);
|
||||||
|
|
||||||
|
controls.appendChild(controlsInner);
|
||||||
|
|
||||||
|
var clear = document.createElement('div');
|
||||||
|
clear.className = 'clear';
|
||||||
|
controls.appendChild(clear);
|
||||||
|
|
||||||
|
content.appendChild(controls);
|
||||||
|
|
||||||
|
var text = document.createElement('text');
|
||||||
|
text.className = 'comment-text';
|
||||||
|
text.innerHTML = obj.text;
|
||||||
|
content.appendChild(text);
|
||||||
|
|
||||||
|
inner.appendChild(content);
|
||||||
|
container.appendChild(inner);
|
||||||
|
|
||||||
|
var replies = document.createElement('ul');
|
||||||
|
replies.className = 'comment-replies';
|
||||||
|
container.appendChild(replies);
|
||||||
|
|
||||||
|
var discussion = document.getElementById('comments').querySelector('.comments-list');
|
||||||
|
|
||||||
|
if (obj.reply) {
|
||||||
|
discussion = document.getElementById('comment-' + obj.reply).querySelector('.comment-replies');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (discussion.children.length > 0) {
|
||||||
|
discussion.insertBefore(container, discussion.firstChild);
|
||||||
|
} else {
|
||||||
|
discussion.appendChild(container);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for(var link in dislikeLinks) {
|
|
||||||
prepareAjaxLink(dislikeLinks[link].id, 'submitPost', ', true, "Voting..."');
|
function commentReply(id, session, avatar) {
|
||||||
|
var url = "{{ route('comments.category.post', [':cat', 1]) }}"
|
||||||
|
.replace('1', id)
|
||||||
|
.replace(':cat', '{{ commentsCategory }}');
|
||||||
|
|
||||||
|
// Find subject post
|
||||||
|
var replyingTo = document.getElementById('comment-' + id);
|
||||||
|
|
||||||
|
// Check if it actually exists
|
||||||
|
if ((typeof replyingTo).toLowerCase() === 'undefined') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt to get previously created box
|
||||||
|
var replyBox = document.getElementById('comment-reply-container-' + id);
|
||||||
|
|
||||||
|
// Remove it if it already exists
|
||||||
|
if (replyBox) {
|
||||||
|
Sakura.removeById('comment-reply-container-' + id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Container
|
||||||
|
var replyContainer = document.createElement('li');
|
||||||
|
replyContainer.id = 'comment-reply-container-' + id;
|
||||||
|
|
||||||
|
// Comment container
|
||||||
|
var replyDiv = document.createElement('div');
|
||||||
|
replyDiv.className = 'comment';
|
||||||
|
replyDiv.id = 'comment-reply-' + id;
|
||||||
|
|
||||||
|
// Avatar
|
||||||
|
var replyAvatar = document.createElement('div');
|
||||||
|
replyAvatar.className = 'comment-avatar';
|
||||||
|
replyAvatar.style.backgroundImage = 'url(' + avatar + ')';
|
||||||
|
replyDiv.appendChild(replyAvatar);
|
||||||
|
|
||||||
|
// Pointer
|
||||||
|
var replyPoint = document.createElement('div');
|
||||||
|
replyPoint.className = 'comment-pointer';
|
||||||
|
replyDiv.appendChild(replyPoint);
|
||||||
|
|
||||||
|
// Textarea
|
||||||
|
var replyText = document.createElement('textarea');
|
||||||
|
replyText.className = 'comment-content';
|
||||||
|
replyText.name = 'text';
|
||||||
|
replyDiv.appendChild(replyText);
|
||||||
|
|
||||||
|
// Submit
|
||||||
|
var replySubmit = document.createElement('button');
|
||||||
|
replySubmit.className = 'comment-submit';
|
||||||
|
replySubmit.name = 'session';
|
||||||
|
replySubmit.value = session;
|
||||||
|
replySubmit.setAttribute('onclick', 'commentPost(this.parentNode, "' + url + '"); commentReply(' + id + ');');
|
||||||
|
replySubmit.innerHTML = "\uf1d8";
|
||||||
|
replyDiv.appendChild(replySubmit);
|
||||||
|
|
||||||
|
// Append form to container
|
||||||
|
replyContainer.appendChild(replyDiv);
|
||||||
|
|
||||||
|
// Insert the HTML
|
||||||
|
if (replyingTo.querySelector('.comment-replies').children.length > 0) {
|
||||||
|
replyingTo.querySelector('.comment-replies').insertBefore(replyContainer, replyingTo.querySelector('.comment-replies').firstChild);
|
||||||
|
} else {
|
||||||
|
replyingTo.querySelector('.comment-replies').appendChild(replyContainer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function commentDelete(id) {
|
||||||
|
var url = "{{ route('comments.comment.delete', 1) }}".replace(1, id);
|
||||||
|
|
||||||
|
commentClient.setUrl(url);
|
||||||
|
|
||||||
|
commentClient.addCallback(200, function () {
|
||||||
|
var resp = JSON.parse(commentClient.response());
|
||||||
|
|
||||||
|
if (resp.error) {
|
||||||
|
ajaxBusyView(true, resp.error, 'fail');
|
||||||
|
|
||||||
|
setTimeout(function () {
|
||||||
|
ajaxBusyView(false);
|
||||||
|
}, 1500);
|
||||||
|
} else {
|
||||||
|
Sakura.removeById("comment-" + id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
commentClient.start(HTTPMethods.POST);
|
||||||
|
}
|
||||||
|
|
||||||
|
function commentVote(id, vote) {
|
||||||
|
var url = "{{ route('comments.comment.vote', 1) }}".replace(1, id),
|
||||||
|
upvotes = document.getElementById("comment-" + id + "-likes"),
|
||||||
|
downvotes = document.getElementById("comment-" + id + "-dislikes");
|
||||||
|
|
||||||
|
commentClient.setSend({"vote":vote});
|
||||||
|
|
||||||
|
commentClient.setUrl(url);
|
||||||
|
|
||||||
|
commentClient.addCallback(200, function () {
|
||||||
|
var resp = JSON.parse(commentClient.response());
|
||||||
|
|
||||||
|
if (resp.error) {
|
||||||
|
ajaxBusyView(true, resp.error, 'fail');
|
||||||
|
|
||||||
|
setTimeout(function () {
|
||||||
|
ajaxBusyView(false);
|
||||||
|
}, 1500);
|
||||||
|
} else {
|
||||||
|
upvotes.innerText = resp.upvotes;
|
||||||
|
downvotes.innerText = resp.downvotes;
|
||||||
|
}
|
||||||
|
|
||||||
|
commentClient.setRawSend("");
|
||||||
|
});
|
||||||
|
|
||||||
|
commentClient.start(HTTPMethods.POST);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -96,10 +96,8 @@
|
||||||
<a class="fa fa-trash" title="Delete this post" href="{{ route('forums.post.delete', post.id) }}"></a>
|
<a class="fa fa-trash" title="Delete this post" href="{{ route('forums.post.delete', post.id) }}"></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if not (post.poster.permission(constant('Sakura\\Perms\\Site::DEACTIVATED')) or post.poster.permission(constant('Sakura\\Perms\\Site::RESTRICTED')) or user.id == post.poster.id) %}
|
{% if not (post.poster.permission(constant('Sakura\\Perms\\Site::DEACTIVATED')) or post.poster.permission(constant('Sakura\\Perms\\Site::RESTRICTED')) or user.id == post.poster.id) %}
|
||||||
{% if user.isFriends(post.poster.id) != 0 %}
|
<a class="fa fa-{% if user.isFriends(post.poster.id) == 2 %}heart{% else %}star{% endif %} friend-{{ post.poster.id }}-level" title="You are friends" {% if user.isFriends(post.poster.id) == 0 %}style="display: none;"{% endif %}></a>
|
||||||
<a class="fa fa-{% if user.isFriends(post.poster.id) == 2 %}heart{% else %}star{% endif %}" title="You are friends"></a>
|
<a class="fa fa-user-{% if user.isFriends(post.poster.id) == 0 %}plus{% else %}times{% endif %} forum-friend-toggle friend-{{ post.poster.id }}-toggle" title="{% if user.isFriends(post.poster.id) == 0 %}Add {{ post.poster.username }} as a friend{% else %}Remove friend{% endif %}" href="javascript:void(0);" onclick="{% if user.isFriends(post.poster.id) == 0 %}addFriend({{ post.poster.id }}){% else %}removeFriend({{ post.poster.id }}){% endif %}"></a>
|
||||||
{% endif %}
|
|
||||||
<a class="fa fa-user-{% if user.isFriends(post.poster.id) == 0 %}plus{% else %}times{% endif %} forum-friend-toggle" title="{% if user.isFriends(post.poster.id) == 0 %}Add {{ post.poster.username }} as a friend{% else %}Remove friend{% endif %}" href="{% if user.isFriends(post.poster.id) == 0 %}{{ urls.format('FRIEND_ADD', [post.poster.id, session_id(), date().timestamp, sakura.currentPage]) }}{% else %}{{ urls.format('FRIEND_REMOVE', [post.poster.id, session_id(), date().timestamp, sakura.currentPage]) }}{% endif %}"></a>
|
|
||||||
<a class="fa fa-flag" title="Report {{ post.poster.username }}" href="{{ urls.format('USER_REPORT', [post.poster.id]) }}"></a>
|
<a class="fa fa-flag" title="Report {{ post.poster.username }}" href="{{ urls.format('USER_REPORT', [post.poster.id]) }}"></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a class="fa fa-reply" title="Quote this post" href="javascript:void(0);" onclick="quotePost({{ post.id }});"></a>
|
<a class="fa fa-reply" title="Quote this post" href="javascript:void(0);" onclick="quotePost({{ post.id }});"></a>
|
||||||
|
|
|
@ -97,11 +97,11 @@
|
||||||
<!-- User menu, displayed on right side of the bar. -->
|
<!-- User menu, displayed on right side of the bar. -->
|
||||||
{% if session.checkLogin %}
|
{% if session.checkLogin %}
|
||||||
<a class="menu-item avatar" href="{{ route('user.profile', user.id) }}" title="Logged in as {{ user.username }}" style="background-image: url('{{ route('file.avatar', user.id) }}'); width: auto; color: {{ user.colour }}; border-color: {{ user.colour }}; font-weight: 700;"></a>
|
<a class="menu-item avatar" href="{{ route('user.profile', user.id) }}" title="Logged in as {{ user.username }}" style="background-image: url('{{ route('file.avatar', user.id) }}'); width: auto; color: {{ user.colour }}; border-color: {{ user.colour }}; font-weight: 700;"></a>
|
||||||
{#<a class="menu-item fa-envelope" href="{{ urls.format('SETTING_CAT', ['messages']) }}" title="Messages"></a>#}
|
{#<a class="menu-item fa-envelope" href="#" title="Messages"></a>#}
|
||||||
{% if user.permission(constant('Sakura\\Perms\\Manage::USE_MANAGE'), constant('Sakura\\Perms::MANAGE')) %}
|
{% if user.permission(constant('Sakura\\Perms\\Manage::USE_MANAGE'), constant('Sakura\\Perms::MANAGE')) %}
|
||||||
<a class="menu-item fa-gavel" href="{{ urls.format('MANAGE_INDEX') }}" title="Manage"></a>
|
<a class="menu-item fa-gavel" href="#" title="Manage"></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a class="menu-item fa-cogs" href="{{ urls.format('SETTINGS_INDEX') }}" title="Settings"></a>
|
<a class="menu-item fa-cogs" href="{{ route('settings.index') }}" title="Settings"></a>
|
||||||
<a class="menu-item fa-sign-out" href="{{ route('auth.logout') }}?s={{ session_id() }}" title="Logout" id="headerLogoutLink"></a>
|
<a class="menu-item fa-sign-out" href="{{ route('auth.logout') }}?s={{ session_id() }}" title="Logout" id="headerLogoutLink"></a>
|
||||||
{% else %}
|
{% else %}
|
||||||
{% if sakura.lockAuth %}
|
{% if sakura.lockAuth %}
|
||||||
|
@ -224,6 +224,48 @@
|
||||||
setInterval(function() {
|
setInterval(function() {
|
||||||
notifyRequest('{{ session_id() }}');
|
notifyRequest('{{ session_id() }}');
|
||||||
}, 60000);
|
}, 60000);
|
||||||
|
|
||||||
|
var friendClient = new AJAX();
|
||||||
|
|
||||||
|
friendClient.contentType("application/x-www-form-urlencoded");
|
||||||
|
|
||||||
|
function addFriend(id) {
|
||||||
|
var url = "{{ route('friends.add', 1) }}".replace(1, id);
|
||||||
|
friendMode(url, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeFriend(id) {
|
||||||
|
var url = "{{ route('friends.remove', 1) }}".replace(1, id);
|
||||||
|
friendMode(url, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
function friendMode(url, id) {
|
||||||
|
var level = document.querySelectorAll('.friend-' + id + '-level'),
|
||||||
|
toggle = document.querySelectorAll('.friend-' + id + '-toggle');
|
||||||
|
|
||||||
|
friendClient.setUrl(url);
|
||||||
|
|
||||||
|
friendClient.setSend({"session":"{{ session_id() }}"});
|
||||||
|
|
||||||
|
friendClient.addCallback(200, function () {
|
||||||
|
var resp = JSON.parse(friendClient.response());
|
||||||
|
|
||||||
|
friendClient.setRawSend("");
|
||||||
|
|
||||||
|
if (resp.error) {
|
||||||
|
ajaxBusyView(true, resp.error, 'fail');
|
||||||
|
|
||||||
|
setTimeout(function () {
|
||||||
|
ajaxBusyView(false);
|
||||||
|
}, 1500);
|
||||||
|
} else {
|
||||||
|
ajaxBusyView(true, resp.message, 'ok');
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
friendClient.start(HTTPMethods.POST);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
{% if sakura.dev.showChangelog and stats %}
|
{% if sakura.dev.showChangelog and stats %}
|
||||||
<script type="text/javascript" src="https://sakura.flash.moe/?get=all&limit=5&variable=true"></script>
|
<script type="text/javascript" src="https://sakura.flash.moe/?get=all&limit=5&variable=true"></script>
|
||||||
|
|
|
@ -3,18 +3,6 @@
|
||||||
{% set paginationPages = friends %}
|
{% set paginationPages = friends %}
|
||||||
{% set paginationUrl %}{{ urls.format('SETTING_MODE', ['friends', 'listing']) }}{% endset %}
|
{% set paginationUrl %}{{ urls.format('SETTING_MODE', ['friends', 'listing']) }}{% endset %}
|
||||||
|
|
||||||
{% block js %}
|
|
||||||
<script type="text/javascript">
|
|
||||||
window.addEventListener("load", function() {
|
|
||||||
var friendsListActions = document.querySelectorAll('[id^="friendslist-friend-action-"]');
|
|
||||||
|
|
||||||
for (var i in friendsListActions) {
|
|
||||||
prepareAjaxLink(friendsListActions[i], 'submitPost', ', true, "Please wait.."');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block css %}
|
{% block css %}
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
.pagination {
|
.pagination {
|
||||||
|
@ -31,8 +19,8 @@ window.addEventListener("load", function() {
|
||||||
<img src="{{ route('file.avatar', friend.id) }}" alt="{{ friend.username }}" class="friends-list-avatar default-avatar-setting" style="width: 150px; height: 150px;" />
|
<img src="{{ route('file.avatar', friend.id) }}" alt="{{ friend.username }}" class="friends-list-avatar default-avatar-setting" style="width: 150px; height: 150px;" />
|
||||||
<div class="friends-list-name" style="color: {{ friend.colour }};">{{ friend.username }}</div>
|
<div class="friends-list-name" style="color: {{ friend.colour }};">{{ friend.username }}</div>
|
||||||
</a>
|
</a>
|
||||||
<div class="friends-list-actions"><!-- urls -->
|
<div class="friends-list-actions">
|
||||||
<a class="remove fill fa fa-remove" title="Remove friend" href="/friends?remove={{ friend.id }}&session={{ session_id() }}&time={{ date().timestamp }}" id="friendslist-friend-action-remove-{{ friend.id }}"></a>
|
<a class="remove fill fa fa-remove" title="Remove friend" href="javascript:void(0);" onclick="removeFriend({{ friend.id }});"></a>
|
||||||
<div class="clear"></div>
|
<div class="clear"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,18 +3,6 @@
|
||||||
{% set paginationPages = friends %}
|
{% set paginationPages = friends %}
|
||||||
{% set paginationUrl %}{{ urls.format('SETTING_MODE', ['friends', 'requests']) }}{% endset %}
|
{% set paginationUrl %}{{ urls.format('SETTING_MODE', ['friends', 'requests']) }}{% endset %}
|
||||||
|
|
||||||
{% block js %}
|
|
||||||
<script type="text/javascript">
|
|
||||||
window.addEventListener("load", function() {
|
|
||||||
var friendsListActions = document.querySelectorAll('[id^="friendslist-friend-action-"]');
|
|
||||||
|
|
||||||
for (var i in friendsListActions) {
|
|
||||||
prepareAjaxLink(friendsListActions[i], 'submitPost', ', true, "Please wait.."');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block css %}
|
{% block css %}
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
.pagination {
|
.pagination {
|
||||||
|
@ -31,9 +19,9 @@ window.addEventListener("load", function() {
|
||||||
<img src="{{ route('file.avatar', friend.id) }}" alt="{{ friend.username }}" class="friends-list-avatar default-avatar-setting" style="width: 150px; height: 150px;" />
|
<img src="{{ route('file.avatar', friend.id) }}" alt="{{ friend.username }}" class="friends-list-avatar default-avatar-setting" style="width: 150px; height: 150px;" />
|
||||||
<div class="friends-list-name" style="color: {{ friend.colour }};">{{ friend.username }}</div>
|
<div class="friends-list-name" style="color: {{ friend.colour }};">{{ friend.username }}</div>
|
||||||
</a>
|
</a>
|
||||||
<div class="friends-list-actions"><!-- urls -->
|
<div class="friends-list-actions">
|
||||||
<a class="add fa fa-check" title="Add friend" href="/friends?add={{ friend.id }}&session={{ session_id() }}&time={{ date().timestamp }}" id="friendslist-friend-action-add-{{ friend.id }}"></a>
|
<a class="add fa fa-check" title="Add friend" href="javascript:void(0);" onclick="addFriend({{ friend.id }});"></a>
|
||||||
<a class="remove fa fa-remove" title="Remove friend" href="/friends?remove={{ friend.id }}&session={{ session_id() }}&time={{ date().timestamp }}" id="friendslist-friend-action-remove-{{ friend.id }}"></a>
|
<a class="remove fa fa-remove" title="Remove friend" href="javascript:void(0);" onclick="removeFriend({{ friend.id }});"></a>
|
||||||
<div class="clear"></div>
|
<div class="clear"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -114,7 +114,7 @@
|
||||||
<a class="fa fa-pencil-square-o" title="Edit your profile" href="{{ urls.format('SETTING_MODE', ['general', 'profile']) }}"></a>
|
<a class="fa fa-pencil-square-o" title="Edit your profile" href="{{ urls.format('SETTING_MODE', ['general', 'profile']) }}"></a>
|
||||||
{% else %}
|
{% else %}
|
||||||
{% if user.isFriends(profile.id) != 0 %}<a class="fa fa-{% if user.isFriends(profile.id) == 2 %}heart{% else %}star{% endif %}" title="You are friends"></a>{% endif %}
|
{% if user.isFriends(profile.id) != 0 %}<a class="fa fa-{% if user.isFriends(profile.id) == 2 %}heart{% else %}star{% endif %}" title="You are friends"></a>{% endif %}
|
||||||
<a class="fa fa-user-{% if user.isFriends(profile.id) == 0 %}plus{% else %}times{% endif %}" title="{% if user.isFriends(profile.id) == 0 %}Add {{ profile.username }} as a friend{% else %}Remove friend{% endif %}" href="{% if user.isFriends(profile.id) == 0 %}{{ urls.format('FRIEND_ADD', [profile.id, session_id(), date().timestamp, sakura.currentPage]) }}{% else %}{{ urls.format('FRIEND_REMOVE', [profile.id, session_id(), date().timestamp, sakura.currentPage]) }}{% endif %}" id="profileFriendToggle"></a>
|
<a class="fa fa-user-{% if user.isFriends(profile.id) == 0 %}plus{% else %}times{% endif %}" title="{% if user.isFriends(profile.id) == 0 %}Add {{ profile.username }} as a friend{% else %}Remove friend{% endif %}" href="javascript:void(0);" onclick="{% if user.isFriends(profile.id) == 0 %}addFriend({{ profile.id }}){% else %}removeFriend({{ profile.id }}){% endif %}"></a>
|
||||||
{#<a class="fa fa-exclamation-circle" title="Report {{ profile.username }}" href="{{ urls.format('USER_REPORT', [profile.id]) }}"></a>#}
|
{#<a class="fa fa-exclamation-circle" title="Report {{ profile.username }}" href="{{ urls.format('USER_REPORT', [profile.id]) }}"></a>#}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if user.permission(constant('Sakura\\Perms\\Manage::CAN_RESTRICT_USERS'), constant('Sakura\\Perms::MANAGE')) %}
|
{% if user.permission(constant('Sakura\\Perms\\Manage::CAN_RESTRICT_USERS'), constant('Sakura\\Perms::MANAGE')) %}
|
||||||
|
|
Reference in a new issue