diff --git a/www/adminops b/www/adminops
index 14effb6f..4fbee3c7 100644
--- a/www/adminops
+++ b/www/adminops
@@ -79,393 +79,8 @@ if (isset($_REQUEST['adminemail'])) {
//------------------ RECENT ACTIVITY BY ALL USERS --------------
-// For long author and title strings, cut off the
-// string after a set number of characters and
-// add "..." if any characters were removed.
-function shortenString($long_string) {
- $short_string = substr($long_string,0,50);
- if ($short_string != $long_string) {
- $short_string .= "...";
- }
- return $short_string;
-}
+include "adminops-components/recent-activity.php";
-
-if (isset($_REQUEST['recentactivity'])) {
- // Find how many days of recent activity to display.
- // If it's not specified, default to 3 days.
- $recent_days = (int)get_req_data('days');
- if ($recent_days == 0) {
- $recent_days = 3;
- }
- pageHeader("Recent activity by all users");
- echo '
Recent activity by all users
';
- echo "Showing activity from the past $recent_days days. For a different number of days, please edit the URL.
";
- // Horizontal menu to jump to different types of activity
- echo '';
- echo 'Ratings and reviews | ';
- echo 'Review votes | ';
- echo 'Page edits | ';
- echo 'Tags | ';
- echo 'Poll votes';
- echo '
';
-
-
- // Find recent ratings and reviews
- $result = mysqli_execute_query($db,
- 'SELECT
- reviews.moddate AS reviewdatetime,
- CASE WHEN reviews.createdate = reviews.moddate
- THEN "added"
- ELSE "edited"
- END AS action,
- DATE_FORMAT(reviews.moddate, "%M %e, %Y") AS reviewdate,
- reviews.userid AS reviewerid,
- reviews.gameid,
- reviews.rating,
- reviews.review,
- reviews.id AS reviewid,
- CASE WHEN reviews.special = 4
- THEN "external "
- ELSE ""
- END AS externalreview,
- games.title AS gametitle,
- games.author AS gameauthor,
- users.name AS reviewername
- FROM reviews
- LEFT JOIN games
- ON reviews.gameid = games.id
- LEFT JOIN users
- ON reviews.userid = users.id
- WHERE (reviews.moddate) > DATE_SUB(NOW(), INTERVAL ? DAY)
- ORDER BY reviews.moddate DESC', [$recent_days]);
-
-
- // Display recent ratings and reviews
- echo "Recent ratings and reviews:
";
- if (mysqli_num_rows($result) > 0) {
- $rows = mysqli_fetch_all($result, MYSQLI_ASSOC);
- $date_heading = "";
- foreach ($rows as $r) {
- $review_date = $r['reviewdate'];
- $reviewer_id = $r['reviewerid'];
- $reviewer_name = $r['reviewername'];
- $external_review = $r['externalreview'];
- $action = $r['action'];
- $rating = "";
- if ($r['rating']) {
- $rating = $r['rating'];
- } else {
- $rating = "no";
- }
- $review_id = $r['reviewid'];
- $rating_or_review = "";
- if ($r['review'] != "") {
- $rating_or_review = "review";
- } else {
- $rating_or_review = "rating";
- }
- $game_id = $r['gameid'];
- $game_title = shortenString($r['gametitle']);
- $game_author = shortenString($r['gameauthor']);
-
- // If the current rating/review has a different
- // date than the last rating/review we printed,
- // display a heading showing the new date
- if ($review_date != $date_heading) {
- if ($date_heading != "") {
- echo "";
- }
- $date_heading = $review_date;
- echo "$date_heading
";
- echo "";
- }
- // Print a little report about this rating/review
- if ($reviewer_name) {
- echo "- $reviewer_name ";
- } else {
- echo "
- Someone "; // External reviews won't have a reviewer name or a regular reviewer id
- }
- if ($action == "added") {
- echo "added ";
- } else if ($action == "edited") {
- echo "edited a rating or review, now ";
- }
- echo "a {$rating}-star {$external_review}{$rating_or_review} ";
- echo "of $game_title by $game_author.
";
- }
- echo "
";
- } else {
- echo "No ratings or reviews in the past $recent_days days.
";
- }
- echo 'Return to top
';
-
-
- // Find recent review helpfulness votes
- $result = mysqli_execute_query($db,
- 'SELECT
- reviewvotes.createdate AS votedatetime,
- DATE_FORMAT(reviewvotes.createdate, "%M %e, %Y") AS votedate,
- reviewvotes.userid as voterid,
- reviewvotes.vote,
- reviewvotes.reviewid,
- reviews.gameid,
- reviews.userid as reviewerid,
- users.name AS reviewername
- FROM reviewvotes
- LEFT JOIN reviews
- ON reviewvotes.reviewid = reviews.id
- LEFT JOIN users
- ON reviews.userid = users.id
- WHERE (reviewvotes.createdate) > DATE_SUB(NOW(), INTERVAL ? DAY)
- ORDER BY reviewvotes.createdate DESC LIMIT 100', [$recent_days]);
-
-
- // Display recent review helpfulness votes
- echo 'Recent votes on review helpfulness:
';
- if (mysqli_num_rows($result) > 0) {
- $rows = mysqli_fetch_all($result, MYSQLI_ASSOC);
- $date_heading = "";
- foreach ($rows as $r) {
- $vote_date = $r['votedate'];
- $voter_id = $r['voterid'];
- $vote = "";
- if ($r['vote'] == "Y") {
- $vote = "Yes";
- } else if ($r['vote'] == "N") {
- $vote = "No";
- };
- $review_id = $r['reviewid'];
- $game_id = $r['gameid'];
- $reviewer_id = $r['reviewerid'];
- $reviewer_name = shortenString($r['reviewername']);
-
- // If the current vote has a different
- // date than the last vote we printed,
- // display a heading showing the new date
- if ($vote_date != $date_heading) {
- if ($date_heading != "") {
- echo "";
- }
- $date_heading = $vote_date;
- echo "$date_heading
";
- echo "";
- }
- // Print a little report about this review vote
- echo "- User $voter_id ";
- echo 'voted "' . $vote . '" on a ';
- echo "review ";
- echo "by $reviewer_name.
";
- }
- echo "
";
- } else {
- echo "No votes on review helpfulness in the past $recent_days days.
";
- }
- echo 'Return to top
';
-
-
- // Find recent page edits
- $result = mysqli_execute_query($db,
- 'SELECT
- games_history.moddate AS editdatetime,
- DATE_FORMAT(games_history.moddate, "%M %e, %Y") AS editdate,
- games_history.id as gameid,
- games_history.editedby as editorid,
- games.title AS gametitle,
- games.author AS gameauthor,
- users.name AS editorname
- FROM games_history
- LEFT JOIN games
- ON games_history.id = games.id
- LEFT JOIN users
- ON games_history.editedby = users.id
- WHERE (games_history.moddate) > DATE_SUB(NOW(), INTERVAL ? DAY)
- ORDER BY games_history.moddate DESC', [$recent_days]);
-
-
- // Display recent page edits
- echo "Recent page edits:
";
- if (mysqli_num_rows($result) > 0) {
- $rows = mysqli_fetch_all($result, MYSQLI_ASSOC);
- $date_heading = "";
- foreach ($rows as $r) {
- $edit_date = $r['editdate'];
- $editor_id = $r['editorid'];
- $editor_name = $r['editorname'];
- $game_id = $r['gameid'];
- $game_title = shortenString($r['gametitle']);
- $game_author = shortenString($r['gameauthor']);
-
- // If this page edit has a different date
- // than the last page edit we printed,
- // display a heading showing the new date
- if ($edit_date != $date_heading) {
- if ($date_heading != "") {
- echo "";
- }
- $date_heading = $edit_date;
- echo "$date_heading
";
- echo "";
- }
- // Print a little report about this page edit
- echo "- $editor_name ";
- echo "edited the page for ";
- echo "$game_title ";
- echo "by $game_author.
";
- }
- echo "
";
- } else {
- echo "No page edits in the past $recent_days days.
";
- }
- echo 'Return to top
';
-
-
- // Find recent tagging activity
- $result = mysqli_execute_query($db,
- 'SELECT
- gametags.moddate AS tagdatetime,
- DATE_FORMAT(gametags.moddate, "%M %e, %Y") AS tagdate,
- gametags.gameid,
- gametags.userid as taggerid,
- gametags.tag,
- games.title AS gametitle,
- games.author AS gameauthor
- FROM gametags
- LEFT JOIN games
- ON gametags.gameid = games.id
- WHERE (gametags.moddate) > DATE_SUB(NOW(), INTERVAL ? DAY)
- ORDER BY gametags.moddate DESC', [$recent_days]);
-
-
- // Display recent tagging activity
- echo "";
- if (mysqli_num_rows($result) > 0) {
- $rows = mysqli_fetch_all($result, MYSQLI_ASSOC);
- $date_heading = "";
- foreach ($rows as $r) {
- $tag_date = $r['tagdate'];
- $tagger_id = $r['taggerid'];
- $tag = $r['tag'];
- $game_id = $r['gameid'];
- $game_title = shortenString($r['gametitle']);
- $game_author = shortenString($r['gameauthor']);
-
- // If this tagging action has a different date
- // than the last tagging action we printed,
- // display a heading showing the new date
- if ($tag_date != $date_heading) {
- if ($date_heading != "") {
- echo "";
- }
- $date_heading = $tag_date;
- echo "$date_heading
";
- echo "";
- }
- // Print a little report about this tagging action
- echo "- User $tagger_id ";
- echo 'added the tag "' . $tag . '" to ';
- echo "$game_title ";
- echo "by $game_author.
";
- }
- echo "
";
- } else {
- echo "No tagging activity in the past $recent_days days.
";
- }
- echo 'Return to top
';
-
-
- // Find recent poll votes
- $result = mysqli_execute_query($db,
- 'SELECT
- pollvotes.votedate AS votedatetime,
- DATE_FORMAT(pollvotes.votedate, "%M %e, %Y") AS votedate,
- pollvotes.userid as voterid,
- pollvotes.gameid,
- pollvotes.quickquote,
- pollvotes.notes,
- pollvotes.pollid,
- games.title AS gametitle,
- games.author AS gameauthor,
- users.name AS votername,
- polls.title AS polltitle,
- CASE WHEN polls.flags = 1
- THEN true
- ELSE false
- END AS voteisanonymous
- FROM pollvotes
- LEFT JOIN games
- ON pollvotes.gameid = games.id
- LEFT JOIN users
- ON pollvotes.userid = users.id
- LEFT JOIN polls
- on pollvotes.pollid = polls.pollid
- WHERE (pollvotes.votedate) > DATE_SUB(NOW(), INTERVAL ? DAY)
- ORDER BY pollvotes.votedate DESC', [$recent_days]);
-
- // Display recent poll votes
- echo "Recent poll votes:
";
- if (mysqli_num_rows($result) > 0) {
- $rows = mysqli_fetch_all($result, MYSQLI_ASSOC);
- $date_heading = "";
- foreach ($rows as $r) {
- $vote_date = $r['votedate'];
- $voter_id = $r['voterid'];
- $voter_name = $r['votername'];
- $quick_quote = $r['quickquote'];
- $notes = $r['notes'];
- $game_id = $r['gameid'];
- $game_title = shortenString($r['gametitle']);
- $game_author = shortenString($r['gameauthor']);
- $poll_id = $r['pollid'];
- $poll_title = shortenString($r['polltitle']);
- $vote_is_anonymous = ($r['voteisanonymous']);
-
- // If this poll vote has a different date
- // than the last poll vote we printed,
- // display a heading showing the new date
- if ($vote_date != $date_heading) {
- if ($date_heading != "") {
- echo "";
- }
- $date_heading = $vote_date;
- echo "$date_heading
";
- echo "";
- }
- // Print a little report about this poll vote
- echo "- ";
- if (!$vote_is_anonymous) {
- echo "$voter_name";
- } else if ($vote_is_anonymous) {
- echo "User $voter_id";
- }
- echo " voted for ";
- echo "$game_title by $game_author ";
- echo "in the poll $poll_title.";
- if ($quick_quote || $notes) {
- echo ' Comment: "' ;
- if ($quick_quote) {
- echo $quick_quote;
- if ($notes) {
- echo ": $notes";
- }
- } else {
- echo $notes;
- }
- echo '" ';
- }
- echo "
";
- }
- echo "
";
- } else {
- echo "No poll votes in the past $recent_days days.
";
- }
- echo 'Return to top
';
- echo '
';
- echo 'Return to the System Maintenance Panel
';
- pageFooter();
- exit();
-} // if (isset($_REQUEST['recentactivity']))
-
//----------------- end of recent activity -------------
//----------------- BEGIN MANAGE SUSPICIOUS DOMAINS -----------
@@ -1930,635 +1545,8 @@ else if (isset($_REQUEST['users'])) {
. "$ctxt
";
}
-} else if (isset($_REQUEST['reaper'])) {
-
- $limit = (int)$_REQUEST['reaper'];
- if ($limit < 0)
- $limit = 30;
- $result = mysql_query(
- "select persistentsessions.id, userid, persistentsessions.lastlogin,
- name, email,
- to_days(now()) - to_days(persistentsessions.lastlogin)
- from persistentsessions, users
- where
- persistentsessions.lastlogin <= date_sub(now(), interval $limit day)
- and users.id = persistentsessions.userid", $db);
-
- if (mysql_num_rows($result) == 0)
- echo "No sessions were found that have been inactive for "
- . "$limit day(s) or more.";
- else {
- echo "| User Name | Email | "
- . "Last Login | Days Inactive |
";
-
- for ($i = 0 ; $i < mysql_num_rows($result) ; $i++) {
- list($sid, $uid, $login, $name, $email, $days) =
- mysql_fetch_row($result);
-
- $sid = mysql_real_escape_string($sid, $db);
- $name = htmlspecialcharx($name);
- $email = htmlspecialcharx($email);
-
- $bg = (($i % 2) == 0) ? "evenRow" : "oddRow";
- echo ""
- . "| $name | "
- . "$email | "
- . "$login | "
- . "$days | "
- . "
";
- }
-
- echo "
";
-
- if (isset($_REQUEST['delete'])) {
- $result = mysql_query(
- "delete from persistentsessions
- where lastlogin <= date_sub(now(), interval $limit day)",
- $db);
-
- if ($result)
- echo "The sessions above have been "
- . "deleted.";
- else
- echo "An error occurred deleting inactive "
- . "sessions.";
-
- echo "Refresh the list";
-
- } else {
-
- echo "
"
- . "Delete these sessions";
-
- }
-
- echo "
";
- }
-
-} else if (isset($_REQUEST['fixsortkeys'])) {
-
- $errMsg = false;
- $rebuild = isset($_REQUEST['rebuild']);
- $where = ($rebuild
- ? ""
- : "where sort_title is null or sort_title = ''
- or sort_author is null or sort_author = ''");
-
- $result = mysql_query(
- "select id, title, author, sort_title, sort_author
- from games $where", $db);
- if (!$result)
- $errMsg = "Query failed: " . mysql_error($db);
-
- for ($rows = array(), $i = 0 ; $i < mysql_num_rows($result) ; $i++)
- $rows[] = mysql_fetch_array($result, MYSQL_ASSOC);
-
- foreach ($rows as $r) {
- $gameid = mysql_real_escape_string($r['id'], $db);
- $title = $r['title'];
- $author = $r['author'];
- $sortTitle = $r['sort_title'];
- $sortAuthor = $r['sort_author'];
-
- $setVars = array();
-
- if ($rebuild || $sortTitle == "")
- $setVars[] = "sort_title = '"
- . mysql_real_escape_string(strtoupper(
- getSortingTitle($title)), $db) . "'";
-
- if ($rebuild || $sortAuthor == "")
- $setVars[] = "sort_author = '"
- . mysql_real_escape_string(strtoupper(
- getSortingPersonalNameList($author)), $db) . "'";
-
- $setVars = implode(",", $setVars);
- $result = mysql_query(
- "update games set $setVars where id='$gameid'", $db);
- if (!$result) {
- $errMsg = "Update failed: id=$gameid; " . mysql_error($db);
- break;
- }
- }
-
- echo "Fix/Rebuild GAMES table SORT keys
";
- if ($errMsg)
- echo "$errMsg";
- else
- echo "Success: " . count($rows) . " row(s) updated
- in GAMES table";
-
- echo "
";
-
-} else if (isset($_REQUEST['fixbafs'])) {
-
- // query up the Baf's reviews that contain tags
- $result = mysql_query(
- "select
- reviews.id as id, reviews.review as review, games.title as title
- from
- reviews, specialreviewers, games
- where
- reviews.special = specialreviewers.id
- and specialreviewers.code = 'bafs'
- and games.id = reviews.gameid
- and reviews.review like '%<%'", $db);
-
- // note if we're in APPLY mode
- $applyMode = isset($_REQUEST['apply']);
-
- // allowed tags - we keep these tags without modification
- $allowedTags = valuesToKeys(
- array('p', 'br',
- 'i', 'b', 'u', 'strong', 'em',
- 'big', 'small', 'tt', 'sup', 'sub',
- 'cite', 'blockquote',
- 'ul', 'ol', 'li', 'dl', 'dt', 'dd'), 1);
-
- $updateCount = 0;
- $errRows = false;
- $allBadTags = array();
-
- while (($row = mysql_fetch_array($result, MYSQL_ASSOC)) != false) {
-
- // decode the row
- $title = $row['title'];
- $rid = $row['id'];
- $txt = $origTxt = $row['review'];
-
- // no unknown tags for this row yet
- $badTags = array();
-
- // scan it for tags we actually need to fix
- $inAnchor = false;
- for ($ofs = 0 ; ($ofs = strpos($txt, '<', $ofs)) !== false ; ) {
- // remember where the tag starts
- $tagOfs = $ofs;
-
- // find the end of the tag
- if (($gt = strpos($txt, '>', $ofs+1)) === false) {
- ++$ofs;
- continue;
- }
-
- // note the length of the full tag from < to >
- $tagLen = $gt + 1 - $ofs;
-
- // pull out the tag name
- $tagName = trim(substr($txt, $ofs + 1, $gt - $ofs - 1));
-
- // if it's a close tag, drop the slash
- $isClose = false;
- if (substr($tagName, 0, 1) == '/') {
- $isClose = true;
- $tagName = trim(substr($tagName, 1));
- }
-
- // check for auto-closing tags
- $isAutoClose = false;
- if (substr($tagName, -1, 1) == '/') {
- $isAutoClose = true;
- $tagName = trim(substr($tagName, 0, -1));
- }
-
- // if we have parameters, pull them out
- $tagAttr = false;
- $sp = strpos($tagName, ' ');
- if ($sp !== false) {
- $tagAttr = trim(substr($tagName, $sp + 1));
- $tagName = substr($tagName, 0, $sp);
- }
-
- // canonicalize the case
- $tagName = strtolower($tagName);
-
- // check what we have
- if (isset($allowedTags[$tagName])) {
- // this one goes through unchanged - just skip it
- $ofs = $gt + 1;
- } else if ($tagName == 'a') {
- // Anchor tag - check for open/close
- if ($isClose) {
- // close - if we're in an anchor, keep it; otherwise
- // delete it
- if ($inAnchor) {
- $inAnchor = false;
- $ofs = $gt;
- } else {
- $txt = substr_replace($txt, "", $tagOfs, $tagLen);
- }
- } else {
- // Open anchor - check the href. If it looks like
- // a baf's game reference, change it to an IFDB
- // game reference. Otherwise just delete it, since
- // we don't allow off-site references in reviews.
- $keepA = false;
-
- // $$$ special cases just for our initial import - these
- // fix a couple of items that are broken in the Baf's data
- if ($tagAttr == "href=game/1822")
- $tagAttr = "href=game/2277";
- else if ($tagAttr == "hre=game/1")
- $tagAttr = "href=game/1";
-
- if (preg_match("/^href=([\"']?)game\/([0-9]+)\\1$/i",
- $tagAttr, $match, 0, 0)
- || preg_match("/^href=([\"'])http:\/\/"
- . "(?:www\.)?wurb\.com"
- . "\/if\/game\/([0-9]+)\\1$/i",
- $tagAttr, $match, 0, 0)) {
-
- // it's a Baf's game reference - look up the game
- $qbafsID = mysql_real_escape_string($match[2], $db);
- $result2 = mysql_query(
- "select id from games where bafsid='$qbafsID'",
- $db);
-
- // if we found a match, rewrite it
- if (mysql_num_rows($result2) > 0) {
- $keepA = true;
- $gameID = mysql_result($result2, 0, "id");
- $newTag = "";
-
- $txt = substr_replace(
- $txt, $newTag, $tagOfs, $tagLen);
- $ofs += strlen($newTag);
-
- $inAnchor = true;
- }
- } else if (preg_match("/^game=([\"'])([a-z0-9]+)\\1$/i",
- $tagAttr, $match, 0, 0)) {
-
- // it's already in our own format - keep it as-is
- $keepA = true;
- $ofs = $gt;
- $inAnchor = true;
- }
-
- // if we're not keeping the tag, delete it
- if (!$keepA) {
- $badTags["a($tagAttr)"] = true;
- $txt = substr_replace($txt, "", $tagOfs, $tagLen);
- }
- }
- } else {
- // it's not an allowed tag - note it and keep going
- $badTags[$tagName] = true;
- $txt = substr_replace($txt, "", $tagOfs, $tagLen);
- }
- }
-
- // check for changes
- if (count($badTags) != 0 || $txt != $origTxt) {
- // count it
- $updateCount++;
-
- // note any bad tags
- echo "Review ID=$rid (title=$title):
"
- . "
";
- if (count($badTags) != 0) {
- echo "Bad tags found:
"
- . implode("
", array_keys($badTags))
- . "
";
- }
- echo "Updated review text:
"
- . fixDesc($txt)
- . "
";
-
- foreach ($badTags as $k=>$v)
- $allBadTags[$k] = true;
- }
- // if we're in APPLY mode, apply the changes
- if ($applyMode) {
- $qtxt = mysql_real_escape_string($txt, $db);
- $result2 = mysql_query(
- "update reviews set review='$qtxt' where id='$rid'", $db);
-
- if (!$result2) {
- $errRows[] = $rid;
- echo "Error updating row ("
- . mysql_error($db) . ")
";
- }
- }
- }
-
- if (count($allBadTags) != 0) {
- echo "
Summary of bad tags found:
"
- . implode("
", array_keys($allBadTags))
- . "
";
- }
-
- if ($errRows) {
- echo "
Database update errors occurred for "
- . "the following review IDs:
";
- foreach ($errRows as $er)
- echo "$er
";
- echo "
";
- }
-
- if ($updateCount == 0)
- echo "No errors were found - no rows need to be updated";
- else if (!$applyMode)
- echo "
Apply these updates
";
-
-} else if (isset($_REQUEST['rebuildgametags'])) {
-
- // run through the GAMES table and rebuild each TAGS field
- $okCnt = 0;
- $result = mysql_query("select id from games", $db);
- for ($cnt = mysql_num_rows($result), $i = 0 ; $i < $cnt ; $i++) {
-
- // get this game ID
- $gameid = mysql_result($result, $i, "id");
-
- // load its tag list
- $tresult = mysql_query(
- "select tag from gametags where gameid = '$gameid'", $db);
- for ($tags = array(), $j = 0, $tcnt = mysql_num_rows($tresult) ;
- $j < $tcnt ; $j++)
- $tags[] = mysql_result($tresult, $j, "tag");
-
- // turn it into a flat string list
- if ($tcnt == 0)
- $tags = "null";
- else
- $tags = "'"
- . mysql_real_escape_string(implode(",", $tags), $db)
- . "'";
-
- // update the game's TAGS field
- $uresult = mysql_query(
- "update games set tags = $tags where id = '$gameid'", $db);
- if ($uresult)
- $okCnt++;
- else
- echo "Error updating game $gameid, tags=$tags"
- . "
";
- }
-
- echo "
Rows successfully updated: $okCnt
";
-
-} else if (isset($_REQUEST['rebuildgametags2'])) {
-
- // run through GAMES and look for missing GAMETAGS entries
- // run through the GAMES table and rebuild each TAGS field
- $okCnt = 0;
- $result = mysql_query(
- "select id, title, tags from games where tags <> ''", $db);
- for ($cnt = mysql_num_rows($result), $i = 0 ; $i < $cnt ; $i++) {
-
- // get this game ID and tag list
- $gameid = mysql_result($result, $i, "id");
- $tags = explode(",", mysql_result($result, $i, "tags"));
- $title = htmlspecialcharx(mysql_result($result, $i, "title"));
-
- // load the corresponding GAMETAGS list
- $tresult = mysql_query(
- "select tag from gametags where gameid = '$gameid'", $db);
- for ($gametags = array(), $j = 0, $tcnt = mysql_num_rows($tresult) ;
- $j < $tcnt ; $j++)
- $gametags[] = mysql_result($tresult, $j, "tag");
-
- // look for missing gametags entries
- $missingTags = array();
- foreach ($tags as $t) {
- if (!in_array($t, $gametags))
- $missingTags[] = $t;
- }
-
- if (count($missingTags) != 0) {
- echo "$title ($gameid): missing tags { "
- . htmlspecialcharx(implode(",", $missingTags))
- . " }
";
- }
- }
-
- echo "
Rows successfully updated: $okCnt
";
-
-} else if (isset($_REQUEST['cleanpix'])) {
- echo "
Scanning for unreferenced images
"
- . "";
- echo "
";
-
-} else if (isset($_REQUEST['filters'])) {
-
- echo "Game Filters
";
-
- $result = mysql_query(
- "select
- filterID, filterName, ckBoxName, showName, endDate,
- filterType, explanation
- from filters", $db);
- echo mysql_error($db);
- for ($i = 0 ; $i < mysql_num_rows($result) ; $i++) {
- list($filterID, $filterName, $ckBoxName, $showName,
- $endDate, $filterType, $explanation) = mysql_fetch_row($result);
-
- echo "
"
- . "Name: $filterName
"
- . "\"Set\" checkbox label: $ckBoxName
"
- . "\"Opt out\" checkbox label: $showName
"
- . "\"End date: " . ($endDate ? $endDate : "None") . "
"
- . "Filter type: " . $filterTypeMap[$filterType] . "
"
- . "Explanation: " . $explanation . "
";
-
- echo "
Edit"
- . " - Delete
";
- }
-
- echo "
"
- . "Add a new filter"
- . "
";
} else if (isset($_REQUEST['delFilter'])) {
@@ -2723,151 +1711,6 @@ else if (isset($_REQUEST['users'])) {
echo "
";
-} else if (isset($_REQUEST['utf8entities'])) {
- function find_columns_to_fix($db, $table, $columns) {
- $columns_to_fix = [];
- foreach ($columns as $column) {
- $result = mysqli_query($db, "SELECT count(`$column`) from `$table` where `$column` like '%%;%'");
- [$count] = mysqli_fetch_row($result);
- if ($count) $columns_to_fix[] = $column;
- }
- error_log("$table " . json_encode($columns_to_fix));
- return $columns_to_fix;
- }
-
- $result = mysqli_query($db, "SELECT table_name FROM information_schema.tables
- WHERE TABLE_SCHEMA = 'ifdb'
- and TABLE_TYPE='BASE TABLE'
- and table_name not like '%_mv'
- order by table_name
- ");
- if (!$result) echo(htmlspecialchars(mysqli_error($db)));
- $tables = array_merge(...mysqli_fetch_all($result, MYSQLI_NUM));
- echo "
";
- $found = false;
- foreach ($tables as $table) {
- $result = mysqli_execute_query($db, "SELECT column_name FROM information_schema.columns
- WHERE TABLE_SCHEMA = 'ifdb'
- and TABLE_NAME=?
- and DATA_TYPE in ('varchar', 'mediumtext', 'longtext', 'blob')
- ", [$table]);
- if (!$result) echo(htmlspecialchars(mysqli_error($db)));
- $columns = array_merge(...mysqli_fetch_all($result, MYSQLI_NUM));
- if (!$columns) continue;
- $result = mysqli_execute_query($db, "SELECT column_name FROM information_schema.columns WHERE TABLE_SCHEMA='ifdb' and TABLE_NAME=? and COLUMN_KEY='PRI'", [$table]);
- if (!$result) echo(htmlspecialchars(mysqli_error($db)));
- $primary_keys = mysqli_fetch_row($result);
-
- if ($table === 'comps_history') {
- $primary_keys = ['compid', 'pagevsn'];
- }
- else if ($table === 'extreviews') {
- $primary_keys = ['gameid', 'reviewid'];
- }
- else if ($table === 'gamelinks') {
- $primary_keys = ['gameid', 'displayorder'];
- }
- else if ($table === 'games_history') {
- $primary_keys = ['id', 'pagevsn'];
- }
- else if ($table === 'gametags') {
- $primary_keys = ['gameid', 'userid', 'moddate'];
- }
- else if ($table === 'pollvotes') {
- $primary_keys = ['pollid', 'userid', 'gameid'];
- }
- else if ($table === 'reclistitems') {
- $primary_keys = ['listid', 'gameid'];
- }
-
- $columns_to_fix = [];
- foreach ($columns as $column) {
- $result = mysqli_query($db, "SELECT count(`$column`) from `$table` where `$column` like '%%;%'");
- [$count] = mysqli_fetch_row($result);
- if ($count) $columns_to_fix[] = $column;
- }
- error_log("$table " . json_encode($columns_to_fix));
-
- if (!$columns_to_fix) continue;
- $found = true;
-
- $logging_level = 1;
- if (isset($_POST['fix'])) {
- error_log("starting $table");
- foreach ($columns_to_fix as $column) {
- error_log("starting $table $column");
- $key_columns = join(", ", array_map(function($k) {return "`$k`";}, $primary_keys));
- $sql = "SELECT `$column`, $key_columns from `$table` where `$column` like '%%;%'";
- if ($logging_level) {
- error_log($sql);
- }
- $result = mysqli_query($db, $sql);
- if (!$result) echo(htmlspecialchars(mysqli_error($db)));
- $rows = mysqli_fetch_all($result, MYSQLI_NUM);
- foreach ($rows as $row) {
- // echo "BEFORE: " . htmlspecialchars($before). "
\n";
- $before = $row[0];
- $row[0] = $after = html_entity_decode($before, ENT_HTML5, "UTF-8");
- $row[] = $before;
- if (!$row[0]) {
- echo "Failed decoding
\n";
- continue;
- }
- // echo "AFTER: " . htmlspecialchars($after). "
\n";
- $where = join(" and ", array_map(function($k) {return "`$k` = ?";}, $primary_keys));
- $sql = "UPDATE $table SET `$column` = ? WHERE $where and `$column` = ?";
- if ($logging_level) {
- error_log($sql);
- error_log(json_encode($row));
- }
- $stmt = $db->prepare($sql);
- if (!$stmt->bind_param(str_repeat('s', count($row)), ...$row)) {
- echo "error " . $stmt->error . "
\n";
- exit();
- }
- if (!$stmt->execute()) {
- echo("error " . htmlspecialchars(mysqli_error($db)));
- exit();
- }
- if (mysqli_affected_rows($db) !== 1) {
- echo "$table $column wrong number of rows: " . mysqli_affected_rows($db) . " row(s)
\n";
- echo htmlspecialchars(json_encode($row));
- exit();
- }
- }
- echo "$table $column: " . count($rows) . "
\n";
- }
- $found = false;
- } else {
- echo "- $table (".join(", ", $primary_keys).")
\n";
- foreach ($columns as $column) {
- $result = mysqli_query($db, "SELECT count(`$column`) from `$table` where `$column` like '%%;%'");
- if (!$result) echo(htmlspecialchars(mysqli_error($db)));
- [$count] = mysqli_fetch_row($result);
- echo "- $column ($count)";
- }
- echo "
\n";
- }
- }
- if ($found) {
- echo "";
- } else {
- echo "No rows left that needed fixing";
- }
- exit();
-
-} else if (isset($_REQUEST['sysinfo'])) {
-
- $phpVsn = phpversion();
-
- $result = mysql_query("select version();", $db);
- list($mysqlVsn) = mysql_fetch_row($result);
-
- echo "System information:"
- . "php version = $phpVsn"
- . "
MySQL version = $mysqlVsn";
-
- echo "
";
}
@@ -3321,8 +2164,11 @@ else if (isset($_REQUEST['deletenews'])) {
echo "
\n";
echo "$count result(s)
";
}
+} else {
+ include "adminops-components/maintenance.php";
}
+
function adjustImageName($name)
{
if (isLocalDev()
diff --git a/www/adminops-components/maintenance.php b/www/adminops-components/maintenance.php
new file mode 100644
index 00000000..452170fb
--- /dev/null
+++ b/www/adminops-components/maintenance.php
@@ -0,0 +1,787 @@
+Scanning for unreferenced images"
+ . "";
+ echo "
";
+
+
+} else if (isset($_REQUEST['reaper'])) {
+
+ $limit = (int)$_REQUEST['reaper'];
+ if ($limit < 0)
+ $limit = 30;
+
+ $result = mysql_query(
+ "select persistentsessions.id, userid, persistentsessions.lastlogin,
+ name, email,
+ to_days(now()) - to_days(persistentsessions.lastlogin)
+ from persistentsessions, users
+ where
+ persistentsessions.lastlogin <= date_sub(now(), interval $limit day)
+ and users.id = persistentsessions.userid", $db);
+
+ if (mysql_num_rows($result) == 0)
+ echo "No sessions were found that have been inactive for "
+ . "$limit day(s) or more.";
+ else {
+ echo "| User Name | Email | "
+ . "Last Login | Days Inactive |
";
+
+ for ($i = 0 ; $i < mysql_num_rows($result) ; $i++) {
+ list($sid, $uid, $login, $name, $email, $days) =
+ mysql_fetch_row($result);
+
+ $sid = mysql_real_escape_string($sid, $db);
+ $name = htmlspecialcharx($name);
+ $email = htmlspecialcharx($email);
+
+ $bg = (($i % 2) == 0) ? "evenRow" : "oddRow";
+ echo ""
+ . "| $name | "
+ . "$email | "
+ . "$login | "
+ . "$days | "
+ . "
";
+ }
+
+ echo "
";
+
+ if (isset($_REQUEST['delete'])) {
+ $result = mysql_query(
+ "delete from persistentsessions
+ where lastlogin <= date_sub(now(), interval $limit day)",
+ $db);
+
+ if ($result)
+ echo "The sessions above have been "
+ . "deleted.";
+ else
+ echo "An error occurred deleting inactive "
+ . "sessions.";
+
+ echo "Refresh the list";
+
+ } else {
+
+ echo "
"
+ . "Delete these sessions";
+
+ }
+
+ echo "
";
+ }
+
+} else if (isset($_REQUEST['fixsortkeys'])) {
+
+ $errMsg = false;
+ $rebuild = isset($_REQUEST['rebuild']);
+ $where = ($rebuild
+ ? ""
+ : "where sort_title is null or sort_title = ''
+ or sort_author is null or sort_author = ''");
+
+ $result = mysql_query(
+ "select id, title, author, sort_title, sort_author
+ from games $where", $db);
+ if (!$result)
+ $errMsg = "Query failed: " . mysql_error($db);
+
+ for ($rows = array(), $i = 0 ; $i < mysql_num_rows($result) ; $i++)
+ $rows[] = mysql_fetch_array($result, MYSQL_ASSOC);
+
+ foreach ($rows as $r) {
+ $gameid = mysql_real_escape_string($r['id'], $db);
+ $title = $r['title'];
+ $author = $r['author'];
+ $sortTitle = $r['sort_title'];
+ $sortAuthor = $r['sort_author'];
+
+ $setVars = array();
+
+ if ($rebuild || $sortTitle == "")
+ $setVars[] = "sort_title = '"
+ . mysql_real_escape_string(strtoupper(
+ getSortingTitle($title)), $db) . "'";
+
+ if ($rebuild || $sortAuthor == "")
+ $setVars[] = "sort_author = '"
+ . mysql_real_escape_string(strtoupper(
+ getSortingPersonalNameList($author)), $db) . "'";
+
+ $setVars = implode(",", $setVars);
+ $result = mysql_query(
+ "update games set $setVars where id='$gameid'", $db);
+ if (!$result) {
+ $errMsg = "Update failed: id=$gameid; " . mysql_error($db);
+ break;
+ }
+ }
+
+ echo "Fix/Rebuild GAMES table SORT keys
";
+ if ($errMsg)
+ echo "$errMsg";
+ else
+ echo "Success: " . count($rows) . " row(s) updated
+ in GAMES table";
+
+ echo "
";
+
+} else if (isset($_REQUEST['rebuildgametags'])) {
+
+ // run through the GAMES table and rebuild each TAGS field
+ $okCnt = 0;
+ $result = mysql_query("select id from games", $db);
+ for ($cnt = mysql_num_rows($result), $i = 0 ; $i < $cnt ; $i++) {
+
+ // get this game ID
+ $gameid = mysql_result($result, $i, "id");
+
+ // load its tag list
+ $tresult = mysql_query(
+ "select tag from gametags where gameid = '$gameid'", $db);
+ for ($tags = array(), $j = 0, $tcnt = mysql_num_rows($tresult) ;
+ $j < $tcnt ; $j++)
+ $tags[] = mysql_result($tresult, $j, "tag");
+
+ // turn it into a flat string list
+ if ($tcnt == 0)
+ $tags = "null";
+ else
+ $tags = "'"
+ . mysql_real_escape_string(implode(",", $tags), $db)
+ . "'";
+
+ // update the game's TAGS field
+ $uresult = mysql_query(
+ "update games set tags = $tags where id = '$gameid'", $db);
+ if ($uresult)
+ $okCnt++;
+ else
+ echo "Error updating game $gameid, tags=$tags"
+ . "
";
+ }
+
+ echo "Rows successfully updated: $okCnt
";
+
+} else if (isset($_REQUEST['rebuildgametags2'])) {
+
+ // run through GAMES and look for missing GAMETAGS entries
+ // run through the GAMES table and rebuild each TAGS field
+ $okCnt = 0;
+ $result = mysql_query(
+ "select id, title, tags from games where tags <> ''", $db);
+ for ($cnt = mysql_num_rows($result), $i = 0 ; $i < $cnt ; $i++) {
+
+ // get this game ID and tag list
+ $gameid = mysql_result($result, $i, "id");
+ $tags = explode(",", mysql_result($result, $i, "tags"));
+ $title = htmlspecialcharx(mysql_result($result, $i, "title"));
+
+ // load the corresponding GAMETAGS list
+ $tresult = mysql_query(
+ "select tag from gametags where gameid = '$gameid'", $db);
+ for ($gametags = array(), $j = 0, $tcnt = mysql_num_rows($tresult) ;
+ $j < $tcnt ; $j++)
+ $gametags[] = mysql_result($tresult, $j, "tag");
+
+ // look for missing gametags entries
+ $missingTags = array();
+ foreach ($tags as $t) {
+ if (!in_array($t, $gametags))
+ $missingTags[] = $t;
+ }
+
+ if (count($missingTags) != 0) {
+ echo "$title ($gameid): missing tags { "
+ . htmlspecialcharx(implode(",", $missingTags))
+ . " }
";
+ }
+ }
+
+ echo "
Rows successfully updated: $okCnt
";
+
+
+} else if (isset($_REQUEST['fixbafs'])) {
+
+ // query up the Baf's reviews that contain tags
+ $result = mysql_query(
+ "select
+ reviews.id as id, reviews.review as review, games.title as title
+ from
+ reviews, specialreviewers, games
+ where
+ reviews.special = specialreviewers.id
+ and specialreviewers.code = 'bafs'
+ and games.id = reviews.gameid
+ and reviews.review like '%<%'", $db);
+
+ // note if we're in APPLY mode
+ $applyMode = isset($_REQUEST['apply']);
+
+ // allowed tags - we keep these tags without modification
+ $allowedTags = valuesToKeys(
+ array('p', 'br',
+ 'i', 'b', 'u', 'strong', 'em',
+ 'big', 'small', 'tt', 'sup', 'sub',
+ 'cite', 'blockquote',
+ 'ul', 'ol', 'li', 'dl', 'dt', 'dd'), 1);
+
+ $updateCount = 0;
+ $errRows = false;
+ $allBadTags = array();
+
+ while (($row = mysql_fetch_array($result, MYSQL_ASSOC)) != false) {
+
+ // decode the row
+ $title = $row['title'];
+ $rid = $row['id'];
+ $txt = $origTxt = $row['review'];
+
+ // no unknown tags for this row yet
+ $badTags = array();
+
+ // scan it for tags we actually need to fix
+ $inAnchor = false;
+ for ($ofs = 0 ; ($ofs = strpos($txt, '<', $ofs)) !== false ; ) {
+ // remember where the tag starts
+ $tagOfs = $ofs;
+
+ // find the end of the tag
+ if (($gt = strpos($txt, '>', $ofs+1)) === false) {
+ ++$ofs;
+ continue;
+ }
+
+ // note the length of the full tag from < to >
+ $tagLen = $gt + 1 - $ofs;
+
+ // pull out the tag name
+ $tagName = trim(substr($txt, $ofs + 1, $gt - $ofs - 1));
+
+ // if it's a close tag, drop the slash
+ $isClose = false;
+ if (substr($tagName, 0, 1) == '/') {
+ $isClose = true;
+ $tagName = trim(substr($tagName, 1));
+ }
+
+ // check for auto-closing tags
+ $isAutoClose = false;
+ if (substr($tagName, -1, 1) == '/') {
+ $isAutoClose = true;
+ $tagName = trim(substr($tagName, 0, -1));
+ }
+
+ // if we have parameters, pull them out
+ $tagAttr = false;
+ $sp = strpos($tagName, ' ');
+ if ($sp !== false) {
+ $tagAttr = trim(substr($tagName, $sp + 1));
+ $tagName = substr($tagName, 0, $sp);
+ }
+
+ // canonicalize the case
+ $tagName = strtolower($tagName);
+
+ // check what we have
+ if (isset($allowedTags[$tagName])) {
+ // this one goes through unchanged - just skip it
+ $ofs = $gt + 1;
+ } else if ($tagName == 'a') {
+ // Anchor tag - check for open/close
+ if ($isClose) {
+ // close - if we're in an anchor, keep it; otherwise
+ // delete it
+ if ($inAnchor) {
+ $inAnchor = false;
+ $ofs = $gt;
+ } else {
+ $txt = substr_replace($txt, "", $tagOfs, $tagLen);
+ }
+ } else {
+ // Open anchor - check the href. If it looks like
+ // a baf's game reference, change it to an IFDB
+ // game reference. Otherwise just delete it, since
+ // we don't allow off-site references in reviews.
+ $keepA = false;
+
+ // $$$ special cases just for our initial import - these
+ // fix a couple of items that are broken in the Baf's data
+ if ($tagAttr == "href=game/1822")
+ $tagAttr = "href=game/2277";
+ else if ($tagAttr == "hre=game/1")
+ $tagAttr = "href=game/1";
+
+ if (preg_match("/^href=([\"']?)game\/([0-9]+)\\1$/i",
+ $tagAttr, $match, 0, 0)
+ || preg_match("/^href=([\"'])http:\/\/"
+ . "(?:www\.)?wurb\.com"
+ . "\/if\/game\/([0-9]+)\\1$/i",
+ $tagAttr, $match, 0, 0)) {
+
+ // it's a Baf's game reference - look up the game
+ $qbafsID = mysql_real_escape_string($match[2], $db);
+ $result2 = mysql_query(
+ "select id from games where bafsid='$qbafsID'",
+ $db);
+
+ // if we found a match, rewrite it
+ if (mysql_num_rows($result2) > 0) {
+ $keepA = true;
+ $gameID = mysql_result($result2, 0, "id");
+ $newTag = "";
+
+ $txt = substr_replace(
+ $txt, $newTag, $tagOfs, $tagLen);
+ $ofs += strlen($newTag);
+
+ $inAnchor = true;
+ }
+ } else if (preg_match("/^game=([\"'])([a-z0-9]+)\\1$/i",
+ $tagAttr, $match, 0, 0)) {
+
+ // it's already in our own format - keep it as-is
+ $keepA = true;
+ $ofs = $gt;
+ $inAnchor = true;
+ }
+
+ // if we're not keeping the tag, delete it
+ if (!$keepA) {
+ $badTags["a($tagAttr)"] = true;
+ $txt = substr_replace($txt, "", $tagOfs, $tagLen);
+ }
+ }
+ } else {
+ // it's not an allowed tag - note it and keep going
+ $badTags[$tagName] = true;
+ $txt = substr_replace($txt, "", $tagOfs, $tagLen);
+ }
+ }
+
+ // check for changes
+ if (count($badTags) != 0 || $txt != $origTxt) {
+ // count it
+ $updateCount++;
+
+ // note any bad tags
+ echo "Review ID=$rid (title=$title):
"
+ . "
";
+ if (count($badTags) != 0) {
+ echo "Bad tags found:
"
+ . implode("
", array_keys($badTags))
+ . "
";
+ }
+ echo "Updated review text:
"
+ . fixDesc($txt)
+ . "
";
+
+ foreach ($badTags as $k=>$v)
+ $allBadTags[$k] = true;
+ }
+
+ // if we're in APPLY mode, apply the changes
+ if ($applyMode) {
+ $qtxt = mysql_real_escape_string($txt, $db);
+ $result2 = mysql_query(
+ "update reviews set review='$qtxt' where id='$rid'", $db);
+
+ if (!$result2) {
+ $errRows[] = $rid;
+ echo "Error updating row ("
+ . mysql_error($db) . ")
";
+ }
+ }
+ }
+
+ if (count($allBadTags) != 0) {
+ echo "
Summary of bad tags found:
"
+ . implode("
", array_keys($allBadTags))
+ . "
";
+ }
+
+ if ($errRows) {
+ echo "
Database update errors occurred for "
+ . "the following review IDs:
";
+ foreach ($errRows as $er)
+ echo "$er
";
+ echo "
";
+ }
+
+ if ($updateCount == 0)
+ echo "No errors were found - no rows need to be updated";
+ else if (!$applyMode)
+ echo "
Apply these updates
";
+
+
+} else if (isset($_REQUEST['filters'])) {
+
+ echo "
Game Filters
";
+
+ $result = mysql_query(
+ "select
+ filterID, filterName, ckBoxName, showName, endDate,
+ filterType, explanation
+ from filters", $db);
+ echo mysql_error($db);
+ for ($i = 0 ; $i < mysql_num_rows($result) ; $i++) {
+ list($filterID, $filterName, $ckBoxName, $showName,
+ $endDate, $filterType, $explanation) = mysql_fetch_row($result);
+
+ echo "
"
+ . "Name: $filterName
"
+ . "\"Set\" checkbox label: $ckBoxName
"
+ . "\"Opt out\" checkbox label: $showName
"
+ . "\"End date: " . ($endDate ? $endDate : "None") . "
"
+ . "Filter type: " . $filterTypeMap[$filterType] . "
"
+ . "Explanation: " . $explanation . "
";
+
+ echo "
Edit"
+ . " - Delete
";
+ }
+
+ echo "
"
+ . "Add a new filter"
+ . "
";
+
+
+} else if (isset($_REQUEST['utf8entities'])) {
+ function find_columns_to_fix($db, $table, $columns) {
+ $columns_to_fix = [];
+ foreach ($columns as $column) {
+ $result = mysqli_query($db, "SELECT count(`$column`) from `$table` where `$column` like '%%;%'");
+ [$count] = mysqli_fetch_row($result);
+ if ($count) $columns_to_fix[] = $column;
+ }
+ error_log("$table " . json_encode($columns_to_fix));
+ return $columns_to_fix;
+ }
+
+ $result = mysqli_query($db, "SELECT table_name FROM information_schema.tables
+ WHERE TABLE_SCHEMA = 'ifdb'
+ and TABLE_TYPE='BASE TABLE'
+ and table_name not like '%_mv'
+ order by table_name
+ ");
+ if (!$result) echo(htmlspecialchars(mysqli_error($db)));
+ $tables = array_merge(...mysqli_fetch_all($result, MYSQLI_NUM));
+ echo "
";
+ $found = false;
+ foreach ($tables as $table) {
+ $result = mysqli_execute_query($db, "SELECT column_name FROM information_schema.columns
+ WHERE TABLE_SCHEMA = 'ifdb'
+ and TABLE_NAME=?
+ and DATA_TYPE in ('varchar', 'mediumtext', 'longtext', 'blob')
+ ", [$table]);
+ if (!$result) echo(htmlspecialchars(mysqli_error($db)));
+ $columns = array_merge(...mysqli_fetch_all($result, MYSQLI_NUM));
+ if (!$columns) continue;
+ $result = mysqli_execute_query($db, "SELECT column_name FROM information_schema.columns WHERE TABLE_SCHEMA='ifdb' and TABLE_NAME=? and COLUMN_KEY='PRI'", [$table]);
+ if (!$result) echo(htmlspecialchars(mysqli_error($db)));
+ $primary_keys = mysqli_fetch_row($result);
+
+ if ($table === 'comps_history') {
+ $primary_keys = ['compid', 'pagevsn'];
+ }
+ else if ($table === 'extreviews') {
+ $primary_keys = ['gameid', 'reviewid'];
+ }
+ else if ($table === 'gamelinks') {
+ $primary_keys = ['gameid', 'displayorder'];
+ }
+ else if ($table === 'games_history') {
+ $primary_keys = ['id', 'pagevsn'];
+ }
+ else if ($table === 'gametags') {
+ $primary_keys = ['gameid', 'userid', 'moddate'];
+ }
+ else if ($table === 'pollvotes') {
+ $primary_keys = ['pollid', 'userid', 'gameid'];
+ }
+ else if ($table === 'reclistitems') {
+ $primary_keys = ['listid', 'gameid'];
+ }
+
+ $columns_to_fix = [];
+ foreach ($columns as $column) {
+ $result = mysqli_query($db, "SELECT count(`$column`) from `$table` where `$column` like '%%;%'");
+ [$count] = mysqli_fetch_row($result);
+ if ($count) $columns_to_fix[] = $column;
+ }
+ error_log("$table " . json_encode($columns_to_fix));
+
+ if (!$columns_to_fix) continue;
+ $found = true;
+
+ $logging_level = 1;
+ if (isset($_POST['fix'])) {
+ error_log("starting $table");
+ foreach ($columns_to_fix as $column) {
+ error_log("starting $table $column");
+ $key_columns = join(", ", array_map(function($k) {return "`$k`";}, $primary_keys));
+ $sql = "SELECT `$column`, $key_columns from `$table` where `$column` like '%%;%'";
+ if ($logging_level) {
+ error_log($sql);
+ }
+ $result = mysqli_query($db, $sql);
+ if (!$result) echo(htmlspecialchars(mysqli_error($db)));
+ $rows = mysqli_fetch_all($result, MYSQLI_NUM);
+ foreach ($rows as $row) {
+ // echo "BEFORE: " . htmlspecialchars($before). "
\n";
+ $before = $row[0];
+ $row[0] = $after = html_entity_decode($before, ENT_HTML5, "UTF-8");
+ $row[] = $before;
+ if (!$row[0]) {
+ echo "Failed decoding
\n";
+ continue;
+ }
+ // echo "AFTER: " . htmlspecialchars($after). "
\n";
+ $where = join(" and ", array_map(function($k) {return "`$k` = ?";}, $primary_keys));
+ $sql = "UPDATE $table SET `$column` = ? WHERE $where and `$column` = ?";
+ if ($logging_level) {
+ error_log($sql);
+ error_log(json_encode($row));
+ }
+ $stmt = $db->prepare($sql);
+ if (!$stmt->bind_param(str_repeat('s', count($row)), ...$row)) {
+ echo "error " . $stmt->error . "
\n";
+ exit();
+ }
+ if (!$stmt->execute()) {
+ echo("error " . htmlspecialchars(mysqli_error($db)));
+ exit();
+ }
+ if (mysqli_affected_rows($db) !== 1) {
+ echo "$table $column wrong number of rows: " . mysqli_affected_rows($db) . " row(s)
\n";
+ echo htmlspecialchars(json_encode($row));
+ exit();
+ }
+ }
+ echo "$table $column: " . count($rows) . "
\n";
+ }
+ $found = false;
+ } else {
+ echo "- $table (".join(", ", $primary_keys).")
\n";
+ foreach ($columns as $column) {
+ $result = mysqli_query($db, "SELECT count(`$column`) from `$table` where `$column` like '%%;%'");
+ if (!$result) echo(htmlspecialchars(mysqli_error($db)));
+ [$count] = mysqli_fetch_row($result);
+ echo "- $column ($count)";
+ }
+ echo "
\n";
+ }
+ }
+ if ($found) {
+ echo "";
+ } else {
+ echo "No rows left that needed fixing";
+ }
+ exit();
+
+
+
+} else if (isset($_REQUEST['sysinfo'])) {
+
+ $phpVsn = phpversion();
+
+ $result = mysql_query("select version();", $db);
+ list($mysqlVsn) = mysql_fetch_row($result);
+
+ echo "System information:"
+ . "php version = $phpVsn"
+ . "
MySQL version = $mysqlVsn";
+
+ echo "
";
+
+}
+
+?>
\ No newline at end of file
diff --git a/www/adminops-components/recent-activity.php b/www/adminops-components/recent-activity.php
new file mode 100644
index 00000000..7511178d
--- /dev/null
+++ b/www/adminops-components/recent-activity.php
@@ -0,0 +1,391 @@
+Recent activity by all users';
+ echo "
Showing activity from the past $recent_days days. For a different number of days, please edit the URL.
";
+ // Horizontal menu to jump to different types of activity
+ echo '';
+ echo 'Ratings and reviews | ';
+ echo 'Review votes | ';
+ echo 'Page edits | ';
+ echo 'Tags | ';
+ echo 'Poll votes';
+ echo '
';
+
+
+ // Find recent ratings and reviews
+ $result = mysqli_execute_query($db,
+ 'SELECT
+ reviews.moddate AS reviewdatetime,
+ CASE WHEN reviews.createdate = reviews.moddate
+ THEN "added"
+ ELSE "edited"
+ END AS action,
+ DATE_FORMAT(reviews.moddate, "%M %e, %Y") AS reviewdate,
+ reviews.userid AS reviewerid,
+ reviews.gameid,
+ reviews.rating,
+ reviews.review,
+ reviews.id AS reviewid,
+ CASE WHEN reviews.special = 4
+ THEN "external "
+ ELSE ""
+ END AS externalreview,
+ games.title AS gametitle,
+ games.author AS gameauthor,
+ users.name AS reviewername
+ FROM reviews
+ LEFT JOIN games
+ ON reviews.gameid = games.id
+ LEFT JOIN users
+ ON reviews.userid = users.id
+ WHERE (reviews.moddate) > DATE_SUB(NOW(), INTERVAL ? DAY)
+ ORDER BY reviews.moddate DESC', [$recent_days]);
+
+
+ // Display recent ratings and reviews
+ echo "Recent ratings and reviews:
";
+ if (mysqli_num_rows($result) > 0) {
+ $rows = mysqli_fetch_all($result, MYSQLI_ASSOC);
+ $date_heading = "";
+ foreach ($rows as $r) {
+ $review_date = $r['reviewdate'];
+ $reviewer_id = $r['reviewerid'];
+ $reviewer_name = $r['reviewername'];
+ $external_review = $r['externalreview'];
+ $action = $r['action'];
+ $rating = "";
+ if ($r['rating']) {
+ $rating = $r['rating'];
+ } else {
+ $rating = "no";
+ }
+ $review_id = $r['reviewid'];
+ $rating_or_review = "";
+ if ($r['review'] != "") {
+ $rating_or_review = "review";
+ } else {
+ $rating_or_review = "rating";
+ }
+ $game_id = $r['gameid'];
+ $game_title = shortenString($r['gametitle']);
+ $game_author = shortenString($r['gameauthor']);
+
+ // If the current rating/review has a different
+ // date than the last rating/review we printed,
+ // display a heading showing the new date
+ if ($review_date != $date_heading) {
+ if ($date_heading != "") {
+ echo "
";
+ }
+ $date_heading = $review_date;
+ echo "$date_heading
";
+ echo "";
+ }
+ // Print a little report about this rating/review
+ if ($reviewer_name) {
+ echo "- $reviewer_name ";
+ } else {
+ echo "
- Someone "; // External reviews won't have a reviewer name or a regular reviewer id
+ }
+ if ($action == "added") {
+ echo "added ";
+ } else if ($action == "edited") {
+ echo "edited a rating or review, now ";
+ }
+ echo "a {$rating}-star {$external_review}{$rating_or_review} ";
+ echo "of $game_title by $game_author.
";
+ }
+ echo "
";
+ } else {
+ echo "No ratings or reviews in the past $recent_days days.
";
+ }
+ echo 'Return to top
';
+
+
+ // Find recent review helpfulness votes
+ $result = mysqli_execute_query($db,
+ 'SELECT
+ reviewvotes.createdate AS votedatetime,
+ DATE_FORMAT(reviewvotes.createdate, "%M %e, %Y") AS votedate,
+ reviewvotes.userid as voterid,
+ reviewvotes.vote,
+ reviewvotes.reviewid,
+ reviews.gameid,
+ reviews.userid as reviewerid,
+ users.name AS reviewername
+ FROM reviewvotes
+ LEFT JOIN reviews
+ ON reviewvotes.reviewid = reviews.id
+ LEFT JOIN users
+ ON reviews.userid = users.id
+ WHERE (reviewvotes.createdate) > DATE_SUB(NOW(), INTERVAL ? DAY)
+ ORDER BY reviewvotes.createdate DESC LIMIT 100', [$recent_days]);
+
+
+ // Display recent review helpfulness votes
+ echo 'Recent votes on review helpfulness:
';
+ if (mysqli_num_rows($result) > 0) {
+ $rows = mysqli_fetch_all($result, MYSQLI_ASSOC);
+ $date_heading = "";
+ foreach ($rows as $r) {
+ $vote_date = $r['votedate'];
+ $voter_id = $r['voterid'];
+ $vote = "";
+ if ($r['vote'] == "Y") {
+ $vote = "Yes";
+ } else if ($r['vote'] == "N") {
+ $vote = "No";
+ };
+ $review_id = $r['reviewid'];
+ $game_id = $r['gameid'];
+ $reviewer_id = $r['reviewerid'];
+ $reviewer_name = shortenString($r['reviewername']);
+
+ // If the current vote has a different
+ // date than the last vote we printed,
+ // display a heading showing the new date
+ if ($vote_date != $date_heading) {
+ if ($date_heading != "") {
+ echo "";
+ }
+ $date_heading = $vote_date;
+ echo "$date_heading
";
+ echo "";
+ }
+ // Print a little report about this review vote
+ echo "- User $voter_id ";
+ echo 'voted "' . $vote . '" on a ';
+ echo "review ";
+ echo "by $reviewer_name.
";
+ }
+ echo "
";
+ } else {
+ echo "No votes on review helpfulness in the past $recent_days days.
";
+ }
+ echo 'Return to top
';
+
+
+ // Find recent page edits
+ $result = mysqli_execute_query($db,
+ 'SELECT
+ games_history.moddate AS editdatetime,
+ DATE_FORMAT(games_history.moddate, "%M %e, %Y") AS editdate,
+ games_history.id as gameid,
+ games_history.editedby as editorid,
+ games.title AS gametitle,
+ games.author AS gameauthor,
+ users.name AS editorname
+ FROM games_history
+ LEFT JOIN games
+ ON games_history.id = games.id
+ LEFT JOIN users
+ ON games_history.editedby = users.id
+ WHERE (games_history.moddate) > DATE_SUB(NOW(), INTERVAL ? DAY)
+ ORDER BY games_history.moddate DESC', [$recent_days]);
+
+
+ // Display recent page edits
+ echo "Recent page edits:
";
+ if (mysqli_num_rows($result) > 0) {
+ $rows = mysqli_fetch_all($result, MYSQLI_ASSOC);
+ $date_heading = "";
+ foreach ($rows as $r) {
+ $edit_date = $r['editdate'];
+ $editor_id = $r['editorid'];
+ $editor_name = $r['editorname'];
+ $game_id = $r['gameid'];
+ $game_title = shortenString($r['gametitle']);
+ $game_author = shortenString($r['gameauthor']);
+
+ // If this page edit has a different date
+ // than the last page edit we printed,
+ // display a heading showing the new date
+ if ($edit_date != $date_heading) {
+ if ($date_heading != "") {
+ echo "";
+ }
+ $date_heading = $edit_date;
+ echo "$date_heading
";
+ echo "";
+ }
+ // Print a little report about this page edit
+ echo "- $editor_name ";
+ echo "edited the page for ";
+ echo "$game_title ";
+ echo "by $game_author.
";
+ }
+ echo "
";
+ } else {
+ echo "No page edits in the past $recent_days days.
";
+ }
+ echo 'Return to top
';
+
+
+ // Find recent tagging activity
+ $result = mysqli_execute_query($db,
+ 'SELECT
+ gametags.moddate AS tagdatetime,
+ DATE_FORMAT(gametags.moddate, "%M %e, %Y") AS tagdate,
+ gametags.gameid,
+ gametags.userid as taggerid,
+ gametags.tag,
+ games.title AS gametitle,
+ games.author AS gameauthor
+ FROM gametags
+ LEFT JOIN games
+ ON gametags.gameid = games.id
+ WHERE (gametags.moddate) > DATE_SUB(NOW(), INTERVAL ? DAY)
+ ORDER BY gametags.moddate DESC', [$recent_days]);
+
+
+ // Display recent tagging activity
+ echo "";
+ if (mysqli_num_rows($result) > 0) {
+ $rows = mysqli_fetch_all($result, MYSQLI_ASSOC);
+ $date_heading = "";
+ foreach ($rows as $r) {
+ $tag_date = $r['tagdate'];
+ $tagger_id = $r['taggerid'];
+ $tag = $r['tag'];
+ $game_id = $r['gameid'];
+ $game_title = shortenString($r['gametitle']);
+ $game_author = shortenString($r['gameauthor']);
+
+ // If this tagging action has a different date
+ // than the last tagging action we printed,
+ // display a heading showing the new date
+ if ($tag_date != $date_heading) {
+ if ($date_heading != "") {
+ echo "";
+ }
+ $date_heading = $tag_date;
+ echo "$date_heading
";
+ echo "";
+ }
+ // Print a little report about this tagging action
+ echo "- User $tagger_id ";
+ echo 'added the tag "' . $tag . '" to ';
+ echo "$game_title ";
+ echo "by $game_author.
";
+ }
+ echo "
";
+ } else {
+ echo "No tagging activity in the past $recent_days days.
";
+ }
+ echo 'Return to top
';
+
+
+ // Find recent poll votes
+ $result = mysqli_execute_query($db,
+ 'SELECT
+ pollvotes.votedate AS votedatetime,
+ DATE_FORMAT(pollvotes.votedate, "%M %e, %Y") AS votedate,
+ pollvotes.userid as voterid,
+ pollvotes.gameid,
+ pollvotes.quickquote,
+ pollvotes.notes,
+ pollvotes.pollid,
+ games.title AS gametitle,
+ games.author AS gameauthor,
+ users.name AS votername,
+ polls.title AS polltitle,
+ CASE WHEN polls.flags = 1
+ THEN true
+ ELSE false
+ END AS voteisanonymous
+ FROM pollvotes
+ LEFT JOIN games
+ ON pollvotes.gameid = games.id
+ LEFT JOIN users
+ ON pollvotes.userid = users.id
+ LEFT JOIN polls
+ on pollvotes.pollid = polls.pollid
+ WHERE (pollvotes.votedate) > DATE_SUB(NOW(), INTERVAL ? DAY)
+ ORDER BY pollvotes.votedate DESC', [$recent_days]);
+
+ // Display recent poll votes
+ echo "Recent poll votes:
";
+ if (mysqli_num_rows($result) > 0) {
+ $rows = mysqli_fetch_all($result, MYSQLI_ASSOC);
+ $date_heading = "";
+ foreach ($rows as $r) {
+ $vote_date = $r['votedate'];
+ $voter_id = $r['voterid'];
+ $voter_name = $r['votername'];
+ $quick_quote = $r['quickquote'];
+ $notes = $r['notes'];
+ $game_id = $r['gameid'];
+ $game_title = shortenString($r['gametitle']);
+ $game_author = shortenString($r['gameauthor']);
+ $poll_id = $r['pollid'];
+ $poll_title = shortenString($r['polltitle']);
+ $vote_is_anonymous = ($r['voteisanonymous']);
+
+ // If this poll vote has a different date
+ // than the last poll vote we printed,
+ // display a heading showing the new date
+ if ($vote_date != $date_heading) {
+ if ($date_heading != "") {
+ echo "";
+ }
+ $date_heading = $vote_date;
+ echo "$date_heading
";
+ echo "";
+ }
+ // Print a little report about this poll vote
+ echo "- ";
+ if (!$vote_is_anonymous) {
+ echo "$voter_name";
+ } else if ($vote_is_anonymous) {
+ echo "User $voter_id";
+ }
+ echo " voted for ";
+ echo "$game_title by $game_author ";
+ echo "in the poll $poll_title.";
+ if ($quick_quote || $notes) {
+ echo ' Comment: "' ;
+ if ($quick_quote) {
+ echo $quick_quote;
+ if ($notes) {
+ echo ": $notes";
+ }
+ } else {
+ echo $notes;
+ }
+ echo '" ';
+ }
+ echo "
";
+ }
+ echo "
";
+ } else {
+ echo "No poll votes in the past $recent_days days.
";
+ }
+ echo 'Return to top
';
+ echo '
';
+ echo 'Return to the System Maintenance Panel
';
+ pageFooter();
+ exit();
+} // if (isset($_REQUEST['recentactivity']))
+
+?>
+
\ No newline at end of file