diff --git a/html/inc/boinc_db.inc b/html/inc/boinc_db.inc index 7231d36377..5d299efcd3 100644 --- a/html/inc/boinc_db.inc +++ b/html/inc/boinc_db.inc @@ -464,6 +464,14 @@ class BoincProfile { $db = BoincDb::get(); return $db->lookup('profile', 'BoincProfile', $clause); } + static function lookup_userid($userid) { + $db = BoincDb::get(); + return $db->lookup('profile', 'BoincProfile', 'userid='.$userid); + } + function update($clause) { + $db = BoincDb::get(); + return $db->update_aux('profile', $clause.' where userid='.$this->userid); + } static function update_aux($clause) { $db = BoincDb::get(); return $db->update_aux('profile', $clause); @@ -480,6 +488,10 @@ class BoincProfile { $db = BoincDb::get(); return $db->enum_fields('profile', 'BoincProfile', $fields, $where_clause, $order_clause); } + function delete() { + $db = BoincDb::get(); + return $db->delete_aux('profile', 'userid='.$this->userid); + } static function delete_aux($clause) { $db = BoincDb::get(); return $db->delete_aux('profile', $clause); diff --git a/html/inc/db_conn.inc b/html/inc/db_conn.inc index 852a9160d5..b7fe126539 100644 --- a/html/inc/db_conn.inc +++ b/html/inc/db_conn.inc @@ -242,6 +242,13 @@ class DbConn { return mysql_error($this->db_conn); } } + function base_errno() { + if (MYSQLI) { + return $this->db_conn->errno; + } else { + return mysql_errno($this->db_conn); + } + } function table_exists($table_name) { $result = $this->do_query("show tables from DBNAME like '$table_name'"); if (!$result) error_page("database error on query $query"); diff --git a/html/inc/uotd.inc b/html/inc/uotd.inc index bf0d83bb44..00e9ab3e56 100644 --- a/html/inc/uotd.inc +++ b/html/inc/uotd.inc @@ -1,7 +1,7 @@ 0", "ORDER BY uotd_time DESC LIMIT 1"); if (sizeof($profiles)) { return $profiles[0]; } @@ -56,10 +56,10 @@ function get_current_uotd() { // Select a (possibly new) UOTD // -function select_uotd() { +function select_uotd($force_new = false) { echo gmdate("F d Y", time())." UTC: Starting\n"; $current_uotd = get_current_uotd(); - if ($current_uotd) { + if ($current_uotd && !$force_new) { $assigned = getdate($current_uotd->uotd_time); $now = getdate(time()); if ($assigned['mday'] == $now['mday']) { @@ -69,60 +69,82 @@ function select_uotd() { exit(); } } + if ($force_new) { + echo "Forcing new UOTD\n"; + } // get a list of profiles that have been 'approved' for UOTD, // using a project-specific query if supplied in project.inc // if (function_exists('uotd_candidates_query')) { $query = uotd_candidates_query(); + echo "using project supplied candidates_query\n"; } else { $query = default_uotd_candidates_query(); + echo "using default candidates_query\n"; } - $result = _mysql_query($query); + $db = BoincDb::get(); + $result = $db->do_query($query); // If the number of approved profiles dips below a threshold, // email the sys admin every time we pick a new one. // if (defined('UOTD_ADMIN_EMAIL') && $result - && _mysql_num_rows($result) < UOTD_THRESHOLD + && $result->num_rows < UOTD_THRESHOLD ) { + echo "approved candidates for UOTD under UOTD_THRESHOLD\n"; $u = new BoincUser; $u->email_addr = UOTD_ADMIN_EMAIL; $u->name = "UOTD admin"; send_email($u, PROJECT . ": User of the Day pool is running low!", "The pool of approved candidates for User of the Day has". - " reached your assigned threshold: there are now only " . _mysql_num_rows($result) . " approved users.\n\n". + " reached your assigned threshold: there are now only " . $result->num_rows . " approved users.\n\n". "To approve more candidates for User of the Day,". " go to the " . PROJECT . " administration page and click \"Screen user profiles\"" ); } - if ($result && _mysql_num_rows($result) == 0) { + if ($result && $result->num_rows == 0) { + echo "no new verified profile found, selecting old UOTD that was shown least recently\n"; + $result->free(); // If all verified profiles have been selected as UOTD, - // reshow the one that was shown least recently. + // reshow a random one of the 100 least recently shown profiles. // - $result = _mysql_query("SELECT * FROM profile,user WHERE profile.userid=user.id AND verification=1 ORDER BY uotd_time ASC LIMIT 1"); + $inner = "SELECT profile.userid FROM profile,user WHERE profile.userid=user.id AND verification=1 AND uotd_time>0 ORDER BY uotd_time ASC LIMIT 100"; + $result = $db->do_query("SELECT * from ($inner) ORDER BY RAND() LIMIT 1"); } - if (!$result || _mysql_num_rows($result) == 0) { + if (!$result || $result->num_rows == 0) { // No valid users of the day - do something. echo "No screened users found\n"; exit(); } - $profile = _mysql_fetch_object($result); - $user = BoincUser::lookup_id($profile->userid); + $candidate = $result->fetch_object(); + $result->free(); - // if profile is "orphaned", delete it and try again + // depending on the candidates query the profile must not exist // - if (!$user) { - $profile->delete_aux("userid=$profile->userid"); - select_uotd(); + $profile = BoincProfile::lookup_userid($candidate->userid); + if (!$profile) { + echo "Could not find profile returned from candidates query.\n"; + exit(); } - $sql = "UPDATE profile SET uotd_time = ".time()." WHERE userid=$user->id"; - _mysql_query($sql); + // "orphaned" profiles can only be detected if the candidate query doesn't join profile and user table + // if this happens, delete the profile and try again + // + $user = BoincUser::lookup_id($candidate->userid); + if (!$user) { + echo "Profile for user $candidate->userid is orphaned and will be deleted\n"; + $profile->delete(); + select_uotd($force_new); + exit(); + } + + $profile->uotd_time = time(); + $profile->update("uotd_time = ".time()); send_email($user, "You're the " . PROJECT . " user of the day!", @@ -131,7 +153,7 @@ function select_uotd() { Your profile will be featured on the " . PROJECT . " website for the next 24 hours." ); echo "Chose user $user->id as UOTD\n"; - $profile->uotd_time = time(); + generate_uotd_gadget($profile, $user); } @@ -143,7 +165,7 @@ function default_uotd_candidates_query(){ $query = "SELECT * FROM profile,user WHERE profile.userid=user.id "; $query .= " AND verification=1 "; $query .= " AND expavg_credit>1 "; - $query .= " AND uotd_time IS NULL "; + $query .= " AND (uotd_time IS NULL or uotd_time=0) "; $query .= "ORDER BY RAND()"; return $query; } @@ -159,11 +181,12 @@ function count_uotd_candidates(){ $query = default_uotd_candidates_query(); } - $result = _mysql_query($query); + $db = BoincDb::get(); + $result = $db->do_query($query); if($result) { - $n = _mysql_num_rows($result); + $n = $result->num_rows; } - _mysql_free_result($result); + $result->free(); return $n; } diff --git a/html/ops/profile_screen_form.php b/html/ops/profile_screen_form.php index 8213d02c30..ff0cb6d50b 100644 --- a/html/ops/profile_screen_form.php +++ b/html/ops/profile_screen_form.php @@ -46,7 +46,7 @@ if (function_exists('profile_screen_query')) { $query = "select * from profile, user where profile.userid=user.id " ." and has_picture>0 " ." and verification=0 " - ." and uotd_time is null " + ." and (uotd_time is null or uotd_time=0) " ." and expavg_credit>1 " ." and (response1 <> '' or response2 <> '') " ." order by recommend desc limit 20" diff --git a/html/ops/update_uotd.php b/html/ops/update_uotd.php index aafec6e69b..611285847f 100755 --- a/html/ops/update_uotd.php +++ b/html/ops/update_uotd.php @@ -3,7 +3,7 @@ 1) { + if ($argv[1] == "-f" || $argv[1] == "--force") { + $force_new = true; + } else { + echo "Usage: ".$argv[0]." [-f|--force]\n"; + echo " -f | --force Will select a new User of the day regardless if there already is one for the current day\n"; + exit(1); + } +} -select_uotd(); +select_uotd($force_new); ?>