Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Forum subscriptions to automatically subscribe to new threads in a given forum #11

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions gazelle.sql
Original file line number Diff line number Diff line change
Expand Up @@ -964,12 +964,6 @@ CREATE TABLE `stylesheets` (
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

CREATE TABLE `subscribed_forums` (
`ForumID` int(10) NOT NULL,
`UserID` int(10) NOT NULL,
PRIMARY KEY (`ForumID`,`UserID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

CREATE TABLE `subscribed_users` (
`UserID` int(10) NOT NULL,
`SubscriberID` int(10) NOT NULL,
Expand Down Expand Up @@ -1619,6 +1613,12 @@ CREATE TABLE `users_sessions` (
KEY `ActiveAgeKeep` (`Active`,`LastUpdate`,`KeepLogged`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `users_subscribed_forums` (
`UserID` int(10) NOT NULL,
`ForumID` int(10) NOT NULL,
PRIMARY KEY (`UserID`,`ForumID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

CREATE TABLE `users_subscriptions` (
`UserID` int(10) NOT NULL,
`TopicID` int(10) NOT NULL,
Expand Down
5 changes: 5 additions & 0 deletions sections/forums/forum.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@
<div class="linkbox">
<? if (check_forumperm($ForumID, 'Write') && check_forumperm($ForumID, 'Create')) { ?>
<a href="forums.php?action=new&amp;forumid=<?=$ForumID?>" class="brackets">New thread</a>
<? } ?>
<? if (!check_user_forum_subscription($UserID, $ForumID)) { ?>
<a href="forums.php?action=forum_subscription&amp;do=subscribe&amp;forumid=<?= $ForumID ?>" class="brackets" title="Automatically subscribe to new threads in this forum">Subscribe</a>
<? } else { ?>
<a href="forums.php?action=forum_subscription&amp;do=unsubscribe&amp;forumid=<?= $ForumID ?>" class="brackets" title="Unsubscribe from new threads in this forum">Unsubscribe</a>
<? } ?>
<a href="#" onclick="$('#searchforum').gtoggle(); this.innerHTML = (this.innerHTML == 'Search this forum' ? 'Hide search' : 'Search this forum'); return false;" class="brackets">Search this forum</a>
<div id="searchforum" class="hidden center">
Expand Down
195 changes: 194 additions & 1 deletion sections/forums/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ function get_thread_info($ThreadID, $Return = true, $SelectiveCache = false, $Ap
if (!$ApiCall) {
error(404);
} else {
return NULL;
return null;
}
}
$ThreadInfo = $DB->next_record(MYSQLI_ASSOC, false);
Expand Down Expand Up @@ -139,3 +139,196 @@ function get_forums() {
}
return $Forums;
}

/**
* Add a forum subscription for the provided user id
*
* @param $UserID
* @param $ForumID
*/
function add_subscribed_forum($UserID, $ForumID) {
global $DB;

$UserID = (int)$DB->escape_str($UserID);
$Subscriptions = get_subscribed_forums($UserID);
if (!in_array($ForumID, $Subscriptions)) {
$Subscriptions[] = $ForumID;
$DB->query("INSERT INTO users_subscribed_forums (UserID, ForumID) VALUES ({$UserID}, $ForumID)");
cache_forum_subscriptions($UserID, $Subscriptions);
}

// Populate the aggregate forum subscription cache
$ForumSubscriptions = get_subscriptions_for_forum($ForumID);
if (!in_array($UserID, $ForumSubscriptions)) {
$ForumSubscriptions[] = $UserID;
cache_aggregate_forum_subscriptions($ForumID, $ForumSubscriptions);
}
}

/**
* Remove a forum subscription from the specified user id
*
* @param $UserID
* @param $ForumID
*/
function remove_subscribed_forum($UserID, $ForumID) {
global $DB;

$UserID = (int)$DB->escape_str($UserID);
$Subscriptions = get_subscribed_forums($UserID);
if (($key = array_search($ForumID, $Subscriptions)) !== false) {
$DB->query("DELETE FROM users_subscribed_forums WHERE ForumID = $ForumID AND UserID = {$UserID}");
unset($Subscriptions[$key]);
cache_forum_subscriptions($UserID, $Subscriptions);
}

$ForumSubscriptions = get_subscriptions_for_forum($ForumID);
if (($key = array_search($UserID, $ForumSubscriptions)) !== false) {
unset($ForumSubscriptions[$key]);
cache_aggregate_forum_subscriptions($ForumID, $ForumSubscriptions);
}
}

/**
* Get a list of forum subscriptions for the given user id
*
* @param $UserID
*
* @return array|int List of forum ids the user has subscribed to
*/
function get_subscribed_forums($UserID) {
global $Cache, $DB;

if (!$Subscriptions = $Cache->get_value("forum_subscriptions_{$UserID}")) {

$UserID = (int)$DB->escape_str($UserID);
$DB->query("SELECT * FROM users_subscribed_forums WHERE UserID = $UserID");
$ResultSet = $DB->to_array();

$Subscriptions = array();
foreach ($ResultSet as $Subscription) {
$Subscriptions[] = $Subscription['ForumID'];
}

cache_forum_subscriptions($UserID, $Subscriptions);

}

return $Subscriptions;
}

/**
* Wrapper method to pull the global requirement on $Cache out of above methods which should
* enable simpler unit testing
*
* @param $UserID
* @param $Subscriptions
*/
function cache_forum_subscriptions($UserID, $Subscriptions) {
global $Cache;

$Cache->set("forum_subscriptions_{$UserID}", $Subscriptions);
}

/**
* Returns true if the user is subscribed to the given forum id; otherwise false
*
* @param $UserID
* @param $ForumID
*
* @return bool
*/
function check_user_forum_subscription($UserID, $ForumID) {
$Subscriptions = get_subscribed_forums($UserID);
if (in_array($ForumID, $Subscriptions)) {
return true;
} else {
return false;
}
}

/**
* Returns a list of users subscribed to the given forum id
*
* @param $ForumID
*
* @return array|int List of user ids subscribed to the forum
*/
function get_subscriptions_for_forum($ForumID) {
global $Cache, $DB;

if (!$Subscriptions = $Cache->get_value("forum_subscriptions_forum_{$ForumID}")) {
$DB->query("SELECT * FROM users_subscribed_forums WHERE ForumID = $ForumID");
$ResultSet = $DB->to_array();

$Subscriptions = array();
foreach ($ResultSet as $Subscription) {
$Subscriptions[] = $Subscription['UserID'];
}
cache_aggregate_forum_subscriptions($ForumID, $Subscriptions);
} else {
$Subscriptions = $Subscriptions;
}

return $Subscriptions;
}

/**
* Wrapper method to pull the global requirement on $Cache out of above methods which should
* enable simpler unit testing
* @param $ForumID
* @param $Subscriptions
*/
function cache_aggregate_forum_subscriptions($ForumID, $Subscriptions) {
global $Cache;

$Cache->set("forum_subscriptions_forum_{$ForumID}", $Subscriptions);
}

/**
* Updates the subscriptions_user_* cache entry to add the given topic ID
* for the specified user
* @param $UserID
* @param $TopicID
*/
function add_topic_subscription_for_user($UserID, $TopicID) {
global $Cache;

$Subscriptions = get_topic_subscriptions_for_user($UserID);
if (!in_array($TopicID, $Subscriptions)) {
$Subscriptions[] = $TopicID;
}

cache_topic_subscriptions_for_user($UserID, $Subscriptions);
}

/**
* Returns a list of topic ids the user is subscribed to
* @param $UserID
*
* @return array|int
*/
function get_topic_subscriptions_for_user($UserID) {
global $Cache, $DB;

if (!$Subscriptions = $Cache->get_value("subscriptions_user_$UserID")) {
$DB->query("SELECT TopicID FROM users_subscriptions WHERE UserID = $UserID");
$ResultSet = $DB->to_array();

$Subscriptions = array();
foreach ($ResultSet as $TopicID) {
$Subscriptions[] = $TopicID;
}

cache_topic_subscriptions_for_user($UserID, $Subscriptions);

}

return $Subscriptions;
}

function cache_topic_subscriptions_for_user($UserID, $Subscriptions) {
global $Cache;

$Cache->set("subscriptions_user_$UserID", $Subscriptions);
}
4 changes: 2 additions & 2 deletions sections/forums/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@
case 'warn':
require(SERVER_ROOT.'/sections/forums/warn.php');
break;
case 'forum_subscribe':
include('subscribe.php');
case 'forum_subscription':
include('subscription.php');
break;
default:
error(404);
Expand Down
14 changes: 0 additions & 14 deletions sections/forums/subscribe.php

This file was deleted.

16 changes: 16 additions & 0 deletions sections/forums/subscription.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

if (!check_forumperm($ForumID)) {
error(403);
}

$ForumID = (int)db_string($_GET['forumid']);
$Subscriptions = get_subscribed_forums($LoggedUser['ID']);
if ($_GET['do'] == 'subscribe') {
add_subscribed_forum($UserID, $ForumID);
} elseif ($_GET['do'] == 'unsubscribe') {
remove_subscribed_forum($UserID, $ForumID);
}
header('Location: forums.php?action=viewforum&forumid=' . $ForumID);
?>

39 changes: 18 additions & 21 deletions sections/forums/take_new_thread.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,31 +90,28 @@
LastPostTime = '".sqltime()."'
WHERE ID = '$TopicID'");

if (isset($_POST['subscribe'])) {
$DB->query("
INSERT INTO users_subscriptions
VALUES ($LoggedUser[ID], $TopicID)");
$Cache->delete_value('subscriptions_user_'.$LoggedUser['ID']);
// Do a bulk insert into the users_subscriptions table for all users
// subscribed to this forum
$Subscribers = get_subscriptions_for_forum($ForumID);
if (count($Subscribers) > 0) {
$SubscribersValueString = '(';
$SubscribersValueString .= implode(", $TopicID), (", $Subscribers);
$SubscribersValueString .= ", $TopicID)";
$DB->query("INSERT INTO users_subscriptions (UserID, TopicID) VALUES $SubscribersValueString");
}

//auto subscribe
/*
if (check_perms('users_mod')) {
// Loop through all the users that got subscribed to the thread and
// update the cache entries
foreach($Subscribers as $Subscriber) {
add_topic_subscription_for_user($Subscriber, $TopicID);
}

if (isset($_POST['subscribe']) && !in_array($LoggedUser['ID'], $Subscribers)) {
$DB->query("
SELECT SubscriberID
FROM subscribed_forums
WHERE ForumID = '$ForumID'
AND SubscriberID != '$LoggedUser[ID]'");
while (list($SubscriberID) = $DB->next_record()) {
$DB->query("INSERT INTO users_subscriptions VALUES ($SubscriberID, $TopicID)");
// $DB->query("INSERT INTO forums_last_read_topics
// (UserID, TopicID, PostID) VALUES
// ('$SubscriberID', '".$TopicID ."', '".db_string($PostID)."')
// ON DUPLICATE KEY UPDATE PostID='$LastPost'");
$Cache->delete_value('subscriptions_user_'.$SubscriberID);
}
INSERT INTO users_subscriptions
VALUES ($LoggedUser[ID], $TopicID)");
add_topic_subscription_for_user($LoggedUser['ID'], $TopicID);
}
*/

if (empty($_POST['question']) || empty($_POST['answers']) || !check_perms('forums_polls_create')) {
$NoPoll = 1;
Expand Down