Browse Source

! The beginnings of the new alerts system.

Signed-off-by: Peter Spicer <[email protected]>
Peter Spicer 11 years ago
parent
commit
3755692c73

+ 1 - 0
Sources/Load.php

@@ -432,6 +432,7 @@ function loadUserSettings()
 		'smiley_set' => isset($user_settings['smiley_set']) ? $user_settings['smiley_set'] : '',
 		'messages' => empty($user_settings['instant_messages']) ? 0 : $user_settings['instant_messages'],
 		'unread_messages' => empty($user_settings['unread_messages']) ? 0 : $user_settings['unread_messages'],
+		'alerts' => empty($user_settings['alerts']) ? 0 : $user_settings['alerts'],
 		'total_time_logged_in' => empty($user_settings['total_time_logged_in']) ? 0 : $user_settings['total_time_logged_in'],
 		'buddies' => !empty($modSettings['enable_buddylist']) && !empty($user_settings['buddy_list']) ? explode(',', $user_settings['buddy_list']) : array(),
 		'ignoreboards' => !empty($user_settings['ignore_boards']) && !empty($modSettings['allow_ignore_boards']) ? explode(',', $user_settings['ignore_boards']) : array(),

+ 144 - 0
Sources/Profile-View.php

@@ -185,6 +185,150 @@ function summary($memID)
 	loadCustomFields($memID);
 }
 
+/**
+ * Fetch the alerts a user currently has.
+ *
+ * @param int $memID id_member
+ * @param bool $all Fetch all, or only fetch unread.
+ */
+function fetch_alerts($memID, $all = false)
+{
+	global $smcFunc, $txt, $scripturl, $memberContext;
+
+	$alerts = array();
+	$request = $smcFunc['db_query']('', '
+		SELECT id_alert, alert_time, mem.id_member AS sender_id, IFNULL(mem.real_name, ua.member_name) AS sender_name,
+			content_type, content_id, content_action, is_read, extra
+		FROM {db_prefix}user_alerts AS ua
+			LEFT JOIN {db_prefix}members AS mem ON (ua.id_member_started = mem.id_member)
+		WHERE ua.id_member = {int:id_member}' . (!$all ? '
+			AND is_read = 0' : '') . '
+		ORDER BY id_alert DESC',
+		array(
+			'id_member' => $memID,
+		)
+	);
+
+	$senders = array();
+	while ($row = $smcFunc['db_fetch_assoc']($request))
+	{
+		$id_alert = array_shift($row);
+		$row['time'] = timeformat($row['alert_time']);
+		$row['extra'] = !empty($row['extra']) ? @unserialize($row['extra']) : array();
+		$alerts[$id_alert] = $row;
+
+		if (!empty($row['sender_id']))
+			$senders[] = $row['sender_id'];
+	}
+	$smcFunc['db_free_result']($request);
+
+	// Hooks might want to do something snazzy around their own content types - including enforcing permissions if appropriate.
+	call_integration_hook('integrate_fetch_alerts', array(&$alerts));
+
+	if (!empty($senders))
+	{
+		$senders = loadMemberData($senders);
+		foreach ($senders as $member)
+			loadMemberContext($member);
+	}
+
+	// Now go through and actually make with the text.
+	loadLanguage('Alerts');
+
+	// For anything that wants us to check board or topic access, let's do that.
+	$boards = array();
+	$topics = array();
+	$msgs = array();
+	foreach ($alerts as $id_alert => $alert)
+	{
+		if (isset($alert['extra']['board']))
+			$boards[$alert['extra']['board']] = $txt['board_na'];
+		if (isset($alert['extra']['topic']))
+			$topics[$alert['extra']['topic']] = $txt['topic_na'];
+		if ($alert['content_type'] == 'msg')
+			$msgs[$alert['content_id']] = $txt['topic_na'];
+	}
+
+	// Having figured out what boards etc. there are, let's now get the names of them if we can see them. If not, there's already a fallback set up.
+	if (!empty($boards))
+	{
+		$request = $smcFunc['db_query']('', '
+			SELECT id_board, name
+			FROM {db_prefix}boards AS b
+			WHERE {query_see_board}
+				AND id_board IN ({array_int:boards})',
+			array(
+				'boards' => array_keys($boards),
+			)
+		);
+		while ($row = $smcFunc['db_fetch_assoc']($request))
+			$boards[$row['id_board']] = '<a href="' . $scripturl . '?board=' . $row['id_board'] . '.0">' . $row['name'] . '</a>';
+	}
+	if (!empty($topics))
+	{
+		$request = $smcFunc['db_query']('', '
+			SELECT t.id_topic, m.subject
+			FROM {db_prefix}topics AS t
+				INNER JOIN {db_prefix}messages AS m ON (t.id_first_msg = m.id_msg)
+				INNER JOIN {db_prefix}boards AS b ON (t.id_board = b.id_board)
+			WHERE {query_see_board}
+				AND t.id_topic IN ({array_int:topics})',
+			array(
+				'topics' => array_keys($topics),
+			)
+		);
+		while ($row = $smcFunc['db_fetch_assoc']($request))
+			$topics[$row['id_topic']] = '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.0">' . $row['subject'] . '</a>';
+	}
+	if (!empty($msgs))
+	{
+		$request = $smcFunc['db_query']('', '
+			SELECT m.id_msg, t.id_topic, m.subject
+			FROM {db_prefix}messages AS m
+				INNER JOIN {db_prefix}topics AS t ON (t.id_first_msg = m.id_msg)
+				INNER JOIN {db_prefix}boards AS b ON (m.id_board = b.id_board)
+			WHERE {query_see_board}
+				AND m.id_msg IN ({array_int:msgs})',
+			array(
+				'msgs' => array_keys($msgs),
+			)
+		);
+		while ($row = $smcFunc['db_fetch_assoc']($request))
+			$msgs[$row['id_msg']] = '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#msg' . $row['id_msg'] . '">' . $row['subject'] . '</a>';
+	}
+
+	// Now to go back through the alerts, reattach this extra information and then try to build the string out of it (if a hook didn't already)
+	foreach ($alerts as $id_alert => $alert)
+	{
+		if (!empty($alert['text']))
+			continue;
+		if (isset($alert['extra']['board']))
+			$alerts[$id_alert]['extra']['board_msg'] = $boards[$alert['extra']['board']];
+		if (isset($alert['extra']['topic']))
+			$alerts[$id_alert]['extra']['topic_msg'] = $topics[$alert['extra']['topic']];
+		if ($alert['content_type'] == 'msg')
+			$alerts[$id_alert]['extra']['msg_msg'] = $msgs[$alert['content_id']];
+
+		if (!empty($memberContext[$alert['sender_id']]))
+			$alerts[$id_alert]['sender'] = &$memberContext[$alert['sender_id']];
+
+		$string = 'alert_' . $alert['content_type'] . '_' . $alert['content_action'];
+		if (isset($txt[$string]))
+		{
+			$extra = $alerts[$id_alert]['extra'];
+			$search = array('{member_link}');
+			$repl = array(!empty($alert['sender_id']) ? '<a href="' . $scripturl . '?action=profile;u=' . $alert['sender_id'] . '">' . $alert['sender_name'] . '</a>' : $alert['sender_name']);
+			foreach ($extra as $k => $v)
+			{
+				$search[] = '{' . $k . '}';
+				$repl[] = $v;
+			}
+			$alerts[$id_alert]['text'] = str_replace($search, $repl, $txt[$string]);
+		}
+	}
+
+	return $alerts;
+}
 
 /**
  * Show all posts by the current user

+ 28 - 0
Sources/Profile.php

@@ -106,6 +106,14 @@ function ModifyProfile($post_errors = array())
 					),
 					'select' => 'summary',
 				),
+				'alerts_popup' => array(
+					'function' => 'alerts_popup',
+					'permission' => array(
+						'own' => 'is_not_guest',
+						'any' => array(),
+					),
+					'select' => 'summary',
+				),
 				'statistics' => array(
 					'label' => $txt['statPanel'],
 					'file' => 'Profile-View.php',
@@ -775,6 +783,26 @@ function profile_popup($memID)
 	}
 }
 
+/**
+ * Set up the requirements for the alerts popup - the area that shows all the alerts just quickly for the current user.
+ *
+ * @param int $memID
+ */
+function alerts_popup($memID)
+{
+	global $context, $scripturl, $txt, $sourcedir, $db_show_debug;
+
+	// We do not want to output debug information here.
+	$db_show_debug = false;
+
+	// We only want to output our little layer here.
+	$context['template_layers'] = array();
+
+	// Now fetch me my unread alerts, pronto!
+	require_once($sourcedir . '/Profile-View.php');
+	$context['unread_alerts'] = fetch_alerts($memID, false);
+}
+
 /**
  * Load any custom fields for this area... no area means load all, 'summary' loads all public ones.
  *

+ 5 - 3
Sources/Subs.php

@@ -2875,6 +2875,7 @@ function setupThemeContext($forceload = false)
 	{
 		$context['user']['messages'] = &$user_info['messages'];
 		$context['user']['unread_messages'] = &$user_info['unread_messages'];
+		$context['user']['alerts'] = &$user_info['alerts'];
 
 		// Personal message popup...
 		if ($user_info['unread_messages'] > (isset($_SESSION['unread_messages']) ? $_SESSION['unread_messages'] : 0))
@@ -3785,7 +3786,8 @@ function setupMenuContext()
 	{
 		addInlineJavascript('
 	var user_menus = new smc_PopupMenu();
-	user_menus.add("profile", "' . $scripturl . '?action=profile;area=popup");', true);
+	user_menus.add("profile", "' . $scripturl . '?action=profile;area=popup");
+	user_menus.add("alerts", "' . $scripturl . '?action=profile;area=alerts_popup");', true);
 		if ($context['allow_pm'])
 			addInlineJavascript('
 	user_menus.add("pm", "' . $scripturl . '?action=pm;sa=popup");', true);
@@ -4012,8 +4014,8 @@ function setupMenuContext()
 	// There are certain exceptions to the above where we don't want anything on the menu highlighted.
 	if ($context['current_action'] == 'profile' && !empty($context['user']['is_owner']))
 	{
-		$current_action = 'self_profile';
-		$context['self_profile'] = true;
+		$current_action = !empty($_GET['area']) && $_GET['area'] == 'alerts_popup' ? 'self_alerts' : 'self_profile';
+		$context[$current_action] = true;
 	}
 	elseif ($context['current_action'] == 'pm')
 	{

+ 42 - 0
Themes/default/Profile.template.php

@@ -87,6 +87,48 @@ function template_profile_popup()
 		</div>';
 }
 
+function template_alerts_popup()
+{
+	global $context, $txt, $scripturl, $settings;
+
+	// Unlike almost every other template, this is designed to be included into the HTML directly via $().load()
+	echo '
+		<div class="alert_bar">
+			<div class="alerts_opts floatright">
+				<a href="' . $scripturl . '?action=pm;sa=send">', $txt['mark_alerts_read'], '</a>
+				| <a href="', $scripturl, '?action=pm;sa=settings">', $txt['alert_settings'], '</a>
+			</div>
+			<div class="alerts_box floatleft">
+				', $txt['unread_alerts'], '
+				| <a href="', $scripturl, '?action=pm">', $txt['all_alerts'], '</a>
+			</div>
+		</div>
+		<div class="alerts_unread">';
+
+	if (empty($context['unread_alerts']))
+	{
+		echo '
+			<div class="no_unread">', $txt['alerts_no_unread'], '</div>';
+	}
+	else
+	{
+		foreach ($context['unread_alerts'] as $id_alert => $details)
+		{
+			echo '
+			<div class="unread">
+				<div class="avatar floatleft">', !empty($details['sender']) ? $details['sender']['avatar']['image'] : '', '</div>
+				<div class="details floatleft">
+					', !empty($details['icon']) ? $details['icon'] : '', $details['text'], ' - ', $details['time'], '
+				</div>
+				<br class="clear" />
+			</div>';
+		}	
+	}
+
+	echo '
+		</div>';
+}
+
 // This template displays users details without any option to edit them.
 function template_summary()
 {

+ 9 - 9
Themes/default/css/index.css

@@ -1161,26 +1161,26 @@ img.sort, .sort {
 #profile_menu .profile_user_links li img {
 	margin-bottom: -1px;
 }
-#pm_menu .pm_unread {
+#pm_menu .pm_unread, #alerts_menu .alerts_unread {
 	margin-top: 2px;
 	padding-top: 3px;
 	border-top: 1px solid #ddd;
 	clear: both;
 }
-#pm_menu .pm_unread .no_unread {
+#pm_menu .no_unread, #alerts_menu .no_unread {
 	padding-top: 3px;
 	text-align: center;
 }
-#pm_menu .pm_unread .windowbg, #pm_menu .pm_unread .windowbg2 {
+#pm_menu .windowbg, #pm_menu .windowbg2, #alerts_menu .windowbg, #alerts_menu .windowbg2 {
 	clear: both;
 	padding: 2px;
 }
-#pm_menu .pm_unread div > .avatar {
+#pm_menu .pm_unread div > .avatar, #alerts_menu .alerts_unread div > .avatar {
 	width: 40px;
 	height: 40px;
 	margin: 1px 6px 0 1px;
 }
-#pm_menu .pm_unread .avatar img {
+#pm_menu .pm_unread .avatar img, #alerts_menu .alerts_unread .avatar img {
 	width: 100%;
 	height: 100%;
 	max-width: 40px;
@@ -1189,16 +1189,16 @@ img.sort, .sort {
 #pm_menu .unread .subject {
 	font-weight: bold;
 }
-#pm_menu .unread {
+#pm_menu .unread, #alerts_menu .unread {
 	border-bottom: 1px solid #ddd;
 }
-#pm_menu .unread:hover {
+#pm_menu .unread:hover, #alerts_menu .unread:hover  {
 	background: #eee;
 }
-#pm_menu .unread:last-of-type {
+#pm_menu .unread:last-of-type, #alerts_menu .unread:last-of-type {
 	border-bottom: 1px solid transparent;
 }
-#pm_menu .details {
+#pm_menu .details, #alerts_menu .details {
 	max-width: 80%;
 }
 /* This CSS is for adding top level subsection indicators, just in case anyone wants them. */

+ 8 - 0
Themes/default/index.template.php

@@ -201,6 +201,14 @@ function template_body_above()
 				</li>';
 		}
 
+		// Thirdly, alerts
+		echo '
+				<li>
+					<a href="', $scripturl, '?action=alerts"', !empty($context['self_alerts']) ? ' class="active"' : '', ' id="alerts_menu_top">', $txt['alerts'], !empty($context['user']['alerts']) ? ' <span class="amt">' . $context['user']['alerts'] . '</span>' : '', '</a>
+					<div id="alerts_menu" class="top_menu"></div>
+				</li>';
+
+		// And now we're done.
 		echo '
 			</ul>';
 	}

+ 14 - 0
Themes/default/languages/Alerts.english.php

@@ -0,0 +1,14 @@
+<?php
+// Version: 2.1 Alpha 1; Alerts
+
+$txt['topic_na'] = '(private topic)';
+$txt['board_na'] = '(private board)';
+
+$txt['unread_alerts'] = 'Unread';
+$txt['all_alerts'] = 'All alerts';
+$txt['mark_alerts_read'] = 'Mark read';
+$txt['alert_settings'] = 'Settings';
+$txt['alerts_no_unread'] = 'No unread alerts.';
+
+$txt['alert_msg_like'] = '{member_link} liked your post {msg_msg}';
+?>

+ 2 - 0
Themes/default/languages/index.english.php

@@ -740,6 +740,8 @@ $txt['split_reset_selection'] = 'reset selection';
 $txt['modify_cancel'] = 'Cancel';
 $txt['mark_read_short'] = 'Mark Read';
 
+$txt['alerts'] = 'Alerts';
+
 $txt['pm_short'] = 'My Messages';
 $txt['pm_menu_read'] = 'Read your messages';
 $txt['pm_menu_send'] = 'Send a message';

+ 21 - 0
other/install_2-1_mysql.sql

@@ -1246,6 +1246,7 @@ CREATE TABLE {$db_prefix}members (
   instant_messages smallint(5) NOT NULL default 0,
   unread_messages smallint(5) NOT NULL default 0,
   new_pm tinyint(3) unsigned NOT NULL default '0',
+  alerts int(10) unsigned NOT NULL default '0',
   buddy_list text NOT NULL,
   pm_ignore_list varchar(255) NOT NULL default '',
   pm_prefs mediumint(8) NOT NULL default '0',
@@ -2126,6 +2127,26 @@ INSERT INTO {$db_prefix}topics
 VALUES (1, 1, 1, 1, 0, 0);
 # --------------------------------------------------------
 
+#
+# Table structure for table `user_alerts`
+#
+
+CREATE TABLE {$db_prefix}user_alerts (
+  id_alert int(10) unsigned NOT NULL auto_increment,
+  alert_time int(10) unsigned NOT NULL default '0',
+  id_member mediumint(10) unsigned NOT NULL default '0',
+  id_member_started mediumint(10) unsigned NOT NULL default '0',
+  member_name varchar(255) NOT NULL default '',
+  content_type varchar(255) NOT NULL default '',
+  content_id int(10) unsigned NOT NULL default '0',
+  content_action varchar(255) NOT NULL default '',
+  is_read tinyint(3) unsigned NOT NULL default '0',
+  extra text NOT NULL,
+  PRIMARY KEY (id_alert),
+  KEY id_member (id_member),
+  KEY alert_time (alert_time)
+) ENGINE=MyISAM;
+
 #
 # Table structure for table `user_drafts`
 #

+ 31 - 0
other/install_2-1_postgresql.sql

@@ -1649,6 +1649,7 @@ CREATE TABLE {$db_prefix}members (
   instant_messages smallint NOT NULL default 0,
   unread_messages smallint NOT NULL default 0,
   new_pm smallint NOT NULL default '0',
+  alerts int NOT NULL default '0',
   buddy_list text NOT NULL,
   pm_ignore_list varchar(255) NOT NULL,
   pm_prefs int NOT NULL default '0',
@@ -2673,6 +2674,36 @@ INSERT INTO {$db_prefix}topics
 VALUES (1, 1, 1, 1, 0, 0);
 # --------------------------------------------------------
 
+#
+# Sequence for table `user_alerts`
+#
+
+CREATE SEQUENCE {$db_prefix}user_alerts_seq;
+
+#
+# Table structure for table `user_alerts`
+#
+
+CREATE TABLE {$db_prefix}user_alerts (
+  id_alert int default nextval('{$db_prefix}user_alerts_seq'),
+  alert_time int NOT NULL default '0',
+  id_member int NOT NULL default '0',
+  id_member_started int NOT NULL default '0',
+  member_name varchar(255) NOT NULL default '',
+  content_type varchar(255) NOT NULL default '',
+  content_id int NOT NULL default '0',
+  content_action varchar(255) NOT NULL default '',
+  is_read smallint NOT NULL default '0',
+  extra text NOT NULL,
+  PRIMARY KEY (id_alert)
+);
+
+#
+# Indexes for table `user_alerts`
+#
+
+CREATE INDEX {$db_prefix}user_alerts_id_member ON {$db_prefix}user_alerts (id_member);
+CREATE INDEX {$db_prefix}user_alerts_alert_time ON {$db_prefix}user_alerts (alert_time);
 
 #
 # Sequence for table `user_drafts`

+ 26 - 0
other/install_2-1_sqlite.sql

@@ -1350,6 +1350,7 @@ CREATE TABLE {$db_prefix}members (
   instant_messages smallint NOT NULL default 0,
   unread_messages smallint NOT NULL default 0,
   new_pm smallint NOT NULL default '0',
+  alerts int NOT NULL default '0',
   buddy_list text NOT NULL,
   pm_ignore_list varchar(255) NOT NULL,
   pm_prefs int NOT NULL default '0',
@@ -2287,6 +2288,31 @@ INSERT INTO {$db_prefix}topics
 VALUES (1, 1, 1, 1, 0, 0);
 # --------------------------------------------------------
 
+#
+# Table structure for table `user_alerts`
+#
+
+CREATE TABLE {$db_prefix}user_alerts (
+  id_alert int primary key,
+  alert_time int unsigned NOT NULL default '0',
+  id_member int unsigned NOT NULL default '0',
+  id_member_started int unsigned NOT NULL default '0',
+  member_name varchar(255) NOT NULL default '',
+  content_type varchar(255) NOT NULL default '',
+  content_id int unsigned NOT NULL default '0',
+  content_action varchar(255) NOT NULL default '',
+  is_read smallint unsigned NOT NULL default '0',
+  extra text NOT NULL,
+  PRIMARY KEY (id_alert)
+);
+
+#
+# Indexes for table `user_alerts`
+#
+
+CREATE INDEX {$db_prefix}user_alerts_id_member ON {$db_prefix}user_alerts (id_member);
+CREATE INDEX {$db_prefix}user_alerts_alert_time ON {$db_prefix}user_alerts (alert_time);
+
 #
 # Table structure for table `user_drafts`
 #

+ 26 - 0
other/install_2-1_sqlite3.sql

@@ -1350,6 +1350,7 @@ CREATE TABLE {$db_prefix}members (
   instant_messages smallint NOT NULL default 0,
   unread_messages smallint NOT NULL default 0,
   new_pm smallint NOT NULL default '0',
+  alerts int NOT NULL default '0',
   buddy_list text NOT NULL,
   pm_ignore_list varchar(255) NOT NULL,
   pm_prefs int NOT NULL default '0',
@@ -2287,6 +2288,31 @@ INSERT INTO {$db_prefix}topics
 VALUES (1, 1, 1, 1, 0, 0);
 # --------------------------------------------------------
 
+#
+# Table structure for table `user_alerts`
+#
+
+CREATE TABLE {$db_prefix}user_alerts (
+  id_alert int primary key,
+  alert_time int unsigned NOT NULL default '0',
+  id_member int unsigned NOT NULL default '0',
+  id_member_started int unsigned NOT NULL default '0',
+  member_name varchar(255) NOT NULL default '',
+  content_type varchar(255) NOT NULL default '',
+  content_id int unsigned NOT NULL default '0',
+  content_action varchar(255) NOT NULL default '',
+  is_read smallint unsigned NOT NULL default '0',
+  extra text NOT NULL,
+  PRIMARY KEY (id_alert)
+);
+
+#
+# Indexes for table `user_alerts`
+#
+
+CREATE INDEX {$db_prefix}user_alerts_id_member ON {$db_prefix}user_alerts (id_member);
+CREATE INDEX {$db_prefix}user_alerts_alert_time ON {$db_prefix}user_alerts (alert_time);
+
 #
 # Table structure for table `user_drafts`
 #

+ 26 - 0
other/upgrade_2-1_mysql.sql

@@ -242,6 +242,32 @@ ALTER TABLE {$db_prefix}categories
 ADD COLUMN description text NOT NULL;
 ---#
 
+/******************************************************************************/
+--- Adding support for alerts
+/******************************************************************************/
+---# Adding the count to the members table...
+ALERT TABLE {$db_prefix}members
+ADD COLUMN alerts int(10) unsigned NOT NULL default '0';
+---#
+
+---# Adding the new table for alerts.
+CREATE TABLE {$db_prefix}user_alerts (
+  id_alert int(10) unsigned NOT NULL auto_increment,
+  alert_time int(10) unsigned NOT NULL default '0',
+  id_member mediumint(10) unsigned NOT NULL default '0',
+  id_member_started mediumint(10) unsigned NOT NULL default '0',
+  member_name varchar(255) NOT NULL default '',
+  content_type varchar(255) NOT NULL default '',
+  content_id int(10) unsigned NOT NULL default '0',
+  content_action varchar(255) NOT NULL default '',
+  is_read tinyint(3) unsigned NOT NULL default '0',
+  extra text NOT NULL,
+  PRIMARY KEY (id_alert),
+  KEY id_member (id_member),
+  KEY alert_time (alert_time)
+) ENGINE=MyISAM;
+---#
+
 /******************************************************************************/
 --- Adding support for topic unwatch
 /******************************************************************************/

+ 29 - 0
other/upgrade_2-1_postgresql.sql

@@ -306,6 +306,35 @@ upgrade_query("
 ---}
 ---#
 
+/******************************************************************************/
+--- Adding support for alerts
+/******************************************************************************/
+---# Adding the count to the members table...
+ALERT TABLE {$db_prefix}members
+ADD COLUMN alerts int NOT NULL default '0';
+---#
+
+---# Adding the new table for alerts.
+CREATE SEQUENCE {$db_prefix}user_alerts_seq;
+
+CREATE TABLE {$db_prefix}user_alerts (
+  id_alert int default nextval('{$db_prefix}user_alerts_seq'),
+  alert_time int NOT NULL default '0',
+  id_member int NOT NULL default '0',
+  id_member_started int NOT NULL default '0',
+  member_name varchar(255) NOT NULL default '',
+  content_type varchar(255) NOT NULL default '',
+  content_id int NOT NULL default '0',
+  content_action varchar(255) NOT NULL default '',
+  is_read smallint NOT NULL default '0',
+  extra text NOT NULL,
+  PRIMARY KEY (id_alert)
+);
+
+CREATE INDEX {$db_prefix}user_alerts_id_member ON {$db_prefix}user_alerts (id_member);
+CREATE INDEX {$db_prefix}user_alerts_alert_time ON {$db_prefix}user_alerts (alert_time);
+---#
+
 /******************************************************************************/
 --- Adding support for topic unwatch
 /******************************************************************************/

+ 38 - 0
other/upgrade_2-1_sqlite.sql

@@ -285,6 +285,44 @@ $smcFunc['db_alter_table']('{db_prefix}log_topics', array(
 ---}
 ---#
 
+/******************************************************************************/
+--- Adding support for alerts
+/******************************************************************************/
+---# Adding the count to the members table...
+---{
+$smcFunc['db_alter_table']('{db_prefix}members', array(
+	'add' => array(
+		'alerts' => array(
+			'name' => 'ualerts',
+			'null' => false,
+			'default' => 0,
+			'type' => 'int',
+			'auto' => false,
+		),
+	)
+));
+---}
+---#
+
+---# Adding the new table for alerts.
+CREATE TABLE {$db_prefix}user_alerts (
+  id_alert int primary key,
+  alert_time int unsigned NOT NULL default '0',
+  id_member int unsigned NOT NULL default '0',
+  id_member_started int unsigned NOT NULL default '0',
+  member_name varchar(255) NOT NULL default '',
+  content_type varchar(255) NOT NULL default '',
+  content_id int unsigned NOT NULL default '0',
+  content_action varchar(255) NOT NULL default '',
+  is_read smallint unsigned NOT NULL default '0',
+  extra text NOT NULL,
+  PRIMARY KEY (id_alert)
+);
+
+CREATE INDEX {$db_prefix}user_alerts_id_member ON {$db_prefix}user_alerts (id_member);
+CREATE INDEX {$db_prefix}user_alerts_alert_time ON {$db_prefix}user_alerts (alert_time);
+---#
+
 /******************************************************************************/
 --- Adding support for topic unwatch
 /******************************************************************************/