events.php 6.89 KB
Newer Older
Scott committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
<?php
/*
	Question2Answer by Gideon Greenspan and contributors
	http://www.question2answer.org/

	Description: Database-level access to userevents and sharedevents tables


	This program is free software; you can redistribute it and/or
	modify it under the terms of the GNU General Public License
	as published by the Free Software Foundation; either version 2
	of the License, or (at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	More about this license: http://www.question2answer.org/license.php
*/

Scott committed
22
if (!defined('QA_VERSION')) { // don't allow this page to be requested directly from browser
23
	header('Location: ../../');
Scott committed
24 25 26 27 28 29 30 31 32
	exit;
}


/**
 * Add an event to the event streams for entity $entitytype with $entityid. The event of type $updatetype relates to
 * $lastpostid whose antecedent question is $questionid, and was caused by $lastuserid. Pass a unix $timestamp for the
 * event time or leave as null to use now. This will add the event both to the entity's shared stream, and the
 * individual user streams for any users following the entity not via its shared stream (See long comment in
33
 * /qa-include/db/favorites.php). Also handles truncation.
Scott committed
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
 * @param $entitytype
 * @param $entityid
 * @param $questionid
 * @param $lastpostid
 * @param $updatetype
 * @param $lastuserid
 * @param $timestamp
 */
function qa_db_event_create_for_entity($entitytype, $entityid, $questionid, $lastpostid, $updatetype, $lastuserid, $timestamp = null)
{
	require_once QA_INCLUDE_DIR . 'db/maxima.php';
	require_once QA_INCLUDE_DIR . 'app/updates.php';

	$updatedsql = isset($timestamp) ? ('FROM_UNIXTIME(' . qa_db_argument_to_mysql($timestamp, false) . ')') : 'NOW()';

	// Enter it into the appropriate shared event stream for that entity

	qa_db_query_sub(
		'INSERT INTO ^sharedevents (entitytype, entityid, questionid, lastpostid, updatetype, lastuserid, updated) ' .
		'VALUES ($, #, #, #, $, $, ' . $updatedsql . ')',
		$entitytype, $entityid, $questionid, $lastpostid, $updatetype, $lastuserid
	);

	// If this is for a question entity, check the shared event stream doesn't have too many entries for that question

	$questiontruncated = false;

	if ($entitytype == QA_ENTITY_QUESTION) {
		$truncate = qa_db_read_one_value(qa_db_query_sub(
			'SELECT updated FROM ^sharedevents WHERE entitytype=$ AND entityid=# AND questionid=# ORDER BY updated DESC LIMIT #,1',
			$entitytype, $entityid, $questionid, QA_DB_MAX_EVENTS_PER_Q
		), true);
Scott committed
66

Scott committed
67 68 69 70 71
		if (isset($truncate)) {
			qa_db_query_sub(
				'DELETE FROM ^sharedevents WHERE entitytype=$ AND entityid=# AND questionid=# AND updated<=$',
				$entitytype, $entityid, $questionid, $truncate
			);
Scott committed
72

Scott committed
73
			$questiontruncated = true;
Scott committed
74
		}
Scott committed
75
	}
Scott committed
76

Scott committed
77
	// If we didn't truncate due to a specific question, truncate the shared event stream for its overall length
Scott committed
78

Scott committed
79 80 81 82
	if (!$questiontruncated) {
		$truncate = qa_db_read_one_value(qa_db_query_sub(
			'SELECT updated FROM ^sharedevents WHERE entitytype=$ AND entityid=$ ORDER BY updated DESC LIMIT #,1',
			$entitytype, $entityid, (int)qa_opt('max_store_user_updates')
Scott committed
83 84
		), true);

Scott committed
85
		if (isset($truncate))
Scott committed
86
			qa_db_query_sub(
Scott committed
87 88
				'DELETE FROM ^sharedevents WHERE entitytype=$ AND entityid=$ AND updated<=$',
				$entitytype, $entityid, $truncate
Scott committed
89 90 91
			);
	}

Scott committed
92
	// See if we can identify a user who has favorited this entity, but is not using its shared event stream
Scott committed
93

Scott committed
94 95 96 97 98 99 100
	$randomuserid = qa_db_read_one_value(qa_db_query_sub(
		'SELECT userid FROM ^userfavorites WHERE entitytype=$ AND entityid=# AND nouserevents=0 ORDER BY RAND() LIMIT 1',
		$entitytype, $entityid
	), true);

	if (isset($randomuserid)) {
		// If one was found, this means we have one or more individual event streams, so update them all
Scott committed
101
		qa_db_query_sub(
Scott committed
102 103 104
			'INSERT INTO ^userevents (userid, entitytype, entityid, questionid, lastpostid, updatetype, lastuserid, updated) ' .
			'SELECT userid, $, #, #, #, $, $, ' . $updatedsql . ' FROM ^userfavorites WHERE entitytype=$ AND entityid=# AND nouserevents=0',
			$entitytype, $entityid, $questionid, $lastpostid, $updatetype, $lastuserid, $entitytype, $entityid
Scott committed
105 106
		);

Scott committed
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
		// Now truncate the random individual event stream that was found earlier
		// (in theory we should truncate them all, but truncation is just a 'housekeeping' activity, so it's not necessary)
		qa_db_user_events_truncate($randomuserid, $questionid);
	}
}


/**
 * Add an event to the event stream for $userid which is not related to an entity they are following (but rather a
 * notification which is relevant for them, e.g. if someone answers their question). The event of type $updatetype
 * relates to $lastpostid whose antecedent question is $questionid, and was caused by $lastuserid. Pass a unix
 * $timestamp for the event time or leave as null to use now. Also handles truncation of event streams.
 * @param $userid
 * @param $questionid
 * @param $lastpostid
 * @param $updatetype
 * @param $lastuserid
 * @param $timestamp
 */
function qa_db_event_create_not_entity($userid, $questionid, $lastpostid, $updatetype, $lastuserid, $timestamp = null)
{
	require_once QA_INCLUDE_DIR . 'app/updates.php';

	$updatedsql = isset($timestamp) ? ('FROM_UNIXTIME(' . qa_db_argument_to_mysql($timestamp, false) . ')') : 'NOW()';

	qa_db_query_sub(
		"INSERT INTO ^userevents (userid, entitytype, entityid, questionid, lastpostid, updatetype, lastuserid, updated) " .
		"VALUES ($, $, 0, #, #, $, $, " . $updatedsql . ")",
		$userid, QA_ENTITY_NONE, $questionid, $lastpostid, $updatetype, $lastuserid
	);

	qa_db_user_events_truncate($userid, $questionid);
}


/**
 * Trim the number of events in the event stream for $userid. If an event was just added for a particular question,
 * pass the question's id in $questionid (to help focus the truncation).
 * @param $userid
 * @param $questionid
 */
function qa_db_user_events_truncate($userid, $questionid = null)
{
	// First try truncating based on there being too many events for this question

	$questiontruncated = false;

	if (isset($questionid)) {
		$truncate = qa_db_read_one_value(qa_db_query_sub(
			'SELECT updated FROM ^userevents WHERE userid=$ AND questionid=# ORDER BY updated DESC LIMIT #,1',
			$userid, $questionid, QA_DB_MAX_EVENTS_PER_Q
		), true);
Scott committed
159

Scott committed
160 161 162 163 164
		if (isset($truncate)) {
			qa_db_query_sub(
				'DELETE FROM ^userevents WHERE userid=$ AND questionid=# AND updated<=$',
				$userid, $questionid, $truncate
			);
Scott committed
165

Scott committed
166
			$questiontruncated = true;
Scott committed
167
		}
Scott committed
168
	}
Scott committed
169

Scott committed
170
	// If that didn't happen, try truncating the stream in general based on its total length
Scott committed
171

Scott committed
172 173 174 175 176
	if (!$questiontruncated) {
		$truncate = qa_db_read_one_value(qa_db_query_sub(
			'SELECT updated FROM ^userevents WHERE userid=$ ORDER BY updated DESC LIMIT #,1',
			$userid, (int)qa_opt('max_store_user_updates')
		), true);
Scott committed
177

Scott committed
178 179 180 181 182
		if (isset($truncate))
			qa_db_query_sub(
				'DELETE FROM ^userevents WHERE userid=$ AND updated<=$',
				$userid, $truncate
			);
Scott committed
183
	}
Scott committed
184
}