You need to sign in or sign up before continuing.
events.php 6.98 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.
34 35 36 37 38 39 40
 * @param string $entitytype
 * @param int $entityid
 * @param int $questionid
 * @param int $lastpostid
 * @param string $updatetype
 * @param mixed $lastuserid
 * @param int|null $timestamp
Scott committed
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
 */
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
		// 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.
119 120 121 122 123 124
 * @param mixed $userid
 * @param int $questionid
 * @param int $lastpostid
 * @param string $updatetype
 * @param mixed $lastuserid
 * @param int|null $timestamp
Scott committed
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
 */
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).
145 146
 * @param mixed $userid
 * @param int|null $questionid
Scott committed
147 148 149 150 151 152 153 154 155 156 157 158
 */
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
}