<?php require_once($INC . "/util.inc.php"); require_once($INC . "/log.inc.php"); require_once($INC . "/sql.inc.php"); require_once($INC . "/user.inc.php"); require_once($INC . "/prof.inc.php"); $rg_watch_error = ""; function rg_watch_set_error($str) { global $rg_watch_error; $rg_watch_error = $str; rg_log('Set error to ' . $str); } function rg_watch_error() { global $rg_watch_error; return $rg_watch_error; } /* * Returns a watched entry */ function rg_watch_load($db, $type, $uid, $obj_id1, $obj_id2) { rg_prof_start("watch_load"); rg_log_enter("watch_load: type=$type uid=$uid obj_id=$obj_id1/$obj_id2"); $ret = FALSE; while (1) { $key = 'watch' . '::' . $type . '::' . $uid . '::' . $obj_id1 . '::' . $obj_id2; $c = rg_cache_get($key); if ($c !== FALSE) { $ret = $c; break; } $params = array( 'uid' => $uid, 'obj_id1' => $obj_id1, 'obj_id2' => $obj_id2); if (strcmp($type, "bug") == 0) { $sql = "SELECT 1 FROM watch_bug" . " WHERE uid = @@uid@@" . " AND repo_id = @@obj_id1@@" . " AND bug_id = @@obj_id2@@"; } else if (strcmp($type, "repo") == 0) { $sql = "SELECT 1 FROM watch_repo" . " WHERE uid = @@uid@@" . " AND repo_id = @@obj_id1@@"; } else if (strcmp($type, "user") == 0) { $sql = "SELECT 1 FROM watch_user" . " WHERE uid = @@uid@@" . " AND watch_uid = @@obj_id1@@"; } else { rg_internal_error("Invalid watch type!"); break; } $res = rg_sql_query_params($db, $sql, $params); if ($res === FALSE) { rg_watch_set_error('cannot get data from db'); break; } $rows = rg_sql_num_rows($res); rg_sql_free_result($res); $ret = $rows > 0 ? 1 : 0; rg_cache_set($key, $ret, RG_SOCKET_NO_WAIT); break; } rg_log_exit(); rg_prof_end("watch_load"); return $ret; } /* * Add somebody to the watch list */ function rg_watch_add($db, $type, $login_uid, $obj_id1, $obj_id2) { global $rg_watch_add_state; rg_prof_start("watch_add"); rg_log_enter("watch_add type=$type, login_uid=$login_uid" . " obj_id=$obj_id1/$obj_id2"); $ret = FALSE; while (1) { $r = rg_watch_load($db, $type, $login_uid, $obj_id1, $obj_id2); if ($r === FALSE) break; if ($r === 1) { // already in watch list $ret = TRUE; break; } $params = array("uid" => $login_uid, "obj_id1" => $obj_id1, "obj_id2" => $obj_id2); if (strcmp($type, "bug") == 0) { $sql = "INSERT INTO watch_bug (uid, repo_id, bug_id)" . " VALUES (@@uid@@, @@obj_id1@@, @@obj_id2@@)"; } else if (strcmp($type, "repo") == 0) { $sql = "INSERT INTO watch_repo (uid, repo_id)" . " VALUES (@@uid@@, @@obj_id1@@)"; } else if (strcmp($type, "user") == 0) { $sql = "INSERT INTO watch_user (uid, watch_uid)" . " VALUES (@@uid@@, @@obj_id1@@)"; } else { rg_internal_error("Invalid watch type!"); break; } $res = rg_sql_query_params($db, $sql, $params); if ($res === FALSE) { rg_watch_set_error('cannot insert data in db'); break; } rg_sql_free_result($res); $key = 'watch' . '::' . $type . '::' . $login_uid . '::' . $obj_id1 . '::' . $obj_id2; rg_cache_set($key, 1, RG_SOCKET_NO_WAIT); $ret = TRUE; break; } rg_log_exit(); rg_prof_end("watch_add"); return $ret; } /* * Delete somebody from the watch list */ function rg_watch_del($db, $type, $login_uid, $obj_id1, $obj_id2) { rg_prof_start("watch_del"); rg_log_enter("watch_del type=$type, login_uid=$login_uid" . " obj_id=$obj_id1/$obj_id2"); $ret = FALSE; while (1) { $r = rg_watch_load($db, $type, $login_uid, $obj_id1, $obj_id2); if ($r === FALSE) break; if ($r === 0) { // already deleted rg_log('DEBUG: watch not active, nothing to do'); $ret = TRUE; break; } $params = array("login_uid" => $login_uid, "obj_id1" => $obj_id1, "obj_id2" => $obj_id2); if (strcmp($type, "bug") == 0) { $sql = "DELETE FROM watch_bug" . " WHERE uid = @@login_uid@@" . " AND repo_id = @@obj_id1@@" . " AND bug_id = @@obj_id2@@"; } else if (strcmp($type, "repo") == 0) { $sql = "DELETE FROM watch_repo" . " WHERE uid = @@login_uid@@" . " AND repo_id = @@obj_id1@@"; } else if (strcmp($type, "user") == 0) { $sql = "DELETE FROM watch_user" . " WHERE uid = @@login_uid@@" . " AND watch_uid = @@obj_id1@@"; } else { rg_internal_error("Invalid watch type!"); break; } $res = rg_sql_query_params($db, $sql, $params); if ($res === FALSE) { rg_watch_set_error('cannot delete data from db'); break; } rg_sql_free_result($res); $key = 'watch' . '::' . $type . '::' . $login_uid . '::' . $obj_id1 . '::' . $obj_id2; rg_cache_unset($key, RG_SOCKET_NO_WAIT); $ret = TRUE; break; } rg_log_exit(); rg_prof_end("watch_del"); return $ret; } /* * Returns a list of uids by type and obj_id */ function rg_watch_load_by_obj_id($db, $type, $obj_id1, $obj_id2) { rg_prof_start("watch_load_by_obj_id"); rg_log_enter("watch_load_by_obj_id: type=$type obj_id=$obj_id1/$obj_id2"); $ret = FALSE; while (1) { $params = array("obj_id1" => $obj_id1, "obj_id2" => $obj_id2); if (strcmp($type, "bug") == 0) { $sql = "SELECT uid FROM watch_bug" . " WHERE repo_id = @@obj_id1@@" . " AND bug_id = @@obj_id2@@"; } else if (strcmp($type, "repo") == 0) { $sql = "SELECT uid FROM watch_repo" . " WHERE repo_id = @@obj_id1@@"; } else if (strcmp($type, "user") == 0) { $sql = "SELECT uid FROM watch_user" . " WHERE watch_uid = @@obj_id1@@"; } else { rg_internal_error("Invalid watch type!"); break; } $res = rg_sql_query_params($db, $sql, $params); if ($res === FALSE) { rg_watch_set_error('cannot get data from db'); break; } $ret = array(); while (($row = rg_sql_fetch_array($res))) $ret[] = $row['uid']; rg_sql_free_result($res); break; } rg_log_exit(); rg_prof_end("watch_load_by_obj_id"); return $ret; } /* * Helper to easy dealing witch watch buttons. * It show and process the presses. */ function rg_watch_hl_process($db, &$rg, $type, $obj_id1, $obj_id2, $url) { rg_prof_start('watch_hl_process'); rg_log_enter('watch_hl_process type=' . $type); $ret = FALSE; $rg['HTML:watch_form'] = ''; $rg['HTML:watch_error'] = ''; while (1) { // If user is not logged in, we cannot add a watch if ($rg['login_ui']['uid'] == 0) { $ret = TRUE; break; } // The owner is already watching his repos if ($rg['login_ui']['uid'] == $rg['page_ui']['uid']) { $ret = TRUE; break; } $watch = rg_watch_load($db, $type, $rg['login_ui']['uid'], $obj_id1, $obj_id2); if ($watch === FALSE) break; // It is our watch? Please note that we may have multiple // watches on the same page: think bugs. $passed_type = rg_var_str('watch_type'); $ours = strcmp($passed_type, $type) == 0; if ((rg_var_uint('watch_doit') == 1) && $ours) { if (!rg_valid_referer()) { rg_watch_set_error('invalid referer; try again'); break; } if (!rg_token_valid($db, $rg, 'watch_' . $type, FALSE)) { rg_watch_set_error('invalid token; try again'); break; } if (rg_var_uint('watch') == $watch) $next_value = 1 - $watch; else $next_value = $watch; } else { $next_value = 1 - $watch; } rg_log('DEBUG: watch=' . $watch . ' next_value=' . $next_value); $rg['watch'] = array( 'type' => $type, 'url' => $url, 'next_value' => $next_value); $rg['rg_form_token_tag'] = 'watch_' . $type; $rg['rg_form_token'] = rg_token_get($db, $rg, 'watch_' . $type); $rg['HTML:watch_form'] = rg_template('watch.html', $rg, TRUE /*xss*/); if ((rg_var_uint('watch_doit') != 1) || !$ours) { $ret = TRUE; break; } if ($watch == 0) $r = rg_watch_add($db, $type, $rg['login_ui']['uid'], $obj_id1, $obj_id2); else $r = rg_watch_del($db, $type, $rg['login_ui']['uid'], $obj_id1, $obj_id2); if ($r === FALSE) break; $ret = TRUE; break; } if ($ret === FALSE) $rg['HTML:watch_error'] = rg_warning('Watch error: ' . rg_watch_error()); rg_log_exit(); rg_prof_end('watch_hl_process'); return $ret; } ?>