function qa_db_event_create_not_entity($userid, $questionid, $lastpostid, $updatetype, $lastuserid, $timestamp = null) { require_once QA_INCLUDE_DIR . 'qa-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); }
function qa_db_count_posts($type = null, $fromuser = null) { $wheresql = ''; if (isset($type)) { $wheresql .= ' WHERE type=' . qa_db_argument_to_mysql($type, true); } if (isset($fromuser)) { $wheresql .= (strlen($wheresql) ? ' AND' : ' WHERE') . ' userid ' . ($fromuser ? 'IS NOT' : 'IS') . ' NULL'; } return qa_db_read_one_value(qa_db_query_sub('SELECT COUNT(*) FROM ^posts' . $wheresql)); }
/** * Substitute ^, $ and # symbols in $query. ^ symbols are replaced with the table prefix set in qa-config.php. * $ and # symbols are replaced in order by the corresponding element in $arguments (if the element is an array, * it is converted recursively into comma-separated list). Each element in $arguments is escaped. * $ is replaced by the argument in quotes (even if it's a number), # only adds quotes if the argument is non-numeric. * It's important to use $ when matching a textual column since MySQL won't use indexes to compare text against numbers. */ function qa_db_apply_sub($query, $arguments) { $query = preg_replace_callback('/\\^([A-Za-z_0-9]+)/', 'qa_db_prefix_callback', $query); if (!is_array($arguments)) { return $query; } $countargs = count($arguments); $offset = 0; for ($argument = 0; $argument < $countargs; $argument++) { $stringpos = strpos($query, '$', $offset); $numberpos = strpos($query, '#', $offset); if ($stringpos === false || $numberpos !== false && $numberpos < $stringpos) { $alwaysquote = false; $position = $numberpos; } else { $alwaysquote = true; $position = $stringpos; } if (!is_numeric($position)) { qa_fatal_error('Insufficient parameters in query: ' . $query); } $value = qa_db_argument_to_mysql($arguments[$argument], $alwaysquote); $query = substr_replace($query, $value, $position, 1); $offset = $position + strlen($value); // allows inserting strings which contain #/$ character } return $query; }
function qa_db_user_updates_selectspec($userid, $forfavorites = true, $forcontent = true) { require_once QA_INCLUDE_DIR . 'qa-app-updates.php'; $selectspec = qa_db_posts_basic_selectspec($userid); $nonesql = qa_db_argument_to_mysql(QA_ENTITY_NONE, true); $selectspec['columns']['obasetype'] = 'LEFT(updateposts.type, 1)'; $selectspec['columns']['oupdatetype'] = 'fullevents.updatetype'; $selectspec['columns']['ohidden'] = "INSTR(updateposts.type, '_HIDDEN')>0"; $selectspec['columns']['opostid'] = 'fullevents.lastpostid'; $selectspec['columns']['ouserid'] = 'fullevents.lastuserid'; $selectspec['columns']['otime'] = 'UNIX_TIMESTAMP(fullevents.updated)'; $selectspec['columns']['opersonal'] = 'fullevents.entitytype=' . $nonesql; $selectspec['columns']['oparentid'] = 'updateposts.parentid'; qa_db_add_selectspec_ousers($selectspec, 'eventusers', 'eventuserpoints'); if ($forfavorites) { // life is hard $selectspec['source'] .= ' JOIN ' . "(SELECT entitytype, questionid, lastpostid, updatetype, lastuserid, updated FROM ^userevents WHERE userid=\$" . ($forcontent ? '' : " AND entitytype!=" . $nonesql) . " UNION SELECT ^sharedevents.entitytype, questionid, lastpostid, updatetype, lastuserid, updated FROM ^sharedevents JOIN ^userfavorites ON ^sharedevents.entitytype=^userfavorites.entitytype AND ^sharedevents.entityid=^userfavorites.entityid AND ^userfavorites.nouserevents=1 WHERE userid=\$) fullevents ON ^posts.postid=fullevents.questionid"; array_push($selectspec['arguments'], $userid, $userid); } else { // life is easy $selectspec['source'] .= " JOIN ^userevents AS fullevents ON ^posts.postid=fullevents.questionid AND fullevents.userid=\$ AND fullevents.entitytype=" . $nonesql; $selectspec['arguments'][] = $userid; } $selectspec['source'] .= " JOIN ^posts AS updateposts ON updateposts.postid=fullevents.lastpostid" . " AND (updateposts.type IN ('Q', 'A', 'C') OR fullevents.entitytype=" . $nonesql . ")" . " AND (^posts.selchildid=fullevents.lastpostid OR NOT fullevents.updatetype<=>\$) AND ^posts.type IN ('Q', 'Q_HIDDEN')" . (QA_FINAL_EXTERNAL_USERS ? '' : ' LEFT JOIN ^users AS eventusers ON fullevents.lastuserid=eventusers.userid') . ' LEFT JOIN ^userpoints AS eventuserpoints ON fullevents.lastuserid=eventuserpoints.userid'; $selectspec['arguments'][] = QA_UPDATE_SELECTED; unset($selectspec['arraykey']); // allow same question to be retrieved multiple times $selectspec['sortdesc'] = 'otime'; return $selectspec; }
function qa_db_categoryslugs_sql($categoryslugs) { if (!is_array($categoryslugs)) { // accept old-style string arguments for one category deep $categoryslugs = strlen($categoryslugs) ? array($categoryslugs) : array(); } $levels = count($categoryslugs); if ($levels > 0 && $levels <= QA_CATEGORY_DEPTH) { return ($levels == QA_CATEGORY_DEPTH ? 'categoryid' : 'catidpath' . $levels) . '=(SELECT categoryid FROM ^categories WHERE backpath=' . qa_db_argument_to_mysql(qa_db_slugs_to_backpath($categoryslugs), true) . ' LIMIT 1) AND '; } else { return ''; } }