Files
Emi 07ec659385 Importing project into Git
This project lived only on the server without version control. This is now the starting point for the repository.
2023-05-23 20:03:24 +02:00

185 lines
7.1 KiB
PHP

<?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
*/
if (!defined('QA_VERSION')) { // don't allow this page to be requested directly from browser
header('Location: ../../');
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
* /qa-include/db/favorites.php). Also handles truncation.
* @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);
if (isset($truncate)) {
qa_db_query_sub(
'DELETE FROM ^sharedevents WHERE entitytype=$ AND entityid=# AND questionid=# AND updated<=$',
$entitytype, $entityid, $questionid, $truncate
);
$questiontruncated = true;
}
}
// If we didn't truncate due to a specific question, truncate the shared event stream for its overall length
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')
), true);
if (isset($truncate))
qa_db_query_sub(
'DELETE FROM ^sharedevents WHERE entitytype=$ AND entityid=$ AND updated<=$',
$entitytype, $entityid, $truncate
);
}
// See if we can identify a user who has favorited this entity, but is not using its shared event stream
$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
qa_db_query_sub(
'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
);
// 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);
if (isset($truncate)) {
qa_db_query_sub(
'DELETE FROM ^userevents WHERE userid=$ AND questionid=# AND updated<=$',
$userid, $questionid, $truncate
);
$questiontruncated = true;
}
}
// If that didn't happen, try truncating the stream in general based on its total length
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);
if (isset($truncate))
qa_db_query_sub(
'DELETE FROM ^userevents WHERE userid=$ AND updated<=$',
$userid, $truncate
);
}
}