From 888db089c515270fd5cd9a9bedd217110f43bc4c Mon Sep 17 00:00:00 2001 From: elij Date: Sun, 29 May 2011 14:33:37 -0700 Subject: rename *.inc files to *.inc.php and adjust imports and references Lukas: Add note to "UPGRADING". Signed-off-by: Lukas Fleischer --- web/lib/acctfuncs.inc | 847 ----------------------------------- web/lib/acctfuncs.inc.php | 847 +++++++++++++++++++++++++++++++++++ web/lib/aur.inc | 593 ------------------------- web/lib/aur.inc.php | 593 +++++++++++++++++++++++++ web/lib/aurjson.class.php | 2 +- web/lib/config.inc.php.proto | 64 +++ web/lib/config.inc.proto | 64 --- web/lib/pkgfuncs.inc | 1001 ------------------------------------------ web/lib/pkgfuncs.inc.php | 1001 ++++++++++++++++++++++++++++++++++++++++++ web/lib/stats.inc | 71 --- web/lib/stats.inc.php | 71 +++ web/lib/translator.inc | 50 --- web/lib/translator.inc.php | 50 +++ web/lib/version.inc | 3 - web/lib/version.inc.php | 3 + 15 files changed, 2630 insertions(+), 2630 deletions(-) delete mode 100644 web/lib/acctfuncs.inc create mode 100644 web/lib/acctfuncs.inc.php delete mode 100644 web/lib/aur.inc create mode 100644 web/lib/aur.inc.php create mode 100644 web/lib/config.inc.php.proto delete mode 100644 web/lib/config.inc.proto delete mode 100644 web/lib/pkgfuncs.inc create mode 100644 web/lib/pkgfuncs.inc.php delete mode 100644 web/lib/stats.inc create mode 100644 web/lib/stats.inc.php delete mode 100644 web/lib/translator.inc create mode 100644 web/lib/translator.inc.php delete mode 100644 web/lib/version.inc create mode 100644 web/lib/version.inc.php (limited to 'web/lib') diff --git a/web/lib/acctfuncs.inc b/web/lib/acctfuncs.inc deleted file mode 100644 index b2f0548..0000000 --- a/web/lib/acctfuncs.inc +++ /dev/null @@ -1,847 +0,0 @@ -\n"; - print "
"; - print "\n"; - if ($UID) { - print "\n"; - } - print "
"; - print "\n"; - print "\n"; - - print ""; - print ""; - print ""; - print "\n"; - - # Only TUs or Devs can promote/demote/suspend a user - if ($UTYPE == "Trusted User" || $UTYPE == "Developer") { - print ""; - print ""; - print ""; - print "\n"; - - print ""; - print ""; - print "\n"; - } - - print ""; - print ""; - print ""; - print "\n"; - - print ""; - print ""; - print "\n"; - - print ""; - print ""; - print "\n"; - - print ""; - print ""; - print ""; - print "\n"; - - print ""; - print ""; - print ""; - print "\n"; - - print ""; - print ""; - print ""; - print "\n"; - - print "\n"; - print ""; - print ""; - print ""; - print "\n"; - - print "
 
".__("Username").": (".__("required").")
".__("Account Type").":
".__("Account Suspended").":"; - } else { - print " />"; - } - print "
".__("Email Address").": (".__("required").")
".__("Password").":"; - if ($A != "UpdateAccount") { - print " (".__("required").")"; - } - print "
".__("Re-type password").":"; - if ($A != "UpdateAccount") { - print " (".__("required").")"; - } - print "
".__("Real Name").":
".__("IRC Nick").":
".__("Language").":
 
 "; - - if ($A == "UpdateAccount") { - print "   "; - } else { - print "   "; - } - print ""; - print "
\n"; - print "\n"; - return; -} # function display_account_form() - - -# process form input from a new/edit account form -# -function process_account_form($UTYPE,$TYPE,$A,$U="",$T="",$S="",$E="", - $P="",$C="",$R="",$L="",$I="",$UID=0) { - # UTYPE: The user's account type - # TYPE: either "edit" or "new" - # A: what parent "form" name to use - # U: value to display for username - # T: value to display for account type - # S: value to display for account suspended - # E: value to display for email address - # P: password value - # C: confirm password value - # R: value to display for RealName - # L: value to display for Language preference - # I: value to display for IRC nick - # N: new package notify value - # UID: database Users.ID value - - # error check and process request for a new/modified account - global $SUPPORTED_LANGS; - - if(isset($_COOKIE['AURSID'])) { - $editor_user = uid_from_sid($_COOKIE['AURSID']); - } - else { - $editor_user = null; - } - - $dbh = db_connect(); - $error = ""; - if (empty($E) || empty($U)) { - $error = __("Missing a required field."); - } - - if ($TYPE == "new") { - # they need password fields for this type of action - # - if (empty($P) || empty($C)) { - $error = __("Missing a required field."); - } - } else { - if (!$UID) { - $error = __("Missing User ID"); - } - } - - if (!$error && !valid_username($U) && !user_is_privileged($editor_user)) - $error = __("The username is invalid.") . ""; - - if (!$error && $P && $C && ($P != $C)) { - $error = __("Password fields do not match."); - } - if (!$error && $P != '' && !good_passwd($P)) - $error = __("Your password must be at least %s characters.",PASSWD_MIN_LEN); - - if (!$error && !valid_email($E)) { - $error = __("The email address is invalid."); - } - if ($UTYPE == "Trusted User" && $T == 3) { - $error = __("A Trusted User cannot assign Developer status."); - } - if (!$error && !array_key_exists($L, $SUPPORTED_LANGS)) { - $error = __("Language is not currently supported."); - } - if (!$error) { - # check to see if this username is available - # NOTE: a race condition exists here if we care... - # - $q = "SELECT COUNT(*) AS CNT FROM Users "; - $q.= "WHERE Username = '".mysql_real_escape_string($U)."'"; - if ($TYPE == "edit") { - $q.= " AND ID != ".intval($UID); - } - $result = db_query($q, $dbh); - if ($result) { - $row = mysql_fetch_array($result); - if ($row[0]) { - $error = __("The username, %h%s%h, is already in use.", - "", htmlspecialchars($U,ENT_QUOTES), ""); - } - } - } - if (!$error) { - # check to see if this email address is available - # NOTE: a race condition exists here if we care... - # - $q = "SELECT COUNT(*) AS CNT FROM Users "; - $q.= "WHERE Email = '".mysql_real_escape_string($E)."'"; - if ($TYPE == "edit") { - $q.= " AND ID != ".intval($UID); - } - $result = db_query($q, $dbh); - if ($result) { - $row = mysql_fetch_array($result); - if ($row[0]) { - $error = __("The address, %h%s%h, is already in use.", - "", htmlspecialchars($E,ENT_QUOTES), ""); - } - } - } - if ($error) { - print "".$error."
\n"; - display_account_form($UTYPE, $A, $U, $T, $S, $E, "", "", - $R, $L, $I, $UID); - } else { - if ($TYPE == "new") { - # no errors, go ahead and create the unprivileged user - $salt = generate_salt(); - $P = salted_hash($P, $salt); - $escaped = array_map('mysql_real_escape_string', - array($U, $E, $P, $salt, $R, $L, $I)); - $q = "INSERT INTO Users (" . - "AccountTypeID, Suspended, Username, Email, Passwd, Salt" . - ", RealName, LangPreference, IRCNick) " . - "VALUES (1, 0, '" . implode("', '", $escaped) . "')"; - $result = db_query($q, $dbh); - if (!$result) { - print __("Error trying to create account, %h%s%h: %s.", - "", htmlspecialchars($U,ENT_QUOTES), "", mysql_error($dbh)); - } else { - # account created/modified, tell them so. - # - print __("The account, %h%s%h, has been successfully created.", - "", htmlspecialchars($U,ENT_QUOTES), ""); - print "

\n"; - print __("Click on the Home link above to login."); - print "

\n"; - } - - } else { - # no errors, go ahead and modify the user account - - $q = "UPDATE Users SET "; - $q.= "Username = '".mysql_real_escape_string($U)."'"; - if ($T) { - $q.= ", AccountTypeID = ".intval($T); - } - if ($S) { - $q.= ", Suspended = 1"; - } else { - $q.= ", Suspended = 0"; - } - $q.= ", Email = '".mysql_real_escape_string($E)."'"; - if ($P) { - $salt = generate_salt(); - $hash = salted_hash($P, $salt); - $q .= ", Passwd = '$hash', Salt = '$salt'"; - } - $q.= ", RealName = '".mysql_real_escape_string($R)."'"; - $q.= ", LangPreference = '".mysql_real_escape_string($L)."'"; - $q.= ", IRCNick = '".mysql_real_escape_string($I)."'"; - $q.= " WHERE ID = ".intval($UID); - $result = db_query($q, $dbh); - if (!$result) { - print __("Error trying to modify account, %h%s%h: %s.", - "", htmlspecialchars($U,ENT_QUOTES), "", mysql_error($dbh)); - } else { - print __("The account, %h%s%h, has been successfully modified.", - "", htmlspecialchars($U,ENT_QUOTES), ""); - } - } - } - return; -} - -# search existing accounts -# -function search_accounts_form() { - include("search_accounts_form.php"); - return; -} - - -# search results page -# -function search_results_page($UTYPE,$O=0,$SB="",$U="",$T="", - $S="",$E="",$R="",$I="") { - # UTYPE: what account type the user belongs to - # O: what row offset we're at - # SB: how to sort the results - # U: value to display for username - # T: value to display for account type - # S: value to display for account suspended - # E: value to display for email address - # R: value to display for RealName - # I: value to display for IRC nick - - $HITS_PER_PAGE = 50; - if ($O) { - $OFFSET = intval($O); - } else { - $OFFSET = 0; - } - if ($OFFSET < 0) { - $OFFSET = 0; - } - $search_vars = array(); - - $q = "SELECT Users.*, AccountTypes.AccountType "; - $q.= "FROM Users, AccountTypes "; - $q.= "WHERE AccountTypes.ID = Users.AccountTypeID "; - if ($T == "u") { - $q.= "AND AccountTypes.ID = 1 "; - $search_vars[] = "T"; - } elseif ($T == "t") { - $q.= "AND AccountTypes.ID = 2 "; - $search_vars[] = "T"; - } elseif ($T == "d") { - $q.= "AND AccountTypes.ID = 3 "; - $search_vars[] = "T"; - } - if ($S) { - $q.= "AND Users.Suspended = 1 "; - $search_vars[] = "S"; - } - if ($U) { - $q.= "AND Username LIKE '%".mysql_real_escape_string($U)."%' "; - $search_vars[] = "U"; - } - if ($E) { - $q.= "AND Email LIKE '%".mysql_real_escape_string($E)."%' "; - $search_vars[] = "E"; - } - if ($R) { - $q.= "AND RealName LIKE '%".mysql_real_escape_string($R)."%' "; - $search_vars[] = "R"; - } - if ($I) { - $q.= "AND IRCNick LIKE '%".mysql_real_escape_string($I)."%' "; - $search_vars[] = "I"; - } - switch ($SB) { - case 't': - $q.= "ORDER BY AccountTypeID, Username "; - break; - case 'r': - $q.= "ORDER BY RealName, AccountTypeID "; - break; - case 'i': - $q.= "ORDER BY IRCNick, AccountTypeID "; - break; - case 'v': - $q.= "ORDER BY LastVoted, Username "; - break; - default: - $q.= "ORDER BY Username, AccountTypeID "; - break; - } - $search_vars[] = "SB"; - $q.= "LIMIT " . $HITS_PER_PAGE . " OFFSET " . $OFFSET; - - $dbh = db_connect(); - - $result = db_query($q, $dbh); - if (!$result) { - print __("No results matched your search criteria."); - } else { - $num_rows = mysql_num_rows($result); - if ($num_rows) { - print "\n"; - print ""; - print "\n"; - - print ""; - print ""; - print ""; - print "\n"; - print "
"; - print "\n"; - print ""; - print ""; - print ""; - print ""; - print ""; - print ""; - print ""; - print ""; - print "\n"; - $i = 0; - while ($row = mysql_fetch_assoc($result)) { - if ($i % 2) { - $c = "data1"; - } else { - $c = "data2"; - } - print ""; - print ""; - print ""; - print ""; - print ""; - print ""; - print ""; - print ""; - } else { - $edit_url = "account.php?Action=DisplayAccount&ID=".$row["ID"]; - print ""; - print "Edit"; - } - print "\n"; - $i++; - } - print "
"; - print "".__("Username").""; - print "".__("Type").""; - print "".__("Status").""; - print "".__("Real Name").""; - print "".__("IRC Nick").""; - print "".__("Last Voted").""; - print "".__("Edit Account")."
"; - print "".$row["Username"].""; - print "".$row["AccountType"]; - print ""; - if ($row["Suspended"]) { - print __("Suspended"); - } else { - print __("Active"); - } - print ""; - $row["RealName"] ? print htmlspecialchars($row["RealName"],ENT_QUOTES) : print " "; - print ""; - $row["IRCNick"] ? print htmlspecialchars($row["IRCNick"],ENT_QUOTES) : print " "; - print ""; - $row["LastVoted"] - ? print date("Ymd", $row["LastVoted"]) - : print __("Never"); - print ""; - if ($UTYPE == "Trusted User" && $row["AccountType"] == "Developer") { - # TUs can't edit devs - # - print " 
\n"; - print "
"; - print "
\n"; - print "
"; - print "\n"; - print "\n"; - reset($search_vars); - while (list($k, $ind) = each($search_vars)) { - print "\n"; - } - print ""; - print "
"; - print "
\n"; - print "
"; - print "
\n"; - print "
"; - print "\n"; - print "\n"; - reset($search_vars); - while (list($k, $ind) = each($search_vars)) { - print "\n"; - } - print ""; - print "
"; - print "
\n"; - print "
\n"; - } else { - print "

\n"; - print __("No more results to display."); - print "

\n"; - } - } - return; -} - -# Display non-editable account info -# -function display_account_info($U="", $T="", $E="", $R="", $I="") { - # U: value to display for username - # T: value to display for account type - # E: value to display for email address - # R: value to display for RealName - # I: value to display for IRC nick - - global $SUPPORTED_LANGS; - - print "\n"; - print " \n"; - print " \n"; - print " \n"; - - print " \n"; - print " \n"; - print " \n"; - print " \n"; - - print " \n"; - print " \n"; - print " \n"; - print " \n"; - - print " \n"; - print " \n"; - print " \n"; - print " \n"; - - print " \n"; - print " \n"; - print " \n"; - print " \n"; - - print " \n"; - print " \n"; - print " \n"; - print " \n"; - - print " \n"; - print " \n"; - print " \n"; - - print "
 
".__("Username").":".$U."
".__("Account Type").":"; - if ($T == "User") { - print __("User"); - } elseif ($T == "Trusted User") { - print __("Trusted User"); - } elseif ($T == "Developer") { - print __("Developer"); - } - print "
".__("Email Address").":".htmlspecialchars($E,ENT_QUOTES)."
".__("Real Name").":".htmlspecialchars($R,ENT_QUOTES)."
".__("IRC Nick").":".htmlspecialchars($I,ENT_QUOTES)."
".__("View this user's packages")."
\n"; - return; -} - -/* - * Returns SID (Session ID) and error (error message) in an array - * SID of 0 means login failed. - */ -function try_login() { - global $MAX_SESSIONS_PER_USER, $PERSISTENT_COOKIE_TIMEOUT; - - $login_error = ""; - $new_sid = ""; - $userID = null; - - if ( isset($_REQUEST['user']) || isset($_REQUEST['passwd']) ) { - - $userID = valid_user($_REQUEST['user']); - - if ( user_suspended( $userID ) ) { - $login_error = "Account Suspended."; - } - elseif ( $userID && isset($_REQUEST['passwd']) - && valid_passwd($userID, $_REQUEST['passwd']) ) { - - $logged_in = 0; - $num_tries = 0; - - # Account looks good. Generate a SID and store it. - - $dbh = db_connect(); - while (!$logged_in && $num_tries < 5) { - if ($MAX_SESSIONS_PER_USER) { - # Delete all user sessions except the - # last ($MAX_SESSIONS_PER_USER - 1). - $q = "DELETE s.* FROM Sessions s "; - $q.= "LEFT JOIN (SELECT SessionID FROM Sessions "; - $q.= "WHERE UsersId = " . $userID . " "; - $q.= "ORDER BY LastUpdateTS DESC "; - $q.= "LIMIT " . ($MAX_SESSIONS_PER_USER - 1) . ") q "; - $q.= "ON s.SessionID = q.SessionID "; - $q.= "WHERE s.UsersId = " . $userID . " "; - $q.= "AND q.SessionID IS NULL;"; - db_query($q, $dbh); - } - - $new_sid = new_sid(); - $q = "INSERT INTO Sessions (UsersID, SessionID, LastUpdateTS)" - ." VALUES (" . $userID . ", '" . $new_sid . "', UNIX_TIMESTAMP())"; - $result = db_query($q, $dbh); - - # Query will fail if $new_sid is not unique - if ($result) { - $logged_in = 1; - break; - } - - $num_tries++; - } - - if ($logged_in) { - # set our SID cookie - - if (isset($_POST['remember_me']) && - $_POST['remember_me'] == "on") { - # Set cookies for 30 days. - $cookie_time = time() + $PERSISTENT_COOKIE_TIMEOUT; - - # Set session for 30 days. - $q = "UPDATE Sessions SET LastUpdateTS = $cookie_time "; - $q.= "WHERE SessionID = '$new_sid'"; - db_query($q, $dbh); - } - else - $cookie_time = 0; - - setcookie("AURSID", $new_sid, $cookie_time, "/"); - header("Location: " . $_SERVER['PHP_SELF'].'?'.$_SERVER['QUERY_STRING']); - $login_error = ""; - - } - else { - $login_error = "Error trying to generate session id."; - } - } - else { - $login_error = __("Bad username or password."); - } - } - return array('SID' => $new_sid, 'error' => $login_error); -} - -/* - * Only checks if the name itself is valid - * Longer or equal to USERNAME_MIN_LEN - * Shorter or equal to USERNAME_MAX_LEN - * Starts and ends with a letter or number - * Contains at most ONE dot, hyphen, or underscore - * Returns the username if it is valid - * Returns nothing if it isn't valid - */ -function valid_username( $user ) -{ - if (!empty($user)) { - - #Is username at not too short or too long? - if ( strlen($user) >= USERNAME_MIN_LEN && - strlen($user) <= USERNAME_MAX_LEN ) { - - $user = strtolower($user); - # Does username: - # start and end with a letter or number - # contain only letters and numbers, - # and at most has one dash, period, or underscore - if ( preg_match("/^[a-z0-9]+[.\-_]?[a-z0-9]+$/", $user) ) { - #All is good return the username - return $user; - } - } - } - - return; -} - -/* - * Checks if the username is valid and if it exists in the database - * Returns the username ID or nothing - */ -function valid_user( $user ) -{ - /* if ( $user = valid_username($user) ) { */ - if ( $user ) { - $dbh = db_connect(); - $q = "SELECT ID FROM Users WHERE Username = '" - . mysql_real_escape_string($user). "'"; - - $result = db_query($q, $dbh); - # Is the username in the database? - if ($result) { - $row = mysql_fetch_row($result); - return $row[0]; - } - } - return; -} - -function good_passwd( $passwd ) -{ - if ( strlen($passwd) >= PASSWD_MIN_LEN ) { - return true; - } - return false; -} - -/* Verifies that the password is correct for the userID specified. - * Returns true or false - */ -function valid_passwd( $userID, $passwd ) -{ - if ( strlen($passwd) > 0 ) { - $dbh = db_connect(); - - # get salt for this user - $salt = get_salt($userID); - if ($salt) { - # use salt - $passwd_q = "SELECT ID FROM Users" . - " WHERE ID = " . $userID . " AND Passwd = '" . - salted_hash($passwd, $salt) . "'"; - $result = db_query($passwd_q, $dbh); - if ($result) { - $passwd_result = mysql_fetch_row($result); - if ($passwd_result[0]) { - return true; - } - } - } else { - # check without salt - $nosalt_q = "SELECT ID FROM Users". - " WHERE ID = " . $userID . - " AND Passwd = '" . md5($passwd) . "'"; - $result = db_query($nosalt_q, $dbh); - if ($result) { - $nosalt_row = mysql_fetch_row($result); - if ($nosalt_row[0]) { - # password correct, but salt it first - if (!save_salt($userID, $passwd)) { - trigger_error("Unable to salt user's password;" . - " ID " . $userID, E_USER_WARNING); - return false; - } - return true; - } - } - } - } - return false; -} - -/* - * Is the user account suspended? - */ -function user_suspended( $id ) -{ - if (!$id) { - return false; - } - $dbh = db_connect(); - $q = "SELECT Suspended FROM Users WHERE ID = " . $id; - $result = db_query($q, $dbh); - if ($result) { - $row = mysql_fetch_row($result); - if ($result[0] == 1 ) { - return true; - } - } - return false; -} - -/* - * This should be expanded to return something - */ -function user_delete( $id ) -{ - $dbh = db_connect(); - $q = "DELETE FROM Users WHERE ID = " . $id; - db_query($q, $dbh); - return; -} - -/* - * A different way of determining a user's privileges - * rather than account_from_sid() - */ -function user_is_privileged( $id ) -{ - $dbh = db_connect(); - $q = "SELECT AccountTypeID FROM Users WHERE ID = " . $id; - $result = db_query($q, $dbh); - if ($result) { - $row = mysql_fetch_row($result); - if( $result[0] > 1) { - return $result[0]; - } - } - return 0; - -} - -# Clear out old expired sessions. -function clear_expired_sessions($dbh = null) { - global $LOGIN_TIMEOUT; - - if (empty($dbh)) { - $dbh = db_connect(); - } - - $q = "DELETE FROM Sessions WHERE LastUpdateTS < (UNIX_TIMESTAMP() - $LOGIN_TIMEOUT)"; - db_query($q, $dbh); - - return; -} - diff --git a/web/lib/acctfuncs.inc.php b/web/lib/acctfuncs.inc.php new file mode 100644 index 0000000..b2f0548 --- /dev/null +++ b/web/lib/acctfuncs.inc.php @@ -0,0 +1,847 @@ +\n"; + print "
"; + print "\n"; + if ($UID) { + print "\n"; + } + print "
"; + print "\n"; + print "\n"; + + print ""; + print ""; + print ""; + print "\n"; + + # Only TUs or Devs can promote/demote/suspend a user + if ($UTYPE == "Trusted User" || $UTYPE == "Developer") { + print ""; + print ""; + print ""; + print "\n"; + + print ""; + print ""; + print "\n"; + } + + print ""; + print ""; + print ""; + print "\n"; + + print ""; + print ""; + print "\n"; + + print ""; + print ""; + print "\n"; + + print ""; + print ""; + print ""; + print "\n"; + + print ""; + print ""; + print ""; + print "\n"; + + print ""; + print ""; + print ""; + print "\n"; + + print "\n"; + print ""; + print ""; + print ""; + print "\n"; + + print "
 
".__("Username").": (".__("required").")
".__("Account Type").":
".__("Account Suspended").":"; + } else { + print " />"; + } + print "
".__("Email Address").": (".__("required").")
".__("Password").":"; + if ($A != "UpdateAccount") { + print " (".__("required").")"; + } + print "
".__("Re-type password").":"; + if ($A != "UpdateAccount") { + print " (".__("required").")"; + } + print "
".__("Real Name").":
".__("IRC Nick").":
".__("Language").":
 
 "; + + if ($A == "UpdateAccount") { + print "   "; + } else { + print "   "; + } + print ""; + print "
\n"; + print "\n"; + return; +} # function display_account_form() + + +# process form input from a new/edit account form +# +function process_account_form($UTYPE,$TYPE,$A,$U="",$T="",$S="",$E="", + $P="",$C="",$R="",$L="",$I="",$UID=0) { + # UTYPE: The user's account type + # TYPE: either "edit" or "new" + # A: what parent "form" name to use + # U: value to display for username + # T: value to display for account type + # S: value to display for account suspended + # E: value to display for email address + # P: password value + # C: confirm password value + # R: value to display for RealName + # L: value to display for Language preference + # I: value to display for IRC nick + # N: new package notify value + # UID: database Users.ID value + + # error check and process request for a new/modified account + global $SUPPORTED_LANGS; + + if(isset($_COOKIE['AURSID'])) { + $editor_user = uid_from_sid($_COOKIE['AURSID']); + } + else { + $editor_user = null; + } + + $dbh = db_connect(); + $error = ""; + if (empty($E) || empty($U)) { + $error = __("Missing a required field."); + } + + if ($TYPE == "new") { + # they need password fields for this type of action + # + if (empty($P) || empty($C)) { + $error = __("Missing a required field."); + } + } else { + if (!$UID) { + $error = __("Missing User ID"); + } + } + + if (!$error && !valid_username($U) && !user_is_privileged($editor_user)) + $error = __("The username is invalid.") . ""; + + if (!$error && $P && $C && ($P != $C)) { + $error = __("Password fields do not match."); + } + if (!$error && $P != '' && !good_passwd($P)) + $error = __("Your password must be at least %s characters.",PASSWD_MIN_LEN); + + if (!$error && !valid_email($E)) { + $error = __("The email address is invalid."); + } + if ($UTYPE == "Trusted User" && $T == 3) { + $error = __("A Trusted User cannot assign Developer status."); + } + if (!$error && !array_key_exists($L, $SUPPORTED_LANGS)) { + $error = __("Language is not currently supported."); + } + if (!$error) { + # check to see if this username is available + # NOTE: a race condition exists here if we care... + # + $q = "SELECT COUNT(*) AS CNT FROM Users "; + $q.= "WHERE Username = '".mysql_real_escape_string($U)."'"; + if ($TYPE == "edit") { + $q.= " AND ID != ".intval($UID); + } + $result = db_query($q, $dbh); + if ($result) { + $row = mysql_fetch_array($result); + if ($row[0]) { + $error = __("The username, %h%s%h, is already in use.", + "", htmlspecialchars($U,ENT_QUOTES), ""); + } + } + } + if (!$error) { + # check to see if this email address is available + # NOTE: a race condition exists here if we care... + # + $q = "SELECT COUNT(*) AS CNT FROM Users "; + $q.= "WHERE Email = '".mysql_real_escape_string($E)."'"; + if ($TYPE == "edit") { + $q.= " AND ID != ".intval($UID); + } + $result = db_query($q, $dbh); + if ($result) { + $row = mysql_fetch_array($result); + if ($row[0]) { + $error = __("The address, %h%s%h, is already in use.", + "", htmlspecialchars($E,ENT_QUOTES), ""); + } + } + } + if ($error) { + print "".$error."
\n"; + display_account_form($UTYPE, $A, $U, $T, $S, $E, "", "", + $R, $L, $I, $UID); + } else { + if ($TYPE == "new") { + # no errors, go ahead and create the unprivileged user + $salt = generate_salt(); + $P = salted_hash($P, $salt); + $escaped = array_map('mysql_real_escape_string', + array($U, $E, $P, $salt, $R, $L, $I)); + $q = "INSERT INTO Users (" . + "AccountTypeID, Suspended, Username, Email, Passwd, Salt" . + ", RealName, LangPreference, IRCNick) " . + "VALUES (1, 0, '" . implode("', '", $escaped) . "')"; + $result = db_query($q, $dbh); + if (!$result) { + print __("Error trying to create account, %h%s%h: %s.", + "", htmlspecialchars($U,ENT_QUOTES), "", mysql_error($dbh)); + } else { + # account created/modified, tell them so. + # + print __("The account, %h%s%h, has been successfully created.", + "", htmlspecialchars($U,ENT_QUOTES), ""); + print "

\n"; + print __("Click on the Home link above to login."); + print "

\n"; + } + + } else { + # no errors, go ahead and modify the user account + + $q = "UPDATE Users SET "; + $q.= "Username = '".mysql_real_escape_string($U)."'"; + if ($T) { + $q.= ", AccountTypeID = ".intval($T); + } + if ($S) { + $q.= ", Suspended = 1"; + } else { + $q.= ", Suspended = 0"; + } + $q.= ", Email = '".mysql_real_escape_string($E)."'"; + if ($P) { + $salt = generate_salt(); + $hash = salted_hash($P, $salt); + $q .= ", Passwd = '$hash', Salt = '$salt'"; + } + $q.= ", RealName = '".mysql_real_escape_string($R)."'"; + $q.= ", LangPreference = '".mysql_real_escape_string($L)."'"; + $q.= ", IRCNick = '".mysql_real_escape_string($I)."'"; + $q.= " WHERE ID = ".intval($UID); + $result = db_query($q, $dbh); + if (!$result) { + print __("Error trying to modify account, %h%s%h: %s.", + "", htmlspecialchars($U,ENT_QUOTES), "", mysql_error($dbh)); + } else { + print __("The account, %h%s%h, has been successfully modified.", + "", htmlspecialchars($U,ENT_QUOTES), ""); + } + } + } + return; +} + +# search existing accounts +# +function search_accounts_form() { + include("search_accounts_form.php"); + return; +} + + +# search results page +# +function search_results_page($UTYPE,$O=0,$SB="",$U="",$T="", + $S="",$E="",$R="",$I="") { + # UTYPE: what account type the user belongs to + # O: what row offset we're at + # SB: how to sort the results + # U: value to display for username + # T: value to display for account type + # S: value to display for account suspended + # E: value to display for email address + # R: value to display for RealName + # I: value to display for IRC nick + + $HITS_PER_PAGE = 50; + if ($O) { + $OFFSET = intval($O); + } else { + $OFFSET = 0; + } + if ($OFFSET < 0) { + $OFFSET = 0; + } + $search_vars = array(); + + $q = "SELECT Users.*, AccountTypes.AccountType "; + $q.= "FROM Users, AccountTypes "; + $q.= "WHERE AccountTypes.ID = Users.AccountTypeID "; + if ($T == "u") { + $q.= "AND AccountTypes.ID = 1 "; + $search_vars[] = "T"; + } elseif ($T == "t") { + $q.= "AND AccountTypes.ID = 2 "; + $search_vars[] = "T"; + } elseif ($T == "d") { + $q.= "AND AccountTypes.ID = 3 "; + $search_vars[] = "T"; + } + if ($S) { + $q.= "AND Users.Suspended = 1 "; + $search_vars[] = "S"; + } + if ($U) { + $q.= "AND Username LIKE '%".mysql_real_escape_string($U)."%' "; + $search_vars[] = "U"; + } + if ($E) { + $q.= "AND Email LIKE '%".mysql_real_escape_string($E)."%' "; + $search_vars[] = "E"; + } + if ($R) { + $q.= "AND RealName LIKE '%".mysql_real_escape_string($R)."%' "; + $search_vars[] = "R"; + } + if ($I) { + $q.= "AND IRCNick LIKE '%".mysql_real_escape_string($I)."%' "; + $search_vars[] = "I"; + } + switch ($SB) { + case 't': + $q.= "ORDER BY AccountTypeID, Username "; + break; + case 'r': + $q.= "ORDER BY RealName, AccountTypeID "; + break; + case 'i': + $q.= "ORDER BY IRCNick, AccountTypeID "; + break; + case 'v': + $q.= "ORDER BY LastVoted, Username "; + break; + default: + $q.= "ORDER BY Username, AccountTypeID "; + break; + } + $search_vars[] = "SB"; + $q.= "LIMIT " . $HITS_PER_PAGE . " OFFSET " . $OFFSET; + + $dbh = db_connect(); + + $result = db_query($q, $dbh); + if (!$result) { + print __("No results matched your search criteria."); + } else { + $num_rows = mysql_num_rows($result); + if ($num_rows) { + print "\n"; + print ""; + print "\n"; + + print ""; + print ""; + print ""; + print "\n"; + print "
"; + print "\n"; + print ""; + print ""; + print ""; + print ""; + print ""; + print ""; + print ""; + print ""; + print "\n"; + $i = 0; + while ($row = mysql_fetch_assoc($result)) { + if ($i % 2) { + $c = "data1"; + } else { + $c = "data2"; + } + print ""; + print ""; + print ""; + print ""; + print ""; + print ""; + print ""; + print ""; + } else { + $edit_url = "account.php?Action=DisplayAccount&ID=".$row["ID"]; + print ""; + print "Edit"; + } + print "\n"; + $i++; + } + print "
"; + print "".__("Username").""; + print "".__("Type").""; + print "".__("Status").""; + print "".__("Real Name").""; + print "".__("IRC Nick").""; + print "".__("Last Voted").""; + print "".__("Edit Account")."
"; + print "".$row["Username"].""; + print "".$row["AccountType"]; + print ""; + if ($row["Suspended"]) { + print __("Suspended"); + } else { + print __("Active"); + } + print ""; + $row["RealName"] ? print htmlspecialchars($row["RealName"],ENT_QUOTES) : print " "; + print ""; + $row["IRCNick"] ? print htmlspecialchars($row["IRCNick"],ENT_QUOTES) : print " "; + print ""; + $row["LastVoted"] + ? print date("Ymd", $row["LastVoted"]) + : print __("Never"); + print ""; + if ($UTYPE == "Trusted User" && $row["AccountType"] == "Developer") { + # TUs can't edit devs + # + print " 
\n"; + print "
"; + print "
\n"; + print "
"; + print "\n"; + print "\n"; + reset($search_vars); + while (list($k, $ind) = each($search_vars)) { + print "\n"; + } + print ""; + print "
"; + print "
\n"; + print "
"; + print "
\n"; + print "
"; + print "\n"; + print "\n"; + reset($search_vars); + while (list($k, $ind) = each($search_vars)) { + print "\n"; + } + print ""; + print "
"; + print "
\n"; + print "
\n"; + } else { + print "

\n"; + print __("No more results to display."); + print "

\n"; + } + } + return; +} + +# Display non-editable account info +# +function display_account_info($U="", $T="", $E="", $R="", $I="") { + # U: value to display for username + # T: value to display for account type + # E: value to display for email address + # R: value to display for RealName + # I: value to display for IRC nick + + global $SUPPORTED_LANGS; + + print "\n"; + print " \n"; + print " \n"; + print " \n"; + + print " \n"; + print " \n"; + print " \n"; + print " \n"; + + print " \n"; + print " \n"; + print " \n"; + print " \n"; + + print " \n"; + print " \n"; + print " \n"; + print " \n"; + + print " \n"; + print " \n"; + print " \n"; + print " \n"; + + print " \n"; + print " \n"; + print " \n"; + print " \n"; + + print " \n"; + print " \n"; + print " \n"; + + print "
 
".__("Username").":".$U."
".__("Account Type").":"; + if ($T == "User") { + print __("User"); + } elseif ($T == "Trusted User") { + print __("Trusted User"); + } elseif ($T == "Developer") { + print __("Developer"); + } + print "
".__("Email Address").":".htmlspecialchars($E,ENT_QUOTES)."
".__("Real Name").":".htmlspecialchars($R,ENT_QUOTES)."
".__("IRC Nick").":".htmlspecialchars($I,ENT_QUOTES)."
".__("View this user's packages")."
\n"; + return; +} + +/* + * Returns SID (Session ID) and error (error message) in an array + * SID of 0 means login failed. + */ +function try_login() { + global $MAX_SESSIONS_PER_USER, $PERSISTENT_COOKIE_TIMEOUT; + + $login_error = ""; + $new_sid = ""; + $userID = null; + + if ( isset($_REQUEST['user']) || isset($_REQUEST['passwd']) ) { + + $userID = valid_user($_REQUEST['user']); + + if ( user_suspended( $userID ) ) { + $login_error = "Account Suspended."; + } + elseif ( $userID && isset($_REQUEST['passwd']) + && valid_passwd($userID, $_REQUEST['passwd']) ) { + + $logged_in = 0; + $num_tries = 0; + + # Account looks good. Generate a SID and store it. + + $dbh = db_connect(); + while (!$logged_in && $num_tries < 5) { + if ($MAX_SESSIONS_PER_USER) { + # Delete all user sessions except the + # last ($MAX_SESSIONS_PER_USER - 1). + $q = "DELETE s.* FROM Sessions s "; + $q.= "LEFT JOIN (SELECT SessionID FROM Sessions "; + $q.= "WHERE UsersId = " . $userID . " "; + $q.= "ORDER BY LastUpdateTS DESC "; + $q.= "LIMIT " . ($MAX_SESSIONS_PER_USER - 1) . ") q "; + $q.= "ON s.SessionID = q.SessionID "; + $q.= "WHERE s.UsersId = " . $userID . " "; + $q.= "AND q.SessionID IS NULL;"; + db_query($q, $dbh); + } + + $new_sid = new_sid(); + $q = "INSERT INTO Sessions (UsersID, SessionID, LastUpdateTS)" + ." VALUES (" . $userID . ", '" . $new_sid . "', UNIX_TIMESTAMP())"; + $result = db_query($q, $dbh); + + # Query will fail if $new_sid is not unique + if ($result) { + $logged_in = 1; + break; + } + + $num_tries++; + } + + if ($logged_in) { + # set our SID cookie + + if (isset($_POST['remember_me']) && + $_POST['remember_me'] == "on") { + # Set cookies for 30 days. + $cookie_time = time() + $PERSISTENT_COOKIE_TIMEOUT; + + # Set session for 30 days. + $q = "UPDATE Sessions SET LastUpdateTS = $cookie_time "; + $q.= "WHERE SessionID = '$new_sid'"; + db_query($q, $dbh); + } + else + $cookie_time = 0; + + setcookie("AURSID", $new_sid, $cookie_time, "/"); + header("Location: " . $_SERVER['PHP_SELF'].'?'.$_SERVER['QUERY_STRING']); + $login_error = ""; + + } + else { + $login_error = "Error trying to generate session id."; + } + } + else { + $login_error = __("Bad username or password."); + } + } + return array('SID' => $new_sid, 'error' => $login_error); +} + +/* + * Only checks if the name itself is valid + * Longer or equal to USERNAME_MIN_LEN + * Shorter or equal to USERNAME_MAX_LEN + * Starts and ends with a letter or number + * Contains at most ONE dot, hyphen, or underscore + * Returns the username if it is valid + * Returns nothing if it isn't valid + */ +function valid_username( $user ) +{ + if (!empty($user)) { + + #Is username at not too short or too long? + if ( strlen($user) >= USERNAME_MIN_LEN && + strlen($user) <= USERNAME_MAX_LEN ) { + + $user = strtolower($user); + # Does username: + # start and end with a letter or number + # contain only letters and numbers, + # and at most has one dash, period, or underscore + if ( preg_match("/^[a-z0-9]+[.\-_]?[a-z0-9]+$/", $user) ) { + #All is good return the username + return $user; + } + } + } + + return; +} + +/* + * Checks if the username is valid and if it exists in the database + * Returns the username ID or nothing + */ +function valid_user( $user ) +{ + /* if ( $user = valid_username($user) ) { */ + if ( $user ) { + $dbh = db_connect(); + $q = "SELECT ID FROM Users WHERE Username = '" + . mysql_real_escape_string($user). "'"; + + $result = db_query($q, $dbh); + # Is the username in the database? + if ($result) { + $row = mysql_fetch_row($result); + return $row[0]; + } + } + return; +} + +function good_passwd( $passwd ) +{ + if ( strlen($passwd) >= PASSWD_MIN_LEN ) { + return true; + } + return false; +} + +/* Verifies that the password is correct for the userID specified. + * Returns true or false + */ +function valid_passwd( $userID, $passwd ) +{ + if ( strlen($passwd) > 0 ) { + $dbh = db_connect(); + + # get salt for this user + $salt = get_salt($userID); + if ($salt) { + # use salt + $passwd_q = "SELECT ID FROM Users" . + " WHERE ID = " . $userID . " AND Passwd = '" . + salted_hash($passwd, $salt) . "'"; + $result = db_query($passwd_q, $dbh); + if ($result) { + $passwd_result = mysql_fetch_row($result); + if ($passwd_result[0]) { + return true; + } + } + } else { + # check without salt + $nosalt_q = "SELECT ID FROM Users". + " WHERE ID = " . $userID . + " AND Passwd = '" . md5($passwd) . "'"; + $result = db_query($nosalt_q, $dbh); + if ($result) { + $nosalt_row = mysql_fetch_row($result); + if ($nosalt_row[0]) { + # password correct, but salt it first + if (!save_salt($userID, $passwd)) { + trigger_error("Unable to salt user's password;" . + " ID " . $userID, E_USER_WARNING); + return false; + } + return true; + } + } + } + } + return false; +} + +/* + * Is the user account suspended? + */ +function user_suspended( $id ) +{ + if (!$id) { + return false; + } + $dbh = db_connect(); + $q = "SELECT Suspended FROM Users WHERE ID = " . $id; + $result = db_query($q, $dbh); + if ($result) { + $row = mysql_fetch_row($result); + if ($result[0] == 1 ) { + return true; + } + } + return false; +} + +/* + * This should be expanded to return something + */ +function user_delete( $id ) +{ + $dbh = db_connect(); + $q = "DELETE FROM Users WHERE ID = " . $id; + db_query($q, $dbh); + return; +} + +/* + * A different way of determining a user's privileges + * rather than account_from_sid() + */ +function user_is_privileged( $id ) +{ + $dbh = db_connect(); + $q = "SELECT AccountTypeID FROM Users WHERE ID = " . $id; + $result = db_query($q, $dbh); + if ($result) { + $row = mysql_fetch_row($result); + if( $result[0] > 1) { + return $result[0]; + } + } + return 0; + +} + +# Clear out old expired sessions. +function clear_expired_sessions($dbh = null) { + global $LOGIN_TIMEOUT; + + if (empty($dbh)) { + $dbh = db_connect(); + } + + $q = "DELETE FROM Sessions WHERE LastUpdateTS < (UNIX_TIMESTAMP() - $LOGIN_TIMEOUT)"; + db_query($q, $dbh); + + return; +} + diff --git a/web/lib/aur.inc b/web/lib/aur.inc deleted file mode 100644 index 1f7b71a..0000000 --- a/web/lib/aur.inc +++ /dev/null @@ -1,593 +0,0 @@ - ".mysql_error($db_handle)); - } - - return $result; -} - -# Set a value in the cache (currently APC) if cache is available for use. If -# not available, this becomes effectively a no-op (return value is -# false). Accepts an optional TTL (defaults to 600 seconds). -function set_cache_value($key, $value, $ttl=600) { - $status = false; - if (EXTENSION_LOADED_APC) { - $status = apc_store(APC_PREFIX.$key, $value, $ttl); - } - return $status; -} - -# Get a value from the cache (currently APC) if cache is available for use. If -# not available, this returns false (optionally sets passed in variable $status -# to false, much like apc_fetch() behaves). This allows for testing the fetch -# result appropriately even in the event that a 'false' value was the value in -# the cache. -function get_cache_value($key, &$status=false) { - if(EXTENSION_LOADED_APC) { - $ret = apc_fetch(APC_PREFIX.$key, $status); - if ($status) { - return $ret; - } - } - return $status; -} - -# Run a simple db query, retrieving and/or caching the value if APC is -# available for use. Accepts an optional TTL value (defaults to 600 seconds). -function db_cache_value($dbq, $dbh, $key, $ttl=600) { - $status = false; - $value = get_cache_value($key, $status); - if (!$status) { - $result = db_query($dbq, $dbh); - $row = mysql_fetch_row($result); - $value = $row[0]; - set_cache_value($key, $value, $ttl); - } - return $value; -} - -# set up the visitor's language -# -function set_lang() { - global $LANG; - global $SUPPORTED_LANGS; - global $PERSISTENT_COOKIE_TIMEOUT; - global $streamer, $l10n; - - $update_cookie = 0; - if (isset($_REQUEST['setlang'])) { - # visitor is requesting a language change - # - $LANG = $_REQUEST['setlang']; - $update_cookie = 1; - - } elseif (isset($_COOKIE['AURLANG'])) { - # If a cookie is set, use that - # - $LANG = $_COOKIE['AURLANG']; - - } elseif (isset($_COOKIE["AURSID"])) { - # No language but a session; use default lang preference - # - $dbh = db_connect(); - $q = "SELECT LangPreference FROM Users, Sessions "; - $q.= "WHERE Users.ID = Sessions.UsersID "; - $q.= "AND Sessions.SessionID = '"; - $q.= mysql_real_escape_string($_COOKIE["AURSID"])."'"; - $result = db_query($q, $dbh); - - if ($result) { - $row = mysql_fetch_array($result); - $LANG = $row[0]; - } - $update_cookie = 1; - } - - # Set $LANG to default if nothing is valid. - if (!array_key_exists($LANG, $SUPPORTED_LANGS)) { - $LANG = DEFAULT_LANG; - } - - if ($update_cookie) { - $cookie_time = time() + $PERSISTENT_COOKIE_TIMEOUT; - setcookie("AURLANG", $LANG, $cookie_time, "/"); - } - - $streamer = new FileReader('../locale/' . $LANG . - '/LC_MESSAGES/aur.mo'); - $l10n = new gettext_reader($streamer, true); - - return; -} - - -# common header -# -function html_header($title="") { - global $_SERVER; - global $_COOKIE; - global $_POST; - global $LANG; - global $SUPPORTED_LANGS; - - $login = try_login(); - $login_error = $login['error']; - - $title = htmlspecialchars($title, ENT_QUOTES); - - include('header.php'); - return; -} - - -# common footer -# -function html_footer($ver="") { - include('footer.php'); - return; -} - -# check to see if the user can submit a package -# -function can_submit_pkg($name="", $sid="") { - if (!$name || !$sid) {return 0;} - $dbh = db_connect(); - $q = "SELECT MaintainerUID "; - $q.= "FROM Packages WHERE Name = '".mysql_real_escape_string($name)."'"; - $result = db_query($q, $dbh); - if (mysql_num_rows($result) == 0) {return 1;} - $row = mysql_fetch_row($result); - $my_uid = uid_from_sid($sid); - - if ($row[0] === NULL || $row[0] == $my_uid) { - return 1; - } - - return 0; -} - -# recursive delete directory -# -function rm_tree($dirname) { - if (empty($dirname) || !is_dir($dirname)) return; - - foreach (scandir($dirname) as $item) { - if ($item != '.' && $item != '..') { - $path = $dirname . '/' . $item; - if (is_file($path) || is_link($path)) { - unlink($path); - } - else { - rm_tree($path); - } - } - } - - rmdir($dirname); - - return; -} - -# Recursive chmod to set group write permissions -# -function chmod_group($path) { - if (!is_dir($path)) - return chmod($path, 0664); - - $d = dir($path); - while ($f = $d->read()) { - if ($f != '.' && $f != '..') { - $fullpath = $path.'/'.$f; - if (is_link($fullpath)) - continue; - elseif (!is_dir($fullpath)) { - if (!chmod($fullpath, 0664)) - return FALSE; - } - elseif(!chmod_group($fullpath)) - return FALSE; - } - } - $d->close(); - - if(chmod($path, 0775)) - return TRUE; - else - return FALSE; -} - -# obtain the uid given a Users.Username -# -function uid_from_username($username="") -{ - if (!$username) { - return ""; - } - $dbh = db_connect(); - $q = "SELECT ID FROM Users WHERE Username = '".mysql_real_escape_string($username) - ."'"; - $result = db_query($q, $dbh); - if (!$result) { - return "None"; - } - $row = mysql_fetch_row($result); - - return $row[0]; -} - -# obtain the uid given a Users.Email -# -function uid_from_email($email="") -{ - if (!$email) { - return ""; - } - $dbh = db_connect(); - $q = "SELECT ID FROM Users WHERE Email = '".mysql_real_escape_string($email) - ."'"; - $result = db_query($q, $dbh); - if (!$result) { - return "None"; - } - $row = mysql_fetch_row($result); - - return $row[0]; -} - -# check user privileges -# -function check_user_privileges() -{ - $type = account_from_sid($_COOKIE['AURSID']); - return ($type == 'Trusted User' || $type == 'Developer'); -} - -/** - * Generate clean url with edited/added user values - * - * Makes a clean string of variables for use in URLs based on current $_GET and - * list of values to edit/add to that. Any empty variables are discarded. - * - * ex. print "http://example.com/test.php?" . mkurl("foo=bar&bar=baz") - * - * @param string $append string of variables and values formatted as in URLs - * ex. mkurl("foo=bar&bar=baz") - * @return string clean string of variables to append to URL, urlencoded - */ -function mkurl($append) { - $get = $_GET; - $append = explode('&', $append); - $uservars = array(); - $out = ''; - - foreach ($append as $i) { - $ex = explode('=', $i); - $uservars[$ex[0]] = $ex[1]; - } - - foreach ($uservars as $k => $v) { $get[$k] = $v; } - - foreach ($get as $k => $v) { - if ($v !== '') { - $out .= '&' . urlencode($k) . '=' . urlencode($v); - } - } - - return substr($out, 5); -} - -function get_salt($user_id) -{ - $dbh = db_connect(); - $salt_q = "SELECT Salt FROM Users WHERE ID = " . $user_id; - $result = db_query($salt_q, $dbh); - if ($result) { - $salt_row = mysql_fetch_row($result); - return $salt_row[0]; - } - return; -} - -function save_salt($user_id, $passwd) -{ - $dbh = db_connect(); - $salt = generate_salt(); - $hash = salted_hash($passwd, $salt); - $salting_q = "UPDATE Users SET Salt = '" . $salt . "', " . - "Passwd = '" . $hash . "' WHERE ID = " . $user_id; - return db_query($salting_q, $dbh); -} - -function generate_salt() -{ - return md5(uniqid(mt_rand(), true)); -} - -function salted_hash($passwd, $salt) -{ - if (strlen($salt) != 32) { - trigger_error('Salt does not look like an md5 hash', E_USER_WARNING); - } - return md5($salt . $passwd); -} - -function parse_comment($comment) -{ - $url_pattern = '/(\b(?:https?|ftp):\/\/[\w\/\#~:.?+=&%@!\-;,]+?' . - '(?=[.:?\-;,]*(?:[^\w\/\#~:.?+=&%@!\-;,]|$)))/iS'; - - $matches = preg_split($url_pattern, $comment, -1, - PREG_SPLIT_DELIM_CAPTURE); - - $html = ''; - for ($i = 0; $i < count($matches); $i++) { - if ($i % 2) { - # convert links - $html .= '' . htmlspecialchars($matches[$i]) . ''; - } - else { - # convert everything else - $html .= nl2br(htmlspecialchars($matches[$i])); - } - } - - return $html; -} diff --git a/web/lib/aur.inc.php b/web/lib/aur.inc.php new file mode 100644 index 0000000..572d781 --- /dev/null +++ b/web/lib/aur.inc.php @@ -0,0 +1,593 @@ + ".mysql_error($db_handle)); + } + + return $result; +} + +# Set a value in the cache (currently APC) if cache is available for use. If +# not available, this becomes effectively a no-op (return value is +# false). Accepts an optional TTL (defaults to 600 seconds). +function set_cache_value($key, $value, $ttl=600) { + $status = false; + if (EXTENSION_LOADED_APC) { + $status = apc_store(APC_PREFIX.$key, $value, $ttl); + } + return $status; +} + +# Get a value from the cache (currently APC) if cache is available for use. If +# not available, this returns false (optionally sets passed in variable $status +# to false, much like apc_fetch() behaves). This allows for testing the fetch +# result appropriately even in the event that a 'false' value was the value in +# the cache. +function get_cache_value($key, &$status=false) { + if(EXTENSION_LOADED_APC) { + $ret = apc_fetch(APC_PREFIX.$key, $status); + if ($status) { + return $ret; + } + } + return $status; +} + +# Run a simple db query, retrieving and/or caching the value if APC is +# available for use. Accepts an optional TTL value (defaults to 600 seconds). +function db_cache_value($dbq, $dbh, $key, $ttl=600) { + $status = false; + $value = get_cache_value($key, $status); + if (!$status) { + $result = db_query($dbq, $dbh); + $row = mysql_fetch_row($result); + $value = $row[0]; + set_cache_value($key, $value, $ttl); + } + return $value; +} + +# set up the visitor's language +# +function set_lang() { + global $LANG; + global $SUPPORTED_LANGS; + global $PERSISTENT_COOKIE_TIMEOUT; + global $streamer, $l10n; + + $update_cookie = 0; + if (isset($_REQUEST['setlang'])) { + # visitor is requesting a language change + # + $LANG = $_REQUEST['setlang']; + $update_cookie = 1; + + } elseif (isset($_COOKIE['AURLANG'])) { + # If a cookie is set, use that + # + $LANG = $_COOKIE['AURLANG']; + + } elseif (isset($_COOKIE["AURSID"])) { + # No language but a session; use default lang preference + # + $dbh = db_connect(); + $q = "SELECT LangPreference FROM Users, Sessions "; + $q.= "WHERE Users.ID = Sessions.UsersID "; + $q.= "AND Sessions.SessionID = '"; + $q.= mysql_real_escape_string($_COOKIE["AURSID"])."'"; + $result = db_query($q, $dbh); + + if ($result) { + $row = mysql_fetch_array($result); + $LANG = $row[0]; + } + $update_cookie = 1; + } + + # Set $LANG to default if nothing is valid. + if (!array_key_exists($LANG, $SUPPORTED_LANGS)) { + $LANG = DEFAULT_LANG; + } + + if ($update_cookie) { + $cookie_time = time() + $PERSISTENT_COOKIE_TIMEOUT; + setcookie("AURLANG", $LANG, $cookie_time, "/"); + } + + $streamer = new FileReader('../locale/' . $LANG . + '/LC_MESSAGES/aur.mo'); + $l10n = new gettext_reader($streamer, true); + + return; +} + + +# common header +# +function html_header($title="") { + global $_SERVER; + global $_COOKIE; + global $_POST; + global $LANG; + global $SUPPORTED_LANGS; + + $login = try_login(); + $login_error = $login['error']; + + $title = htmlspecialchars($title, ENT_QUOTES); + + include('header.php'); + return; +} + + +# common footer +# +function html_footer($ver="") { + include('footer.php'); + return; +} + +# check to see if the user can submit a package +# +function can_submit_pkg($name="", $sid="") { + if (!$name || !$sid) {return 0;} + $dbh = db_connect(); + $q = "SELECT MaintainerUID "; + $q.= "FROM Packages WHERE Name = '".mysql_real_escape_string($name)."'"; + $result = db_query($q, $dbh); + if (mysql_num_rows($result) == 0) {return 1;} + $row = mysql_fetch_row($result); + $my_uid = uid_from_sid($sid); + + if ($row[0] === NULL || $row[0] == $my_uid) { + return 1; + } + + return 0; +} + +# recursive delete directory +# +function rm_tree($dirname) { + if (empty($dirname) || !is_dir($dirname)) return; + + foreach (scandir($dirname) as $item) { + if ($item != '.' && $item != '..') { + $path = $dirname . '/' . $item; + if (is_file($path) || is_link($path)) { + unlink($path); + } + else { + rm_tree($path); + } + } + } + + rmdir($dirname); + + return; +} + +# Recursive chmod to set group write permissions +# +function chmod_group($path) { + if (!is_dir($path)) + return chmod($path, 0664); + + $d = dir($path); + while ($f = $d->read()) { + if ($f != '.' && $f != '..') { + $fullpath = $path.'/'.$f; + if (is_link($fullpath)) + continue; + elseif (!is_dir($fullpath)) { + if (!chmod($fullpath, 0664)) + return FALSE; + } + elseif(!chmod_group($fullpath)) + return FALSE; + } + } + $d->close(); + + if(chmod($path, 0775)) + return TRUE; + else + return FALSE; +} + +# obtain the uid given a Users.Username +# +function uid_from_username($username="") +{ + if (!$username) { + return ""; + } + $dbh = db_connect(); + $q = "SELECT ID FROM Users WHERE Username = '".mysql_real_escape_string($username) + ."'"; + $result = db_query($q, $dbh); + if (!$result) { + return "None"; + } + $row = mysql_fetch_row($result); + + return $row[0]; +} + +# obtain the uid given a Users.Email +# +function uid_from_email($email="") +{ + if (!$email) { + return ""; + } + $dbh = db_connect(); + $q = "SELECT ID FROM Users WHERE Email = '".mysql_real_escape_string($email) + ."'"; + $result = db_query($q, $dbh); + if (!$result) { + return "None"; + } + $row = mysql_fetch_row($result); + + return $row[0]; +} + +# check user privileges +# +function check_user_privileges() +{ + $type = account_from_sid($_COOKIE['AURSID']); + return ($type == 'Trusted User' || $type == 'Developer'); +} + +/** + * Generate clean url with edited/added user values + * + * Makes a clean string of variables for use in URLs based on current $_GET and + * list of values to edit/add to that. Any empty variables are discarded. + * + * ex. print "http://example.com/test.php?" . mkurl("foo=bar&bar=baz") + * + * @param string $append string of variables and values formatted as in URLs + * ex. mkurl("foo=bar&bar=baz") + * @return string clean string of variables to append to URL, urlencoded + */ +function mkurl($append) { + $get = $_GET; + $append = explode('&', $append); + $uservars = array(); + $out = ''; + + foreach ($append as $i) { + $ex = explode('=', $i); + $uservars[$ex[0]] = $ex[1]; + } + + foreach ($uservars as $k => $v) { $get[$k] = $v; } + + foreach ($get as $k => $v) { + if ($v !== '') { + $out .= '&' . urlencode($k) . '=' . urlencode($v); + } + } + + return substr($out, 5); +} + +function get_salt($user_id) +{ + $dbh = db_connect(); + $salt_q = "SELECT Salt FROM Users WHERE ID = " . $user_id; + $result = db_query($salt_q, $dbh); + if ($result) { + $salt_row = mysql_fetch_row($result); + return $salt_row[0]; + } + return; +} + +function save_salt($user_id, $passwd) +{ + $dbh = db_connect(); + $salt = generate_salt(); + $hash = salted_hash($passwd, $salt); + $salting_q = "UPDATE Users SET Salt = '" . $salt . "', " . + "Passwd = '" . $hash . "' WHERE ID = " . $user_id; + return db_query($salting_q, $dbh); +} + +function generate_salt() +{ + return md5(uniqid(mt_rand(), true)); +} + +function salted_hash($passwd, $salt) +{ + if (strlen($salt) != 32) { + trigger_error('Salt does not look like an md5 hash', E_USER_WARNING); + } + return md5($salt . $passwd); +} + +function parse_comment($comment) +{ + $url_pattern = '/(\b(?:https?|ftp):\/\/[\w\/\#~:.?+=&%@!\-;,]+?' . + '(?=[.:?\-;,]*(?:[^\w\/\#~:.?+=&%@!\-;,]|$)))/iS'; + + $matches = preg_split($url_pattern, $comment, -1, + PREG_SPLIT_DELIM_CAPTURE); + + $html = ''; + for ($i = 0; $i < count($matches); $i++) { + if ($i % 2) { + # convert links + $html .= '' . htmlspecialchars($matches[$i]) . ''; + } + else { + # convert everything else + $html .= nl2br(htmlspecialchars($matches[$i])); + } + } + + return $html; +} diff --git a/web/lib/aurjson.class.php b/web/lib/aurjson.class.php index 0f8e2fa..5d15b89 100644 --- a/web/lib/aurjson.class.php +++ b/web/lib/aurjson.class.php @@ -4,7 +4,7 @@ * * This file contains the AurRPC remote handling class **/ -include_once("aur.inc"); +include_once("aur.inc.php"); /** * This class defines a remote interface for fetching data diff --git a/web/lib/config.inc.php.proto b/web/lib/config.inc.php.proto new file mode 100644 index 0000000..43c64d2 --- /dev/null +++ b/web/lib/config.inc.php.proto @@ -0,0 +1,64 @@ + "Català", + "cs" => "česky", + "da" => "Dansk", + "de" => "Deutsch", + "en" => "English", + "el_GR" => "Ελληνικά", + "es" => "Español", + "fr" => "Français", + "he" => "עברית", + "hr" => "Hrvatski", + "hu" => "Magyar", + "it" => "Italiano", + "nb_NO" => "Norsk", + "pl" => "Polski", + "pt" => "Português", + "ro" => "Română", + "ru" => "Русский", + "sr" => "Srpski", + "tr" => "Türkçe", + "uk" => "Українська", + "zh_CN" => "简体中文" +); + +# Session limit per user +$MAX_SESSIONS_PER_USER = 8; + +# Idle seconds before timeout +$LOGIN_TIMEOUT = 7200; + +# Session timeout when using "Remember me" cookies +$PERSISTENT_COOKIE_TIMEOUT = 60 * 60 * 24 * 30; + +# Uncompressed file size limit for submitted tarballs (ZIP bomb protection) - +# please ensure "upload_max_filesize" is additionally set to no more than 3M, +# otherwise this check might be easy to bypass (FS#22991 for details) +$MAX_FILESIZE_UNCOMPRESSED = 1024 * 1024 * 8; diff --git a/web/lib/config.inc.proto b/web/lib/config.inc.proto deleted file mode 100644 index 43c64d2..0000000 --- a/web/lib/config.inc.proto +++ /dev/null @@ -1,64 +0,0 @@ - "Català", - "cs" => "česky", - "da" => "Dansk", - "de" => "Deutsch", - "en" => "English", - "el_GR" => "Ελληνικά", - "es" => "Español", - "fr" => "Français", - "he" => "עברית", - "hr" => "Hrvatski", - "hu" => "Magyar", - "it" => "Italiano", - "nb_NO" => "Norsk", - "pl" => "Polski", - "pt" => "Português", - "ro" => "Română", - "ru" => "Русский", - "sr" => "Srpski", - "tr" => "Türkçe", - "uk" => "Українська", - "zh_CN" => "简体中文" -); - -# Session limit per user -$MAX_SESSIONS_PER_USER = 8; - -# Idle seconds before timeout -$LOGIN_TIMEOUT = 7200; - -# Session timeout when using "Remember me" cookies -$PERSISTENT_COOKIE_TIMEOUT = 60 * 60 * 24 * 30; - -# Uncompressed file size limit for submitted tarballs (ZIP bomb protection) - -# please ensure "upload_max_filesize" is additionally set to no more than 3M, -# otherwise this check might be easy to bypass (FS#22991 for details) -$MAX_FILESIZE_UNCOMPRESSED = 1024 * 1024 * 8; diff --git a/web/lib/pkgfuncs.inc b/web/lib/pkgfuncs.inc deleted file mode 100644 index 2024aeb..0000000 --- a/web/lib/pkgfuncs.inc +++ /dev/null @@ -1,1001 +0,0 @@ - 0) { - return TRUE; - } - } - return FALSE; -} - -# Make sure this visitor can delete the requested package comment -# They can delete if they were the comment submitter, or if they are a TU/Dev -# -function canDeleteCommentArray($comment, $atype="", $uid=0) { - if ($atype == "Trusted User" || $atype == "Developer") { - # A TU/Dev can delete any comment - return TRUE; - } else if ($comment['UsersID'] == $uid) { - # User's own comment - return TRUE; - } - return FALSE; -} - -# see if this Users.ID can manage the package -# -function canManagePackage($uid=0,$AURMUID=0, $MUID=0, $SUID=0, $managed=0) { - if (!$uid) {return 0;} - - # The uid of the TU/Dev that manages the package - # - if ($uid == $AURMUID) {return 1;} - - # If the package isn't maintained by a TU/Dev, is this the user-maintainer? - # - if ($uid == $MUID && !$managed) {return 1;} - - # If the package isn't maintained by a TU/Dev, is this the user-submitter? - # - if ($uid == $SUID && !$managed) {return 1;} - - # otherwise, no right to manage this package - # - return 0; -} - -# Check if the current user can submit blacklisted packages. -# -function canSubmitBlacklisted($atype = "") { - if ($atype == "Trusted User" || $atype == "Developer") { - # Only TUs/Devs can submit blacklisted packages. - return TRUE; - } - else { - return FALSE; - } -} - -# grab the current list of PackageCategories -# -function pkgCategories() { - $cats = array(); - $dbh = db_connect(); - $q = "SELECT * FROM PackageCategories WHERE ID != 1 "; - $q.= "ORDER BY Category ASC"; - $result = db_query($q, $dbh); - if ($result) { - while ($row = mysql_fetch_row($result)) { - $cats[$row[0]] = $row[1]; - } - } - return $cats; -} - -# check to see if the package name exists -# -function package_exists($name="") { - if (!$name) {return NULL;} - $dbh = db_connect(); - $q = "SELECT ID FROM Packages "; - $q.= "WHERE Name = '".mysql_real_escape_string($name)."' "; - $result = db_query($q, $dbh); - if (!$result) {return NULL;} - $row = mysql_fetch_row($result); - return $row[0]; -} - -# grab package dependencies -# -function package_dependencies($pkgid=0) { - $deps = array(); - $pkgid = intval($pkgid); - if ($pkgid > 0) { - $dbh = db_connect(); - $q = "SELECT pd.DepName, pd.DepCondition, p.ID FROM PackageDepends pd "; - $q.= "LEFT JOIN Packages p ON pd.DepName = p.Name "; - $q.= "WHERE pd.PackageID = ". $pkgid . " "; - $q.= "ORDER BY pd.DepName"; - $result = db_query($q, $dbh); - if (!$result) {return array();} - while ($row = mysql_fetch_row($result)) { - $deps[] = $row; - } - } - return $deps; -} - -function package_required($name="") { - $deps = array(); - if ($name != "") { - $dbh = db_connect(); - $q = "SELECT p.Name, PackageID FROM PackageDepends pd "; - $q.= "JOIN Packages p ON pd.PackageID = p.ID "; - $q.= "WHERE DepName = '".mysql_real_escape_string($name)."' "; - $q.= "ORDER BY p.Name"; - $result = db_query($q, $dbh); - if (!$result) {return array();} - while ($row = mysql_fetch_row($result)) { - $deps[] = $row; - } - } - return $deps; -} - -# Return the number of comments for a specified package -function package_comments_count($pkgid = 0) { - $pkgid = intval($pkgid); - if ($pkgid > 0) { - $dbh = db_connect(); - $q = "SELECT COUNT(*) FROM PackageComments "; - $q.= "WHERE PackageID = " . $pkgid; - $q.= " AND DelUsersID IS NULL"; - } - $result = db_query($q, $dbh); - - if (!$result) { - return; - } - - return mysql_result($result, 0); -} - -# Return an array of package comments -function package_comments($pkgid = 0) { - $comments = array(); - $pkgid = intval($pkgid); - if ($pkgid > 0) { - $dbh = db_connect(); - $q = "SELECT PackageComments.ID, UserName, UsersID, Comments, CommentTS "; - $q.= "FROM PackageComments, Users "; - $q.= "WHERE PackageComments.UsersID = Users.ID"; - $q.= " AND PackageID = " . $pkgid; - $q.= " AND DelUsersID IS NULL"; # only display non-deleted comments - $q.= " ORDER BY CommentTS DESC"; - - if (!isset($_GET['comments'])) { - $q.= " LIMIT 10"; - } - - $result = db_query($q, $dbh); - - if (!$result) { - return; - } - - while ($row = mysql_fetch_assoc($result)) { - $comments[] = $row; - } - } - return $comments; -} - -# grab package sources -# -function package_sources($pkgid=0) { - $sources = array(); - $pkgid = intval($pkgid); - if ($pkgid > 0) { - $dbh = db_connect(); - $q = "SELECT Source FROM PackageSources "; - $q.= "WHERE PackageID = " . $pkgid; - $q.= " ORDER BY Source"; - $result = db_query($q, $dbh); - if (!$result) {return array();} - while ($row = mysql_fetch_row($result)) { - $sources[] = $row[0]; - } - } - return $sources; -} - - -# grab array of Package.IDs that I've voted for: $pkgs[1234] = 1, ... -# -function pkgvotes_from_sid($sid="") { - $pkgs = array(); - if (!$sid) {return $pkgs;} - $dbh = db_connect(); - $q = "SELECT PackageID "; - $q.= "FROM PackageVotes, Users, Sessions "; - $q.= "WHERE Users.ID = Sessions.UsersID "; - $q.= "AND Users.ID = PackageVotes.UsersID "; - $q.= "AND Sessions.SessionID = '".mysql_real_escape_string($sid)."'"; - $result = db_query($q, $dbh); - if ($result) { - while ($row = mysql_fetch_row($result)) { - $pkgs[$row[0]] = 1; - } - } - return $pkgs; -} - -# array of package ids that you're being notified for -# *yoink* -# -function pkgnotify_from_sid($sid="") { - $pkgs = array(); - if (!$sid) {return $pkgs;} - $dbh = db_connect(); - $q = "SELECT PkgID "; - $q.= "FROM CommentNotify, Users, Sessions "; - $q.= "WHERE Users.ID = Sessions.UsersID "; - $q.= "AND Users.ID = CommentNotify.UserID "; - $q.= "AND Sessions.SessionID = '".mysql_real_escape_string($sid)."'"; - $result = db_query($q, $dbh); - if ($result) { - while ($row = mysql_fetch_row($result)) { - $pkgs[$row[0]] = 1; - } - } - return $pkgs; -} - -# get name of package based on pkgid -# -function pkgname_from_id($pkgid=0) { - $pkgid = intval($pkgid); - $name = ""; - if ($pkgid > 0) { - $dbh = db_connect(); - $q = "SELECT Name FROM Packages WHERE ID = " . $pkgid; - $result = db_query($q, $dbh); - if (mysql_num_rows($result) > 0) { - $name = mysql_result($result, 0); - } - } - return $name; -} - -# Check if a package name is blacklisted. -# -function pkgname_is_blacklisted($name) { - $dbh = db_connect(); - $q = "SELECT COUNT(*) FROM PackageBlacklist WHERE Name = '" . mysql_real_escape_string($name) . "'"; - $result = db_query($q, $dbh); - - if (!$result) return false; - return (mysql_result($result, 0) > 0); -} - -# display package details -# -function package_details($id=0, $SID="") { - $atype = account_from_sid($SID); - $uid = uid_from_sid($SID); - - $q = "SELECT Packages.*,Category "; - $q.= "FROM Packages,PackageCategories "; - $q.= "WHERE Packages.CategoryID = PackageCategories.ID "; - $q.= "AND Packages.ID = " . intval($id); - $dbh = db_connect(); - $results = db_query($q, $dbh); - - if (!$results) { - print __("Error retrieving package details.") . "
\n"; - } - else { - $row = mysql_fetch_assoc($results); - if (empty($row)) { - print __("Package details could not be found.") . "
\n"; - - } - else { - include('pkg_details.php'); - - # Actions Bar - if ($SID) { - include('actions_form.php'); - include('pkg_comment_form.php'); - } - - # Print Comments - $comments = package_comments($id); - if (!empty($comments)) { - include('pkg_comments.php'); - } - } - } - return; -} - - -/* pkg_search_page(SID) - * outputs the body of search/search results page - * - * parameters: - * SID - current Session ID - * preconditions: - * package search page has been accessed - * request variables have not been sanitized - * - * request vars: - * O - starting result number - * PP - number of search hits per page - * C - package category ID number - * K - package search string - * SO - search hit sort order: - * values: a - ascending - * d - descending - * SB - sort search hits by: - * values: c - package category - * n - package name - * v - number of votes - * m - maintainer username - * SeB- property that search string (K) represents - * values: n - package name - * nd - package name & description - * x - package name (exact match) - * m - package maintainer's username - * s - package submitter's username - * do_Orphans - boolean. whether to search packages - * without a maintainer - * - * - * These two are actually handled in packages.php. - * - * IDs- integer array of ticked packages' IDs - * action - action to be taken on ticked packages - * values: do_Flag - Flag out-of-date - * do_UnFlag - Remove out-of-date flag - * do_Adopt - Adopt - * do_Disown - Disown - * do_Delete - Delete (requires confirm_Delete to be set) - * do_Notify - Enable notification - * do_UnNotify - Disable notification - */ -function pkg_search_page($SID="") { - // establish a db connection - $dbh = db_connect(); - - // get commonly used variables... - // TODO: REDUCE DB HITS. - // grab info for user if they're logged in - if ($SID) - $myuid = uid_from_sid($SID); - // get a list of package categories - $cats = pkgCategories(); //meow - - // sanitize paging variables - // - if (isset($_GET['O'])) { - $_GET['O'] = intval($_GET['O']); - if ($_GET['O'] < 0) - $_GET['O'] = 0; - } - else { - $_GET['O'] = 0; - } - - if (isset($_GET["PP"])) { - $_GET["PP"] = intval($_GET["PP"]); - if ($_GET["PP"] < 50) - $_GET["PP"] = 50; - else if ($_GET["PP"] > 250) - $_GET["PP"] = 250; - } - else { - $_GET["PP"] = 50; - } - - // FIXME: pull out DB-related code. all of it. - // this one's worth a choco-chip cookie, - // one of those nice big soft ones - - // build the package search query - // - $q_select = "SELECT "; - if ($SID) { - $q_select .= "CommentNotify.UserID AS Notify, - PackageVotes.UsersID AS Voted, "; - } - $q_select .= "Users.Username AS Maintainer, - PackageCategories.Category, - Packages.Name, Packages.Version, Packages.Description, Packages.NumVotes, - Packages.ID, Packages.OutOfDateTS "; - - $q_from = "FROM Packages - LEFT JOIN Users ON (Packages.MaintainerUID = Users.ID) - LEFT JOIN PackageCategories - ON (Packages.CategoryID = PackageCategories.ID) "; - if ($SID) { - # this portion is not needed for the total row count query - $q_from_extra = "LEFT JOIN PackageVotes - ON (Packages.ID = PackageVotes.PackageID AND PackageVotes.UsersID = $myuid) - LEFT JOIN CommentNotify - ON (Packages.ID = CommentNotify.PkgID AND CommentNotify.UserID = $myuid) "; - } else { - $q_from_extra = ""; - } - - $q_where = "WHERE 1 = 1 "; - // TODO: possibly do string matching on category - // to make request variable values more sensible - if (isset($_GET["C"]) && intval($_GET["C"])) { - $q_where .= "AND Packages.CategoryID = ".intval($_GET["C"])." "; - } - - if (isset($_GET['K'])) { - $_GET['K'] = mysql_real_escape_string(trim($_GET['K'])); - - # Search by maintainer - if (isset($_GET["SeB"]) && $_GET["SeB"] == "m") { - $q_where .= "AND Users.Username = '".$_GET['K']."' "; - } - # Search by submitter - elseif (isset($_GET["SeB"]) && $_GET["SeB"] == "s") { - $q_where .= "AND SubmitterUID = ".uid_from_username($_GET['K'])." "; - } - # Search by name - elseif (isset($_GET["SeB"]) && $_GET["SeB"] == "n") { - $q_where .= "AND (Name LIKE '%".$_GET['K']."%') "; - } - # Search by name (exact match) - elseif (isset($_GET["SeB"]) && $_GET["SeB"] == "x") { - $q_where .= "AND (Name = '".$_GET['K']."') "; - } - # Search by name and description (Default) - else { - $q_where .= "AND (Name LIKE '%".$_GET['K']."%' OR "; - $q_where .= "Description LIKE '%".$_GET['K']."%') "; - } - } - - if (isset($_GET["do_Orphans"])) { - $q_where .= "AND MaintainerUID IS NULL "; - } - - if (isset($_GET['outdated'])) { - if ($_GET['outdated'] == 'on') { - $q_where .= "AND OutOfDateTS IS NOT NULL "; - } - elseif ($_GET['outdated'] == 'off') { - $q_where .= "AND OutOfDateTS IS NULL "; - } - } - - $order = (isset($_GET["SO"]) && $_GET["SO"] == 'd') ? 'DESC' : 'ASC'; - - $q_sort = "ORDER BY Name ".$order.", CategoryID DESC "; - $sort_by = isset($_GET["SB"]) ? $_GET["SB"] : ''; - switch ($sort_by) { - case 'c': - $q_sort = "ORDER BY CategoryID ".$order.", Name ASC "; - break; - case 'v': - $q_sort = "ORDER BY NumVotes ".$order.", Name ASC, CategoryID DESC "; - break; - case 'w': - if ($SID) { - $q_sort = "ORDER BY Voted ".$order.", Name ASC, CategoryID DESC "; - } - break; - case 'o': - if ($SID) { - $q_sort = "ORDER BY Notify ".$order.", Name ASC, CategoryID DESC "; - } - break; - case 'm': - $q_sort = "ORDER BY Maintainer ".$order.", Name ASC "; - break; - case 'a': - $q_sort = "ORDER BY ModifiedTS ".$order.", Name ASC "; - break; - default: - break; - } - - $q_limit = "LIMIT ".$_GET["PP"]." OFFSET ".$_GET["O"]; - - $q = $q_select . $q_from . $q_from_extra . $q_where . $q_sort . $q_limit; - $q_total = "SELECT COUNT(*) " . $q_from . $q_where; - - $result = db_query($q, $dbh); - $result_t = db_query($q_total, $dbh); - if ($result_t) { - $total = mysql_result($result_t, 0); - } - else { - $total = 0; - } - - if ($result && $total > 0) { - if (isset($_GET["SO"]) && $_GET["SO"] == "d"){ - $SO_next = "a"; - } - else { - $SO_next = "d"; - } - } - - // figure out the results to use - $first = $_GET['O'] + 1; - - if (($_GET['PP'] + $_GET['O']) > $total) { - $last = $total; - } else { - $last = $_GET['PP'] + $_GET['O']; - } - - - if ($total > 1 || $total == 0) { - # calculation of pagination links - $per_page = ($_GET['PP'] > 0) ? $_GET['PP'] : 50; - $current = ceil($first / $per_page); - $pages = ceil($total / $per_page); - $templ_pages = array(); - - if ($current > 1) { - $templ_pages[__('First')] = 0; - $templ_pages[__('Previous')] = ($current - 2) * $per_page; - } - - if ($current - 5 > 1) - $templ_pages["..."] = false; - - for ($i = max($current - 5, 1); $i <= min($pages, $current + 5); $i++) { - $templ_pages[$i] = ($i - 1) * $per_page; - } - - if ($current + 5 < $pages) - $templ_pages["... "] = false; - - if ($current < $pages) { - $templ_pages[__('Next')] = $current * $per_page; - $templ_pages[__('Last')] = ($pages - 1) * $per_page; - } - - include('pkg_search_form.php'); - include('pkg_search_results.php'); - } - else { - $pkgdetails = mysql_fetch_assoc($result); - header("Location: packages.php?ID={$pkgdetails['ID']}"); - } - - return; -} - -function current_action($action) { - return (isset($_POST['action']) && $_POST['action'] == $action) || - isset($_POST[$action]); -} - -/** - * Ensure an array of IDs is in fact all valid integers. - */ -function sanitize_ids($ids) { - $new_ids = array(); - foreach ($ids as $id) { - $id = intval($id); - if ($id > 0) { - $new_ids[] = $id; - } - } - return $new_ids; -} - -/** - * Flag and un-flag packages out-of-date - * - * @param string $atype Account type, output of account_from_sid - * @param array $ids Array of package IDs to flag/unflag - * @param boolean $action True flags out-of-date, false un-flags. Flags by - * default - * - * @return string Translated success or error messages - */ -function pkg_flag ($atype, $ids, $action = True) { - if (!$atype) { - if ($action) { - return __("You must be logged in before you can flag packages."); - } else { - return __("You must be logged in before you can unflag packages."); - } - } - - $ids = sanitize_ids($ids); - if (empty($ids)) { - if ($action) { - return __("You did not select any packages to flag."); - } else { - return __("You did not select any packages to unflag."); - } - } - - $dbh = db_connect(); - - $q = "UPDATE Packages SET"; - if ($action) { - $q.= " OutOfDateTS = UNIX_TIMESTAMP()"; - } - else { - $q.= " OutOfDateTS = NULL"; - } - $q.= " WHERE ID IN (" . implode(",", $ids) . ")"; - - db_query($q, $dbh); - - if ($action) { - # Notify of flagging by email - $f_name = username_from_sid($_COOKIE['AURSID']); - $f_email = email_from_sid($_COOKIE['AURSID']); - $f_uid = uid_from_sid($_COOKIE['AURSID']); - $q = "SELECT Packages.Name, Users.Email, Packages.ID "; - $q.= "FROM Packages, Users "; - $q.= "WHERE Packages.ID IN (" . implode(",", $ids) .") "; - $q.= "AND Users.ID = Packages.MaintainerUID "; - $q.= "AND Users.ID != " . $f_uid; - $result = db_query($q, $dbh); - if (mysql_num_rows($result)) { - while ($row = mysql_fetch_assoc($result)) { - # construct email - $body = "Your package " . $row['Name'] . " has been flagged out of date by " . $f_name . " [1]. You may view your package at:\nhttps://aur.archlinux.org/packages.php?ID=" . $row['ID'] . "\n\n[1] - https://aur.archlinux.org/account.php?Action=AccountInfo&ID=" . $f_uid; - $body = wordwrap($body, 70); - $headers = "Reply-to: nobody@archlinux.org\nFrom:aur-notify@archlinux.org\nX-Mailer: PHP\nX-MimeOLE: Produced By AUR\n"; - @mail($row['Email'], "AUR Out-of-date Notification for ".$row['Name'], $body, $headers); - } - } - } - - if ($action) { - return __("The selected packages have been flagged out-of-date."); - } else { - return __("The selected packages have been unflagged."); - } -} - -/** - * Delete packages - * - * @param string $atype Account type, output of account_from_sid - * @param array $ids Array of package IDs to delete - * - * @return string Translated error or success message - */ -function pkg_delete ($atype, $ids) { - if (!$atype) { - return __("You must be logged in before you can delete packages."); - } - - # If they're a TU or dev, can delete - if ($atype != "Trusted User" && $atype != "Developer") { - return __("You do have permission to delete packages."); - } - - $ids = sanitize_ids($ids); - if (empty($ids)) { - return __("You did not select any packages to delete."); - } - - $dbh = db_connect(); - $q = "DELETE FROM Packages WHERE ID IN (" . implode(",", $ids) . ")"; - $result = db_query($q, $dbh); - - return __("The selected packages have been deleted."); -} - -/** - * Adopt or disown packages - * - * @param string $atype Account type, output of account_from_sid - * @param array $ids Array of package IDs to adopt/disown - * @param boolean $action Adopts if true, disowns if false. Adopts by default - * - * @return string Translated error or success message - */ -function pkg_adopt ($atype, $ids, $action = True) { - if (!$atype) { - if ($action) { - return __("You must be logged in before you can adopt packages."); - } else { - return __("You must be logged in before you can disown packages."); - } - } - - $ids = sanitize_ids($ids); - if (empty($ids)) { - if ($action) { - return __("You did not select any packages to adopt."); - } else { - return __("You did not select any packages to disown."); - } - } - - $dbh = db_connect(); - - $field = "MaintainerUID"; - $q = "UPDATE Packages "; - - if ($action) { - $user = uid_from_sid($_COOKIE["AURSID"]); - } else { - $user = 'NULL'; - } - - $q.= "SET $field = $user "; - $q.= "WHERE ID IN (" . implode(",", $ids) . ") "; - - if ($action && $atype == "User") { - # Regular users may only adopt orphan packages from unsupported - $q.= "AND $field IS NULL "; - } else if ($atype == "User") { - $q.= "AND $field = " . uid_from_sid($_COOKIE["AURSID"]); - } - - db_query($q, $dbh); - - if ($action) { - pkg_notify(account_from_sid($_COOKIE["AURSID"]), $ids); - return __("The selected packages have been adopted."); - } else { - return __("The selected packages have been disowned."); - } -} - -/** - * Vote and un-vote for packages - * - * @param string $atype Account type, output of account_from_sid - * @param array $ids Array of package IDs to vote/un-vote - * @param boolean $action Votes if true, un-votes if false. Votes by default - * - * @return string Translated error or success message - */ -function pkg_vote ($atype, $ids, $action = True) { - if (!$atype) { - if ($action) { - return __("You must be logged in before you can vote for packages."); - } else { - return __("You must be logged in before you can un-vote for packages."); - } - } - - $ids = sanitize_ids($ids); - if (empty($ids)) { - if ($action) { - return __("You did not select any packages to vote for."); - } else { - return __("Your votes have been removed from the selected packages."); - } - } - - $dbh = db_connect(); - $my_votes = pkgvotes_from_sid($_COOKIE["AURSID"]); - $uid = uid_from_sid($_COOKIE["AURSID"]); - - $first = 1; - foreach ($ids as $pid) { - if ($action) { - $check = !isset($my_votes[$pid]); - } else { - $check = isset($my_votes[$pid]); - } - - if ($check) { - if ($first) { - $first = 0; - $vote_ids = $pid; - if ($action) { - $vote_clauses = "($uid, $pid)"; - } - } else { - $vote_ids .= ", $pid"; - if ($action) { - $vote_clauses .= ", ($uid, $pid)"; - } - } - } - } - - # only vote for packages the user hasn't already voted for - # - $op = $action ? "+" : "-"; - $q = "UPDATE Packages SET NumVotes = NumVotes $op 1 "; - $q.= "WHERE ID IN ($vote_ids)"; - - db_query($q, $dbh); - - if ($action) { - $q = "INSERT INTO PackageVotes (UsersID, PackageID) VALUES "; - $q.= $vote_clauses; - } else { - $q = "DELETE FROM PackageVotes WHERE UsersID = $uid "; - $q.= "AND PackageID IN ($vote_ids)"; - } - - db_query($q, $dbh); - - if ($action) { - $q = "UPDATE Users SET LastVoted = UNIX_TIMESTAMP() "; - $q.= "WHERE ID = $uid"; - - db_query($q, $dbh); - } - - if ($action) { - return __("Your votes have been cast for the selected packages."); - } else { - return __("Your votes have been removed from the selected packages."); - } -} - -/** - * Toggle notification of packages - * - * @param string $atype Account type, output of account_from_sid - * @param array $ids Array of package IDs to toggle, formatted as $package_id - * @return string Translated error or success message - */ -function pkg_notify ($atype, $ids, $action = True) { - if (!$atype) { -# return __("You must be logged in before you can get notifications on comments."); - return; - } - - $ids = sanitize_ids($ids); - if (empty($ids)) { - return __("Couldn't add to notification list."); - } - - $dbh = db_connect(); - $uid = uid_from_sid($_COOKIE["AURSID"]); - - $output = ""; - - $first = True; - - # There currently shouldn't be multiple requests here, but the - # format in which it's sent requires this. - foreach ($ids as $pid) { - $q = "SELECT Name FROM Packages WHERE ID = $pid"; - $result = db_query($q, $dbh); - if ($result) { - $pkgname = mysql_result($result , 0); - } - else { - $pkgname = ''; - } - - if ($first) - $first = False; - else - $output .= ", "; - - - if ($action) { - $q = "SELECT * FROM CommentNotify WHERE UserID = $uid"; - $q .= " AND PkgID = $pid"; - - # Notification already added. Don't add again. - $result = db_query($q, $dbh); - if (!mysql_num_rows($result)) { - $q = "INSERT INTO CommentNotify (PkgID, UserID) VALUES ($pid, $uid)"; - db_query($q, $dbh); - } - - $output .= $pkgname; - } - else { - $q = "DELETE FROM CommentNotify WHERE PkgID = $pid"; - $q .= " AND UserID = $uid"; - db_query($q, $dbh); - - $output .= $pkgname; - } - } - - if ($action) { - $output = __("You have been added to the comment notification list for %s.", $output); - } - else { - $output = __("You have been removed from the comment notification list for %s.", $output); - } - - return $output; -} - - - -/** - * Delete comment - * - * @param string $atype Account type, output of account_from_sid - * @return string Translated error or success message - */ -function pkg_delete_comment($atype) { - if (!$atype) { - return __("You must be logged in before you can edit package information."); - } - - # Get ID of comment to be removed - if (isset($_POST["comment_id"])) { - $comment_id = $_POST["comment_id"]; - } else { - return __("Missing comment ID."); - } - - $uid = uid_from_sid($_COOKIE["AURSID"]); - if (canDeleteComment($comment_id, $atype, $uid)) { - - $dbh = db_connect(); - $q = "UPDATE PackageComments "; - $q.= "SET DelUsersID = ".$uid." "; - $q.= "WHERE ID = ".intval($comment_id); - db_query($q, $dbh); - return __("Comment has been deleted."); - } else { - return __("You are not allowed to delete this comment."); - } -} - -/** - * Change package category - * - * @param string $atype Account type, output of account_from_sid - * @return string Translated error or success message - */ -function pkg_change_category($atype) { - if (!$atype) { - return __("You must be logged in before you can edit package information."); - } - - # Get ID of the new category - if (isset($_POST["category_id"])) { - $category_id = $_POST["category_id"]; - } else { - return __("Missing category ID."); - } - - $catArray = pkgCategories(); - if (!array_key_exists($category_id, $catArray)) { - return __("Invalid category ID."); - } - - if (isset($_GET["ID"])) { - $pid = $_GET["ID"]; - } else { - return __("Missing package ID."); - } - - # Verify package ownership - $dbh = db_connect(); - $q = "SELECT Packages.MaintainerUID "; - $q.= "FROM Packages "; - $q.= "WHERE Packages.ID = ".$pid; - $result = db_query($q, $dbh); - if ($result) { - $pkg = mysql_fetch_assoc($result); - } - else { - return __("You are not allowed to change this package category."); - } - - $uid = uid_from_sid($_COOKIE["AURSID"]); - if ($uid == $pkg["MaintainerUID"] or - ($atype == "Developer" or $atype == "Trusted User")) { - $q = "UPDATE Packages "; - $q.= "SET CategoryID = ".intval($category_id)." "; - $q.= "WHERE ID = ".intval($pid); - db_query($q, $dbh); - return __("Package category changed."); - } else { - return __("You are not allowed to change this package category."); - } -} diff --git a/web/lib/pkgfuncs.inc.php b/web/lib/pkgfuncs.inc.php new file mode 100644 index 0000000..7d46541 --- /dev/null +++ b/web/lib/pkgfuncs.inc.php @@ -0,0 +1,1001 @@ + 0) { + return TRUE; + } + } + return FALSE; +} + +# Make sure this visitor can delete the requested package comment +# They can delete if they were the comment submitter, or if they are a TU/Dev +# +function canDeleteCommentArray($comment, $atype="", $uid=0) { + if ($atype == "Trusted User" || $atype == "Developer") { + # A TU/Dev can delete any comment + return TRUE; + } else if ($comment['UsersID'] == $uid) { + # User's own comment + return TRUE; + } + return FALSE; +} + +# see if this Users.ID can manage the package +# +function canManagePackage($uid=0,$AURMUID=0, $MUID=0, $SUID=0, $managed=0) { + if (!$uid) {return 0;} + + # The uid of the TU/Dev that manages the package + # + if ($uid == $AURMUID) {return 1;} + + # If the package isn't maintained by a TU/Dev, is this the user-maintainer? + # + if ($uid == $MUID && !$managed) {return 1;} + + # If the package isn't maintained by a TU/Dev, is this the user-submitter? + # + if ($uid == $SUID && !$managed) {return 1;} + + # otherwise, no right to manage this package + # + return 0; +} + +# Check if the current user can submit blacklisted packages. +# +function canSubmitBlacklisted($atype = "") { + if ($atype == "Trusted User" || $atype == "Developer") { + # Only TUs/Devs can submit blacklisted packages. + return TRUE; + } + else { + return FALSE; + } +} + +# grab the current list of PackageCategories +# +function pkgCategories() { + $cats = array(); + $dbh = db_connect(); + $q = "SELECT * FROM PackageCategories WHERE ID != 1 "; + $q.= "ORDER BY Category ASC"; + $result = db_query($q, $dbh); + if ($result) { + while ($row = mysql_fetch_row($result)) { + $cats[$row[0]] = $row[1]; + } + } + return $cats; +} + +# check to see if the package name exists +# +function package_exists($name="") { + if (!$name) {return NULL;} + $dbh = db_connect(); + $q = "SELECT ID FROM Packages "; + $q.= "WHERE Name = '".mysql_real_escape_string($name)."' "; + $result = db_query($q, $dbh); + if (!$result) {return NULL;} + $row = mysql_fetch_row($result); + return $row[0]; +} + +# grab package dependencies +# +function package_dependencies($pkgid=0) { + $deps = array(); + $pkgid = intval($pkgid); + if ($pkgid > 0) { + $dbh = db_connect(); + $q = "SELECT pd.DepName, pd.DepCondition, p.ID FROM PackageDepends pd "; + $q.= "LEFT JOIN Packages p ON pd.DepName = p.Name "; + $q.= "WHERE pd.PackageID = ". $pkgid . " "; + $q.= "ORDER BY pd.DepName"; + $result = db_query($q, $dbh); + if (!$result) {return array();} + while ($row = mysql_fetch_row($result)) { + $deps[] = $row; + } + } + return $deps; +} + +function package_required($name="") { + $deps = array(); + if ($name != "") { + $dbh = db_connect(); + $q = "SELECT p.Name, PackageID FROM PackageDepends pd "; + $q.= "JOIN Packages p ON pd.PackageID = p.ID "; + $q.= "WHERE DepName = '".mysql_real_escape_string($name)."' "; + $q.= "ORDER BY p.Name"; + $result = db_query($q, $dbh); + if (!$result) {return array();} + while ($row = mysql_fetch_row($result)) { + $deps[] = $row; + } + } + return $deps; +} + +# Return the number of comments for a specified package +function package_comments_count($pkgid = 0) { + $pkgid = intval($pkgid); + if ($pkgid > 0) { + $dbh = db_connect(); + $q = "SELECT COUNT(*) FROM PackageComments "; + $q.= "WHERE PackageID = " . $pkgid; + $q.= " AND DelUsersID IS NULL"; + } + $result = db_query($q, $dbh); + + if (!$result) { + return; + } + + return mysql_result($result, 0); +} + +# Return an array of package comments +function package_comments($pkgid = 0) { + $comments = array(); + $pkgid = intval($pkgid); + if ($pkgid > 0) { + $dbh = db_connect(); + $q = "SELECT PackageComments.ID, UserName, UsersID, Comments, CommentTS "; + $q.= "FROM PackageComments, Users "; + $q.= "WHERE PackageComments.UsersID = Users.ID"; + $q.= " AND PackageID = " . $pkgid; + $q.= " AND DelUsersID IS NULL"; # only display non-deleted comments + $q.= " ORDER BY CommentTS DESC"; + + if (!isset($_GET['comments'])) { + $q.= " LIMIT 10"; + } + + $result = db_query($q, $dbh); + + if (!$result) { + return; + } + + while ($row = mysql_fetch_assoc($result)) { + $comments[] = $row; + } + } + return $comments; +} + +# grab package sources +# +function package_sources($pkgid=0) { + $sources = array(); + $pkgid = intval($pkgid); + if ($pkgid > 0) { + $dbh = db_connect(); + $q = "SELECT Source FROM PackageSources "; + $q.= "WHERE PackageID = " . $pkgid; + $q.= " ORDER BY Source"; + $result = db_query($q, $dbh); + if (!$result) {return array();} + while ($row = mysql_fetch_row($result)) { + $sources[] = $row[0]; + } + } + return $sources; +} + + +# grab array of Package.IDs that I've voted for: $pkgs[1234] = 1, ... +# +function pkgvotes_from_sid($sid="") { + $pkgs = array(); + if (!$sid) {return $pkgs;} + $dbh = db_connect(); + $q = "SELECT PackageID "; + $q.= "FROM PackageVotes, Users, Sessions "; + $q.= "WHERE Users.ID = Sessions.UsersID "; + $q.= "AND Users.ID = PackageVotes.UsersID "; + $q.= "AND Sessions.SessionID = '".mysql_real_escape_string($sid)."'"; + $result = db_query($q, $dbh); + if ($result) { + while ($row = mysql_fetch_row($result)) { + $pkgs[$row[0]] = 1; + } + } + return $pkgs; +} + +# array of package ids that you're being notified for +# *yoink* +# +function pkgnotify_from_sid($sid="") { + $pkgs = array(); + if (!$sid) {return $pkgs;} + $dbh = db_connect(); + $q = "SELECT PkgID "; + $q.= "FROM CommentNotify, Users, Sessions "; + $q.= "WHERE Users.ID = Sessions.UsersID "; + $q.= "AND Users.ID = CommentNotify.UserID "; + $q.= "AND Sessions.SessionID = '".mysql_real_escape_string($sid)."'"; + $result = db_query($q, $dbh); + if ($result) { + while ($row = mysql_fetch_row($result)) { + $pkgs[$row[0]] = 1; + } + } + return $pkgs; +} + +# get name of package based on pkgid +# +function pkgname_from_id($pkgid=0) { + $pkgid = intval($pkgid); + $name = ""; + if ($pkgid > 0) { + $dbh = db_connect(); + $q = "SELECT Name FROM Packages WHERE ID = " . $pkgid; + $result = db_query($q, $dbh); + if (mysql_num_rows($result) > 0) { + $name = mysql_result($result, 0); + } + } + return $name; +} + +# Check if a package name is blacklisted. +# +function pkgname_is_blacklisted($name) { + $dbh = db_connect(); + $q = "SELECT COUNT(*) FROM PackageBlacklist WHERE Name = '" . mysql_real_escape_string($name) . "'"; + $result = db_query($q, $dbh); + + if (!$result) return false; + return (mysql_result($result, 0) > 0); +} + +# display package details +# +function package_details($id=0, $SID="") { + $atype = account_from_sid($SID); + $uid = uid_from_sid($SID); + + $q = "SELECT Packages.*,Category "; + $q.= "FROM Packages,PackageCategories "; + $q.= "WHERE Packages.CategoryID = PackageCategories.ID "; + $q.= "AND Packages.ID = " . intval($id); + $dbh = db_connect(); + $results = db_query($q, $dbh); + + if (!$results) { + print __("Error retrieving package details.") . "
\n"; + } + else { + $row = mysql_fetch_assoc($results); + if (empty($row)) { + print __("Package details could not be found.") . "
\n"; + + } + else { + include('pkg_details.php'); + + # Actions Bar + if ($SID) { + include('actions_form.php'); + include('pkg_comment_form.php'); + } + + # Print Comments + $comments = package_comments($id); + if (!empty($comments)) { + include('pkg_comments.php'); + } + } + } + return; +} + + +/* pkg_search_page(SID) + * outputs the body of search/search results page + * + * parameters: + * SID - current Session ID + * preconditions: + * package search page has been accessed + * request variables have not been sanitized + * + * request vars: + * O - starting result number + * PP - number of search hits per page + * C - package category ID number + * K - package search string + * SO - search hit sort order: + * values: a - ascending + * d - descending + * SB - sort search hits by: + * values: c - package category + * n - package name + * v - number of votes + * m - maintainer username + * SeB- property that search string (K) represents + * values: n - package name + * nd - package name & description + * x - package name (exact match) + * m - package maintainer's username + * s - package submitter's username + * do_Orphans - boolean. whether to search packages + * without a maintainer + * + * + * These two are actually handled in packages.php. + * + * IDs- integer array of ticked packages' IDs + * action - action to be taken on ticked packages + * values: do_Flag - Flag out-of-date + * do_UnFlag - Remove out-of-date flag + * do_Adopt - Adopt + * do_Disown - Disown + * do_Delete - Delete (requires confirm_Delete to be set) + * do_Notify - Enable notification + * do_UnNotify - Disable notification + */ +function pkg_search_page($SID="") { + // establish a db connection + $dbh = db_connect(); + + // get commonly used variables... + // TODO: REDUCE DB HITS. + // grab info for user if they're logged in + if ($SID) + $myuid = uid_from_sid($SID); + // get a list of package categories + $cats = pkgCategories(); //meow + + // sanitize paging variables + // + if (isset($_GET['O'])) { + $_GET['O'] = intval($_GET['O']); + if ($_GET['O'] < 0) + $_GET['O'] = 0; + } + else { + $_GET['O'] = 0; + } + + if (isset($_GET["PP"])) { + $_GET["PP"] = intval($_GET["PP"]); + if ($_GET["PP"] < 50) + $_GET["PP"] = 50; + else if ($_GET["PP"] > 250) + $_GET["PP"] = 250; + } + else { + $_GET["PP"] = 50; + } + + // FIXME: pull out DB-related code. all of it. + // this one's worth a choco-chip cookie, + // one of those nice big soft ones + + // build the package search query + // + $q_select = "SELECT "; + if ($SID) { + $q_select .= "CommentNotify.UserID AS Notify, + PackageVotes.UsersID AS Voted, "; + } + $q_select .= "Users.Username AS Maintainer, + PackageCategories.Category, + Packages.Name, Packages.Version, Packages.Description, Packages.NumVotes, + Packages.ID, Packages.OutOfDateTS "; + + $q_from = "FROM Packages + LEFT JOIN Users ON (Packages.MaintainerUID = Users.ID) + LEFT JOIN PackageCategories + ON (Packages.CategoryID = PackageCategories.ID) "; + if ($SID) { + # this portion is not needed for the total row count query + $q_from_extra = "LEFT JOIN PackageVotes + ON (Packages.ID = PackageVotes.PackageID AND PackageVotes.UsersID = $myuid) + LEFT JOIN CommentNotify + ON (Packages.ID = CommentNotify.PkgID AND CommentNotify.UserID = $myuid) "; + } else { + $q_from_extra = ""; + } + + $q_where = "WHERE 1 = 1 "; + // TODO: possibly do string matching on category + // to make request variable values more sensible + if (isset($_GET["C"]) && intval($_GET["C"])) { + $q_where .= "AND Packages.CategoryID = ".intval($_GET["C"])." "; + } + + if (isset($_GET['K'])) { + $_GET['K'] = mysql_real_escape_string(trim($_GET['K'])); + + # Search by maintainer + if (isset($_GET["SeB"]) && $_GET["SeB"] == "m") { + $q_where .= "AND Users.Username = '".$_GET['K']."' "; + } + # Search by submitter + elseif (isset($_GET["SeB"]) && $_GET["SeB"] == "s") { + $q_where .= "AND SubmitterUID = ".uid_from_username($_GET['K'])." "; + } + # Search by name + elseif (isset($_GET["SeB"]) && $_GET["SeB"] == "n") { + $q_where .= "AND (Name LIKE '%".$_GET['K']."%') "; + } + # Search by name (exact match) + elseif (isset($_GET["SeB"]) && $_GET["SeB"] == "x") { + $q_where .= "AND (Name = '".$_GET['K']."') "; + } + # Search by name and description (Default) + else { + $q_where .= "AND (Name LIKE '%".$_GET['K']."%' OR "; + $q_where .= "Description LIKE '%".$_GET['K']."%') "; + } + } + + if (isset($_GET["do_Orphans"])) { + $q_where .= "AND MaintainerUID IS NULL "; + } + + if (isset($_GET['outdated'])) { + if ($_GET['outdated'] == 'on') { + $q_where .= "AND OutOfDateTS IS NOT NULL "; + } + elseif ($_GET['outdated'] == 'off') { + $q_where .= "AND OutOfDateTS IS NULL "; + } + } + + $order = (isset($_GET["SO"]) && $_GET["SO"] == 'd') ? 'DESC' : 'ASC'; + + $q_sort = "ORDER BY Name ".$order.", CategoryID DESC "; + $sort_by = isset($_GET["SB"]) ? $_GET["SB"] : ''; + switch ($sort_by) { + case 'c': + $q_sort = "ORDER BY CategoryID ".$order.", Name ASC "; + break; + case 'v': + $q_sort = "ORDER BY NumVotes ".$order.", Name ASC, CategoryID DESC "; + break; + case 'w': + if ($SID) { + $q_sort = "ORDER BY Voted ".$order.", Name ASC, CategoryID DESC "; + } + break; + case 'o': + if ($SID) { + $q_sort = "ORDER BY Notify ".$order.", Name ASC, CategoryID DESC "; + } + break; + case 'm': + $q_sort = "ORDER BY Maintainer ".$order.", Name ASC "; + break; + case 'a': + $q_sort = "ORDER BY ModifiedTS ".$order.", Name ASC "; + break; + default: + break; + } + + $q_limit = "LIMIT ".$_GET["PP"]." OFFSET ".$_GET["O"]; + + $q = $q_select . $q_from . $q_from_extra . $q_where . $q_sort . $q_limit; + $q_total = "SELECT COUNT(*) " . $q_from . $q_where; + + $result = db_query($q, $dbh); + $result_t = db_query($q_total, $dbh); + if ($result_t) { + $total = mysql_result($result_t, 0); + } + else { + $total = 0; + } + + if ($result && $total > 0) { + if (isset($_GET["SO"]) && $_GET["SO"] == "d"){ + $SO_next = "a"; + } + else { + $SO_next = "d"; + } + } + + // figure out the results to use + $first = $_GET['O'] + 1; + + if (($_GET['PP'] + $_GET['O']) > $total) { + $last = $total; + } else { + $last = $_GET['PP'] + $_GET['O']; + } + + + if ($total > 1 || $total == 0) { + # calculation of pagination links + $per_page = ($_GET['PP'] > 0) ? $_GET['PP'] : 50; + $current = ceil($first / $per_page); + $pages = ceil($total / $per_page); + $templ_pages = array(); + + if ($current > 1) { + $templ_pages[__('First')] = 0; + $templ_pages[__('Previous')] = ($current - 2) * $per_page; + } + + if ($current - 5 > 1) + $templ_pages["..."] = false; + + for ($i = max($current - 5, 1); $i <= min($pages, $current + 5); $i++) { + $templ_pages[$i] = ($i - 1) * $per_page; + } + + if ($current + 5 < $pages) + $templ_pages["... "] = false; + + if ($current < $pages) { + $templ_pages[__('Next')] = $current * $per_page; + $templ_pages[__('Last')] = ($pages - 1) * $per_page; + } + + include('pkg_search_form.php'); + include('pkg_search_results.php'); + } + else { + $pkgdetails = mysql_fetch_assoc($result); + header("Location: packages.php?ID={$pkgdetails['ID']}"); + } + + return; +} + +function current_action($action) { + return (isset($_POST['action']) && $_POST['action'] == $action) || + isset($_POST[$action]); +} + +/** + * Ensure an array of IDs is in fact all valid integers. + */ +function sanitize_ids($ids) { + $new_ids = array(); + foreach ($ids as $id) { + $id = intval($id); + if ($id > 0) { + $new_ids[] = $id; + } + } + return $new_ids; +} + +/** + * Flag and un-flag packages out-of-date + * + * @param string $atype Account type, output of account_from_sid + * @param array $ids Array of package IDs to flag/unflag + * @param boolean $action True flags out-of-date, false un-flags. Flags by + * default + * + * @return string Translated success or error messages + */ +function pkg_flag ($atype, $ids, $action = True) { + if (!$atype) { + if ($action) { + return __("You must be logged in before you can flag packages."); + } else { + return __("You must be logged in before you can unflag packages."); + } + } + + $ids = sanitize_ids($ids); + if (empty($ids)) { + if ($action) { + return __("You did not select any packages to flag."); + } else { + return __("You did not select any packages to unflag."); + } + } + + $dbh = db_connect(); + + $q = "UPDATE Packages SET"; + if ($action) { + $q.= " OutOfDateTS = UNIX_TIMESTAMP()"; + } + else { + $q.= " OutOfDateTS = NULL"; + } + $q.= " WHERE ID IN (" . implode(",", $ids) . ")"; + + db_query($q, $dbh); + + if ($action) { + # Notify of flagging by email + $f_name = username_from_sid($_COOKIE['AURSID']); + $f_email = email_from_sid($_COOKIE['AURSID']); + $f_uid = uid_from_sid($_COOKIE['AURSID']); + $q = "SELECT Packages.Name, Users.Email, Packages.ID "; + $q.= "FROM Packages, Users "; + $q.= "WHERE Packages.ID IN (" . implode(",", $ids) .") "; + $q.= "AND Users.ID = Packages.MaintainerUID "; + $q.= "AND Users.ID != " . $f_uid; + $result = db_query($q, $dbh); + if (mysql_num_rows($result)) { + while ($row = mysql_fetch_assoc($result)) { + # construct email + $body = "Your package " . $row['Name'] . " has been flagged out of date by " . $f_name . " [1]. You may view your package at:\nhttps://aur.archlinux.org/packages.php?ID=" . $row['ID'] . "\n\n[1] - https://aur.archlinux.org/account.php?Action=AccountInfo&ID=" . $f_uid; + $body = wordwrap($body, 70); + $headers = "Reply-to: nobody@archlinux.org\nFrom:aur-notify@archlinux.org\nX-Mailer: PHP\nX-MimeOLE: Produced By AUR\n"; + @mail($row['Email'], "AUR Out-of-date Notification for ".$row['Name'], $body, $headers); + } + } + } + + if ($action) { + return __("The selected packages have been flagged out-of-date."); + } else { + return __("The selected packages have been unflagged."); + } +} + +/** + * Delete packages + * + * @param string $atype Account type, output of account_from_sid + * @param array $ids Array of package IDs to delete + * + * @return string Translated error or success message + */ +function pkg_delete ($atype, $ids) { + if (!$atype) { + return __("You must be logged in before you can delete packages."); + } + + # If they're a TU or dev, can delete + if ($atype != "Trusted User" && $atype != "Developer") { + return __("You do have permission to delete packages."); + } + + $ids = sanitize_ids($ids); + if (empty($ids)) { + return __("You did not select any packages to delete."); + } + + $dbh = db_connect(); + $q = "DELETE FROM Packages WHERE ID IN (" . implode(",", $ids) . ")"; + $result = db_query($q, $dbh); + + return __("The selected packages have been deleted."); +} + +/** + * Adopt or disown packages + * + * @param string $atype Account type, output of account_from_sid + * @param array $ids Array of package IDs to adopt/disown + * @param boolean $action Adopts if true, disowns if false. Adopts by default + * + * @return string Translated error or success message + */ +function pkg_adopt ($atype, $ids, $action = True) { + if (!$atype) { + if ($action) { + return __("You must be logged in before you can adopt packages."); + } else { + return __("You must be logged in before you can disown packages."); + } + } + + $ids = sanitize_ids($ids); + if (empty($ids)) { + if ($action) { + return __("You did not select any packages to adopt."); + } else { + return __("You did not select any packages to disown."); + } + } + + $dbh = db_connect(); + + $field = "MaintainerUID"; + $q = "UPDATE Packages "; + + if ($action) { + $user = uid_from_sid($_COOKIE["AURSID"]); + } else { + $user = 'NULL'; + } + + $q.= "SET $field = $user "; + $q.= "WHERE ID IN (" . implode(",", $ids) . ") "; + + if ($action && $atype == "User") { + # Regular users may only adopt orphan packages from unsupported + $q.= "AND $field IS NULL "; + } else if ($atype == "User") { + $q.= "AND $field = " . uid_from_sid($_COOKIE["AURSID"]); + } + + db_query($q, $dbh); + + if ($action) { + pkg_notify(account_from_sid($_COOKIE["AURSID"]), $ids); + return __("The selected packages have been adopted."); + } else { + return __("The selected packages have been disowned."); + } +} + +/** + * Vote and un-vote for packages + * + * @param string $atype Account type, output of account_from_sid + * @param array $ids Array of package IDs to vote/un-vote + * @param boolean $action Votes if true, un-votes if false. Votes by default + * + * @return string Translated error or success message + */ +function pkg_vote ($atype, $ids, $action = True) { + if (!$atype) { + if ($action) { + return __("You must be logged in before you can vote for packages."); + } else { + return __("You must be logged in before you can un-vote for packages."); + } + } + + $ids = sanitize_ids($ids); + if (empty($ids)) { + if ($action) { + return __("You did not select any packages to vote for."); + } else { + return __("Your votes have been removed from the selected packages."); + } + } + + $dbh = db_connect(); + $my_votes = pkgvotes_from_sid($_COOKIE["AURSID"]); + $uid = uid_from_sid($_COOKIE["AURSID"]); + + $first = 1; + foreach ($ids as $pid) { + if ($action) { + $check = !isset($my_votes[$pid]); + } else { + $check = isset($my_votes[$pid]); + } + + if ($check) { + if ($first) { + $first = 0; + $vote_ids = $pid; + if ($action) { + $vote_clauses = "($uid, $pid)"; + } + } else { + $vote_ids .= ", $pid"; + if ($action) { + $vote_clauses .= ", ($uid, $pid)"; + } + } + } + } + + # only vote for packages the user hasn't already voted for + # + $op = $action ? "+" : "-"; + $q = "UPDATE Packages SET NumVotes = NumVotes $op 1 "; + $q.= "WHERE ID IN ($vote_ids)"; + + db_query($q, $dbh); + + if ($action) { + $q = "INSERT INTO PackageVotes (UsersID, PackageID) VALUES "; + $q.= $vote_clauses; + } else { + $q = "DELETE FROM PackageVotes WHERE UsersID = $uid "; + $q.= "AND PackageID IN ($vote_ids)"; + } + + db_query($q, $dbh); + + if ($action) { + $q = "UPDATE Users SET LastVoted = UNIX_TIMESTAMP() "; + $q.= "WHERE ID = $uid"; + + db_query($q, $dbh); + } + + if ($action) { + return __("Your votes have been cast for the selected packages."); + } else { + return __("Your votes have been removed from the selected packages."); + } +} + +/** + * Toggle notification of packages + * + * @param string $atype Account type, output of account_from_sid + * @param array $ids Array of package IDs to toggle, formatted as $package_id + * @return string Translated error or success message + */ +function pkg_notify ($atype, $ids, $action = True) { + if (!$atype) { +# return __("You must be logged in before you can get notifications on comments."); + return; + } + + $ids = sanitize_ids($ids); + if (empty($ids)) { + return __("Couldn't add to notification list."); + } + + $dbh = db_connect(); + $uid = uid_from_sid($_COOKIE["AURSID"]); + + $output = ""; + + $first = True; + + # There currently shouldn't be multiple requests here, but the + # format in which it's sent requires this. + foreach ($ids as $pid) { + $q = "SELECT Name FROM Packages WHERE ID = $pid"; + $result = db_query($q, $dbh); + if ($result) { + $pkgname = mysql_result($result , 0); + } + else { + $pkgname = ''; + } + + if ($first) + $first = False; + else + $output .= ", "; + + + if ($action) { + $q = "SELECT * FROM CommentNotify WHERE UserID = $uid"; + $q .= " AND PkgID = $pid"; + + # Notification already added. Don't add again. + $result = db_query($q, $dbh); + if (!mysql_num_rows($result)) { + $q = "INSERT INTO CommentNotify (PkgID, UserID) VALUES ($pid, $uid)"; + db_query($q, $dbh); + } + + $output .= $pkgname; + } + else { + $q = "DELETE FROM CommentNotify WHERE PkgID = $pid"; + $q .= " AND UserID = $uid"; + db_query($q, $dbh); + + $output .= $pkgname; + } + } + + if ($action) { + $output = __("You have been added to the comment notification list for %s.", $output); + } + else { + $output = __("You have been removed from the comment notification list for %s.", $output); + } + + return $output; +} + + + +/** + * Delete comment + * + * @param string $atype Account type, output of account_from_sid + * @return string Translated error or success message + */ +function pkg_delete_comment($atype) { + if (!$atype) { + return __("You must be logged in before you can edit package information."); + } + + # Get ID of comment to be removed + if (isset($_POST["comment_id"])) { + $comment_id = $_POST["comment_id"]; + } else { + return __("Missing comment ID."); + } + + $uid = uid_from_sid($_COOKIE["AURSID"]); + if (canDeleteComment($comment_id, $atype, $uid)) { + + $dbh = db_connect(); + $q = "UPDATE PackageComments "; + $q.= "SET DelUsersID = ".$uid." "; + $q.= "WHERE ID = ".intval($comment_id); + db_query($q, $dbh); + return __("Comment has been deleted."); + } else { + return __("You are not allowed to delete this comment."); + } +} + +/** + * Change package category + * + * @param string $atype Account type, output of account_from_sid + * @return string Translated error or success message + */ +function pkg_change_category($atype) { + if (!$atype) { + return __("You must be logged in before you can edit package information."); + } + + # Get ID of the new category + if (isset($_POST["category_id"])) { + $category_id = $_POST["category_id"]; + } else { + return __("Missing category ID."); + } + + $catArray = pkgCategories(); + if (!array_key_exists($category_id, $catArray)) { + return __("Invalid category ID."); + } + + if (isset($_GET["ID"])) { + $pid = $_GET["ID"]; + } else { + return __("Missing package ID."); + } + + # Verify package ownership + $dbh = db_connect(); + $q = "SELECT Packages.MaintainerUID "; + $q.= "FROM Packages "; + $q.= "WHERE Packages.ID = ".$pid; + $result = db_query($q, $dbh); + if ($result) { + $pkg = mysql_fetch_assoc($result); + } + else { + return __("You are not allowed to change this package category."); + } + + $uid = uid_from_sid($_COOKIE["AURSID"]); + if ($uid == $pkg["MaintainerUID"] or + ($atype == "Developer" or $atype == "Trusted User")) { + $q = "UPDATE Packages "; + $q.= "SET CategoryID = ".intval($category_id)." "; + $q.= "WHERE ID = ".intval($pid); + db_query($q, $dbh); + return __("Package category changed."); + } else { + return __("You are not allowed to change this package category."); + } +} diff --git a/web/lib/stats.inc b/web/lib/stats.inc deleted file mode 100644 index 67fbdca..0000000 --- a/web/lib/stats.inc +++ /dev/null @@ -1,71 +0,0 @@ -append($row); - } - set_cache_value($key, $newest_packages); - } - include('stats/updates_table.php'); -} - -function user_table($user, $dbh) -{ - $escuser = mysql_real_escape_string($user); - $base_q = "SELECT count(*) FROM Packages,Users WHERE Packages.MaintainerUID = Users.ID AND Users.Username='" . $escuser . "'"; - - $maintainer_unsupported_count = db_cache_value($base_q, $dbh, - 'user_unsupported_count:' . $escuser); - - $q = "SELECT count(*) FROM Packages,Users WHERE Packages.OutOfDateTS IS NOT NULL AND Packages.MaintainerUID = Users.ID AND Users.Username='" . $escuser . "'"; - - $flagged_outdated = db_cache_value($q, $dbh, - 'user_flagged_outdated:' . $escuser); - - # If the user is a TU calculate the number of the packages - $atype = account_from_sid($_COOKIE["AURSID"]); - - include('stats/user_table.php'); -} - -function general_stats_table($dbh) -{ - # AUR statistics - $q = "SELECT count(*) FROM Packages"; - $unsupported_count = db_cache_value($q, $dbh, 'unsupported_count'); - - $q = "SELECT count(*) FROM Packages WHERE MaintainerUID IS NULL"; - $orphan_count = db_cache_value($q, $dbh, 'orphan_count'); - - $q = "SELECT count(*) FROM Users"; - $user_count = db_cache_value($q, $dbh, 'user_count'); - - $q = "SELECT count(*) FROM Users,AccountTypes WHERE Users.AccountTypeID = AccountTypes.ID AND AccountTypes.AccountType = 'Trusted User'"; - $tu_count = db_cache_value($q, $dbh, 'tu_count'); - - $targstamp = intval(strtotime("-7 days")); - $yearstamp = intval(strtotime("-1 year")); - - $q = "SELECT count(*) FROM Packages WHERE Packages.ModifiedTS >= $targstamp AND Packages.ModifiedTS = Packages.SubmittedTS"; - $add_count = db_cache_value($q, $dbh, 'add_count'); - - $q = "SELECT count(*) FROM Packages WHERE Packages.ModifiedTS >= $targstamp AND Packages.ModifiedTS != Packages.SubmittedTS"; - $update_count = db_cache_value($q, $dbh, 'update_count'); - - $q = "SELECT count(*) FROM Packages WHERE Packages.ModifiedTS >= $yearstamp AND Packages.ModifiedTS != Packages.SubmittedTS"; - $update_year_count = db_cache_value($q, $dbh, 'update_year_count'); - - $q = "SELECT count(*) FROM Packages WHERE Packages.ModifiedTS = Packages.SubmittedTS"; - $never_update_count = db_cache_value($q, $dbh, 'never_update_count'); - - include('stats/general_stats_table.php'); -} diff --git a/web/lib/stats.inc.php b/web/lib/stats.inc.php new file mode 100644 index 0000000..2690a5c --- /dev/null +++ b/web/lib/stats.inc.php @@ -0,0 +1,71 @@ +append($row); + } + set_cache_value($key, $newest_packages); + } + include('stats/updates_table.php'); +} + +function user_table($user, $dbh) +{ + $escuser = mysql_real_escape_string($user); + $base_q = "SELECT count(*) FROM Packages,Users WHERE Packages.MaintainerUID = Users.ID AND Users.Username='" . $escuser . "'"; + + $maintainer_unsupported_count = db_cache_value($base_q, $dbh, + 'user_unsupported_count:' . $escuser); + + $q = "SELECT count(*) FROM Packages,Users WHERE Packages.OutOfDateTS IS NOT NULL AND Packages.MaintainerUID = Users.ID AND Users.Username='" . $escuser . "'"; + + $flagged_outdated = db_cache_value($q, $dbh, + 'user_flagged_outdated:' . $escuser); + + # If the user is a TU calculate the number of the packages + $atype = account_from_sid($_COOKIE["AURSID"]); + + include('stats/user_table.php'); +} + +function general_stats_table($dbh) +{ + # AUR statistics + $q = "SELECT count(*) FROM Packages"; + $unsupported_count = db_cache_value($q, $dbh, 'unsupported_count'); + + $q = "SELECT count(*) FROM Packages WHERE MaintainerUID IS NULL"; + $orphan_count = db_cache_value($q, $dbh, 'orphan_count'); + + $q = "SELECT count(*) FROM Users"; + $user_count = db_cache_value($q, $dbh, 'user_count'); + + $q = "SELECT count(*) FROM Users,AccountTypes WHERE Users.AccountTypeID = AccountTypes.ID AND AccountTypes.AccountType = 'Trusted User'"; + $tu_count = db_cache_value($q, $dbh, 'tu_count'); + + $targstamp = intval(strtotime("-7 days")); + $yearstamp = intval(strtotime("-1 year")); + + $q = "SELECT count(*) FROM Packages WHERE Packages.ModifiedTS >= $targstamp AND Packages.ModifiedTS = Packages.SubmittedTS"; + $add_count = db_cache_value($q, $dbh, 'add_count'); + + $q = "SELECT count(*) FROM Packages WHERE Packages.ModifiedTS >= $targstamp AND Packages.ModifiedTS != Packages.SubmittedTS"; + $update_count = db_cache_value($q, $dbh, 'update_count'); + + $q = "SELECT count(*) FROM Packages WHERE Packages.ModifiedTS >= $yearstamp AND Packages.ModifiedTS != Packages.SubmittedTS"; + $update_year_count = db_cache_value($q, $dbh, 'update_year_count'); + + $q = "SELECT count(*) FROM Packages WHERE Packages.ModifiedTS = Packages.SubmittedTS"; + $never_update_count = db_cache_value($q, $dbh, 'never_update_count'); + + include('stats/general_stats_table.php'); +} diff --git a/web/lib/translator.inc b/web/lib/translator.inc deleted file mode 100644 index 903b061..0000000 --- a/web/lib/translator.inc +++ /dev/null @@ -1,50 +0,0 @@ -", ""); - -include_once('config.inc'); -include_once('gettext.php'); -include_once('streams.php'); - -global $streamer, $l10n; - -function __() { - global $LANG; - global $l10n; - - # Create the translation. - $args = func_get_args(); - - # First argument is always string to be translated - $tag = $args[0]; - - # Translate using gettext_reader initialized before. - $translated = $l10n->translate($tag); - $translated = htmlspecialchars($translated, ENT_QUOTES); - - $num_args = sizeof($args); - - # Subsequent arguments are strings to be formatted - # - # TODO: make this more robust. - # '%%' should translate to a literal '%' - - if ( $num_args > 1 ) { - for ($i = 1; $i < $num_args; $i++) { - $translated = preg_replace("/\%[sh]/", $args[$i], $translated, 1); - } - } - - return $translated; -} - diff --git a/web/lib/translator.inc.php b/web/lib/translator.inc.php new file mode 100644 index 0000000..44c87bd --- /dev/null +++ b/web/lib/translator.inc.php @@ -0,0 +1,50 @@ +", ""); + +include_once('config.inc.php'); +include_once('gettext.php'); +include_once('streams.php'); + +global $streamer, $l10n; + +function __() { + global $LANG; + global $l10n; + + # Create the translation. + $args = func_get_args(); + + # First argument is always string to be translated + $tag = $args[0]; + + # Translate using gettext_reader initialized before. + $translated = $l10n->translate($tag); + $translated = htmlspecialchars($translated, ENT_QUOTES); + + $num_args = sizeof($args); + + # Subsequent arguments are strings to be formatted + # + # TODO: make this more robust. + # '%%' should translate to a literal '%' + + if ( $num_args > 1 ) { + for ($i = 1; $i < $num_args; $i++) { + $translated = preg_replace("/\%[sh]/", $args[$i], $translated, 1); + } + } + + return $translated; +} + diff --git a/web/lib/version.inc b/web/lib/version.inc deleted file mode 100644 index 04238d9..0000000 --- a/web/lib/version.inc +++ /dev/null @@ -1,3 +0,0 @@ -