public function icon_html($includeLink)
 {
     global $Conf;
     if ($title = get(ReviewForm::$revtype_names, $this->row->reviewType)) {
         $title .= " review";
     } else {
         $title = "Review";
     }
     if ($this->needsSubmit) {
         $title .= " (" . strtolower($this->description_html()) . ")";
     }
     $t = review_type_icon($this->row->reviewType, $this->needsSubmit, $title);
     if ($includeLink) {
         $t = $this->wrap_link($t);
     }
     if ($this->round) {
         $t .= '<span class="revround" title="Review round">&nbsp;' . $this->round . "</span>";
     }
     return $t;
 }
示例#2
0
 echo '<div class="ctelt"><div class="ctelti' . ($color ? " {$color}" : "") . '">';
 if ($p->conflictType >= CONFLICT_AUTHOR) {
     echo '<div class="pctbass">', review_type_icon(-2), Ht::img("_.gif", ">", array("class" => "next", "style" => "visibility:hidden")), '&nbsp;</div>', '<div id="ass' . $p->contactId . '" class="pctbname pctbname-2 taghl nw">', $Me->name_html_for($pc), '</div>';
 } else {
     if ($p->conflictType > 0) {
         $revtype = -1;
     } else {
         if ($p->reviewType) {
             $revtype = $p->reviewType;
         } else {
             $revtype = $p->refused ? -3 : 0;
         }
     }
     $title = $p->refused ? "Review previously declined" : "Assignment";
     // NB manualassign.php also uses the "pcs$contactId" convention
     echo '<div class="pctbass">' . '<div id="foldass' . $p->contactId . '" class="foldc" style="position:relative">' . '<a id="folderass' . $p->contactId . '" href="#" onclick="return assigntable.open(' . $p->contactId . ')">' . review_type_icon($revtype, false, $title) . Ht::img("_.gif", ">", array("class" => "next")) . '</a>&nbsp;' . Ht::hidden("pcs{$p->contactId}", $p->conflictType == 0 ? $p->reviewType : -1, array("id" => "pcs{$p->contactId}")) . '</div></div>';
     echo '<div id="ass' . $p->contactId . '" class="pctbname pctbname' . $revtype . '">' . '<span class="taghl nw">' . $Me->name_html_for($pc) . '</span>';
     if ($p->conflictType == 0) {
         $p->topicInterestScore = $prow->topic_interest_score($pc);
         if ($p->reviewerPreference || $p->reviewerExpertise || $p->topicInterestScore) {
             echo unparse_preference_span($p);
         }
     }
     echo '</div>';
 }
 // then, number of reviews
 echo '<div class="pctbnrev">';
 $numReviews = strlen($p->allReviews);
 $numPrimary = preg_match_all("|" . REVIEW_PRIMARY . "|", $p->allReviews, $matches);
 if (!$numReviews) {
     echo "0 reviews";
    }
    redirectSelf(["kind" => $qreq->kind]);
}
if ($qreq->update && $reviewer > 0 && check_post()) {
    saveAssignments($qreq, $reviewer);
} else {
    if ($qreq->update) {
        Conf::msg_error("You need to select a reviewer.");
    }
}
$Conf->header("Assignments &nbsp;&#x2215;&nbsp; <strong>Manual</strong>", "assignpc", actionBar());
echo '<div class="psmode">', '<div class="papmode"><a href="', hoturl("autoassign"), '">Automatic</a></div>', '<div class="papmodex"><a href="', hoturl("manualassign"), '">Manual</a></div>', '<div class="papmode"><a href="', hoturl("bulkassign"), '">Bulk update</a></div>', '</div><hr class="c" />';
// Help list
echo "<div class='helpside'><div class='helpinside'>\nAssignment methods:\n<ul><li><a href='", hoturl("autoassign"), "'>Automatic</a></li>\n <li><a href='", hoturl("manualassign"), "' class='q'><strong>Manual by PC member</strong></a></li>\n <li><a href='", hoturl("assign"), "'>Manual by paper</a></li>\n <li><a href='", hoturl("bulkassign"), "'>Bulk update</a></li>\n</ul>\n<hr class='hr' />\n";
if ($qreq->kind == "a") {
    echo "Types of PC review:\n<dl><dt>" . review_type_icon(REVIEW_PRIMARY) . " Primary</dt><dd>Mandatory, may not be delegated</dd>\n  <dt>" . review_type_icon(REVIEW_SECONDARY) . " Secondary</dt><dd>Mandatory, may be delegated to external reviewers</dd>\n  <dt>" . review_type_icon(REVIEW_PC) . " Optional</dt><dd>May be declined</dd></dl>\n<hr class='hr' />\n";
}
echo "<dl><dt>Potential conflicts</dt><dd>Matches between PC member collaborators and paper authors, or between PC member and paper authors or collaborators</dd>\n";
if ($qreq->kind == "a") {
    echo "<dt>Preference</dt><dd><a href='", hoturl("reviewprefs"), "'>Review preference</a></dd>\n  <dt>Topic score</dt><dd>+4 per high interest paper topic, &minus;2 per low interest paper topic</dd>\n  <dt>Desirability</dt><dd>High values mean many PC members want to review the paper</dd>\n";
}
echo "</dl>\nClick a heading to sort.\n</div></div>";
if ($reviewer > 0) {
    echo "<h2 style='margin-top:1em'>Assignments for ", $Me->name_html_for($pcm[$reviewer]), $pcm[$reviewer]->affiliation ? " (" . htmlspecialchars($pcm[$reviewer]->affiliation) . ")" : "", "</h2>\n";
} else {
    echo "<h2 style='margin-top:1em'>Assignments by PC member</h2>\n";
}
// Change PC member
echo "<table><tr><td><div class='aahc assignpc_pcsel'>", Ht::form_div(hoturl("manualassign"), array("method" => "get", "id" => "selectreviewerform"));
$result = $Conf->qe("select ContactInfo.contactId, count(reviewId)\n                from ContactInfo\n                left join PaperReview on (PaperReview.contactId=ContactInfo.contactId and PaperReview.reviewType>=" . REVIEW_SECONDARY . ")\n                where (roles&" . Contact::ROLE_PC . ")!=0\n                group by ContactInfo.contactId");
$rev_count = array();
 public function content($pl, $row, $rowidx)
 {
     $conflicted = $this->is_direct ? $row->reviewerConflictType > 0 : $row->has_conflict($this->contact);
     if ($conflicted && !$pl->contact->allow_administer($row)) {
         return review_type_icon(-1);
     } else {
         if (!$this->editable) {
             return $this->show_content($pl, $row, false);
         } else {
             $ptext = $this->text($pl, $row);
             $iname = "revpref" . $row->paperId;
             if (!$this->is_direct) {
                 $iname .= "u" . $this->contact->contactId;
             }
             return '<input name="' . $iname . '" class="revpref" value="' . ($ptext !== "0" ? $ptext : "") . '" type="text" size="4" tabindex="2" placeholder="0" />' . ($conflicted && !$this->is_direct ? "&nbsp;" . review_type_icon(-1) : "");
         }
     }
 }
function complete_assignment($callback)
{
    global $Me;
    $assignset = new AssignmentSet($Me, false);
    $assignset->parse($_POST["file"], get($_POST, "filename"), assignment_defaults(), $callback);
    $SSel = SearchSelection::make(make_qreq(), $Me);
    $assignset->restrict_papers($SSel->selection());
    return $assignset->execute(true);
}
if (isset($_REQUEST["saveassignment"]) && check_post() && (isset($_REQUEST["cancel"]) || isset($_POST["file"]) && get($_POST, "assignment_size_estimate") < 1000 && complete_assignment(null))) {
    /*redirectSelf()*/
}
$Conf->header("Assignments &nbsp;&#x2215;&nbsp; <strong>Bulk update</strong>", "bulkassign", actionBar());
echo '<div class="psmode">', '<div class="papmode"><a href="', hoturl("autoassign"), '">Automatic</a></div>', '<div class="papmode"><a href="', hoturl("manualassign"), '">Manual</a></div>', '<div class="papmodex"><a href="', hoturl("bulkassign"), '">Bulk update</a></div>', '</div><hr class="c" />';
// Help list
echo "<div class='helpside'><div class='helpinside'>\nAssignment methods:\n<ul><li><a href='", hoturl("autoassign"), "'>Automatic</a></li>\n <li><a href='", hoturl("manualassign"), "'>Manual by PC member</a></li>\n <li><a href='", hoturl("assign"), "'>Manual by paper</a></li>\n <li><a href='", hoturl("bulkassign"), "' class='q'><strong>Bulk update</strong></a></li>\n</ul>\n<hr class='hr' />\nTypes of PC review:\n<dl><dt>" . review_type_icon(REVIEW_PRIMARY) . " Primary</dt><dd>Mandatory, may not be delegated</dd>\n  <dt>" . review_type_icon(REVIEW_SECONDARY) . " Secondary</dt><dd>Mandatory, may be delegated to external reviewers</dd>\n  <dt>" . review_type_icon(REVIEW_PC) . " Optional</dt><dd>May be declined</dd></dl>\n</div></div>";
// upload review form action
if (isset($_POST["bulkentry"]) && trim($_POST["bulkentry"]) === "Enter assignments") {
    unset($_POST["bulkentry"]);
}
if (isset($_GET["upload"]) && check_post() && (isset($_POST["bulkentry"]) && $_POST["bulkentry"] || fileUploaded($_FILES["bulk"]))) {
    flush();
    while (@ob_end_flush()) {
        /* do nothing */
    }
    if (fileUploaded($_FILES["bulk"])) {
        $text = file_get_contents($_FILES["bulk"]["tmp_name"]);
        $filename = $_FILES["bulk"]["name"];
    } else {
        $text = $_POST["bulkentry"];
        $filename = "";
 function unparse_display(AssignmentSet $aset)
 {
     $aset->show_column("pcconf");
     $t = $aset->contact()->reviewer_html_for($this->contact) . ' ';
     if ($this->ctype) {
         $t .= review_type_icon(-1);
     } else {
         $t .= "(remove conflict)";
     }
     if (ReviewAssigner::$prefinfo && ($pref = get(ReviewAssigner::$prefinfo, "{$this->pid} {$this->cid}"))) {
         $t .= unparse_preference_span($pref);
     }
     return $t;
 }
    }
    echo Ht::select($name, $opts, $Qreq[$name], $extra);
}
function divClass($name, $classes = null)
{
    global $Error;
    if (isset($Error[$name])) {
        $classes = ($classes ? $classes . " " : "") . "error";
    }
    if ($classes) {
        return '<div class="' . $classes . '">';
    } else {
        return '<div>';
    }
}
echo Ht::form(hoturl_post("autoassign", array("profile" => $Qreq->profile, "seed" => $Qreq->seed, "XDEBUG_PROFILE" => $Qreq->XDEBUG_PROFILE))), '<div class="aahc">', "<div class='helpside'><div class='helpinside'>\nAssignment methods:\n<ul><li><a href='", hoturl("autoassign"), "' class='q'><strong>Automatic</strong></a></li>\n <li><a href='", hoturl("manualassign"), "'>Manual by PC member</a></li>\n <li><a href='", hoturl("assign") . "'>Manual by paper</a></li>\n <li><a href='", hoturl("bulkassign"), "'>Bulk update</a></li>\n</ul>\n<hr class='hr' />\nTypes of PC review:\n<dl><dt>" . review_type_icon(REVIEW_PRIMARY) . " Primary</dt><dd>Mandatory, may not be delegated</dd>\n  <dt>" . review_type_icon(REVIEW_SECONDARY) . " Secondary</dt><dd>Mandatory, may be delegated to external reviewers</dd>\n  <dt>" . review_type_icon(REVIEW_PC) . " Optional</dt><dd>May be declined</dd></dl>\n</div></div>\n";
// paper selection
echo divClass("pap"), "<h3>Paper selection</h3>";
if (!isset($Qreq->q)) {
    // XXX redundant
    $Qreq->q = join(" ", $SSel->selection());
}
echo Ht::entry_h("q", $Qreq->q, array("id" => "autoassignq", "placeholder" => "(All)", "size" => 40, "title" => "Enter paper numbers or search terms", "class" => "hotcrp_searchbox", "onfocus" => 'autosub("requery",this)')), " &nbsp;in &nbsp;";
if (count($tOpt) > 1) {
    echo Ht::select("t", $tOpt, $Qreq->t, array("onchange" => "highlightUpdate(\"requery\")"));
} else {
    echo join("", $tOpt);
}
echo " &nbsp; ", Ht::submit("requery", "List", array("id" => "requery"));
if (isset($Qreq->requery) || isset($Qreq->haspap)) {
    echo "<br /><span class='hint'>Assignments will apply to the selected papers.</span>\n<div class='g'></div>";
function reviewTable($prow, $rrows, $crows, $rrow, $mode, $proposals = null)
{
    global $Conf, $Me;
    $subrev = array();
    $nonsubrev = array();
    $foundRrow = $foundMyReview = $notShown = 0;
    $conflictType = $Me->view_conflict_type($prow);
    $allow_admin = $Me->allow_administer($prow);
    $admin = $Me->can_administer($prow);
    $hideUnviewable = $conflictType > 0 && !$admin || !$Me->act_pc($prow) && !$Conf->setting("extrev_view");
    $show_colors = $Me->can_view_reviewer_tags($prow);
    $tagger = $show_colors ? new Tagger($Me) : null;
    $xsep = ' <span class="barsep">·</span> ';
    $want_scores = $mode !== "assign" && $mode !== "edit" && $mode !== "re";
    $want_requested_by = false;
    $want_retract = false;
    $pcm = pcMembers();
    $score_header = array();
    // actual rows
    foreach ($rrows as $rr) {
        $highlight = $rrow && $rr->reviewId == $rrow->reviewId;
        $foundRrow += $highlight;
        if ($Me->is_my_review($rr)) {
            $foundMyReview++;
        }
        $canView = $Me->can_view_review($prow, $rr, null);
        // skip unsubmitted reviews
        if (!$canView && $hideUnviewable) {
            if ($rr->reviewNeedsSubmit == 1 && $rr->reviewModified) {
                $notShown++;
            }
            continue;
        }
        $t = "";
        $tclass = $rrow && $highlight ? "hilite" : "";
        // review ID
        $id = "Review";
        if ($rr->reviewSubmitted) {
            $id .= "&nbsp;#" . $prow->paperId . unparseReviewOrdinal($rr->reviewOrdinal);
        } else {
            if ($rr->reviewType == REVIEW_SECONDARY && $rr->reviewNeedsSubmit <= 0) {
                $id .= "&nbsp;(delegated)";
            } else {
                if ($rr->reviewModified > 0) {
                    $id .= "&nbsp;(in&nbsp;progress)";
                } else {
                    $id .= "&nbsp;(not&nbsp;started)";
                }
            }
        }
        $rlink = unparseReviewOrdinal($rr);
        if ($rrow && $rrow->reviewId == $rr->reviewId) {
            if ($Me->contactId == $rr->contactId && !$rr->reviewSubmitted) {
                $id = "Your {$id}";
            }
            $t .= '<td><a href="' . hoturl("review", "p={$prow->paperId}&r={$rlink}") . '" class="q"><b>' . $id . '</b></a></td>';
        } else {
            if (!$canView) {
                $t .= "<td>{$id}</td>";
            } else {
                if ($rrow || $rr->reviewModified <= 0 || ($mode === "re" || $mode === "assign") && $Me->can_review($prow, $rr)) {
                    $t .= '<td><a href="' . hoturl("review", "p={$prow->paperId}&r={$rlink}") . '">' . $id . '</a></td>';
                } else {
                    if (Navigation::page() !== "paper") {
                        $t .= '<td><a href="' . hoturl("paper", "p={$prow->paperId}#r{$rlink}") . '">' . $id . '</a></td>';
                    } else {
                        $t .= '<td><a href="#r' . $rlink . '">' . $id . '</a></td>';
                    }
                }
            }
        }
        // primary/secondary glyph
        if ($conflictType > 0 && !$admin) {
            $rtype = "";
        } else {
            if ($rr->reviewType > 0) {
                $rtype = review_type_icon($rr->reviewType);
                if ($admin && $mode === "assign") {
                    $rtype .= _review_table_round_selector($prow, $rr);
                } else {
                    if ($rr->reviewRound > 0 && $Me->can_view_review_round($prow, $rr)) {
                        $rtype .= '&nbsp;<span class="revround" title="Review round">' . htmlspecialchars($Conf->round_name($rr->reviewRound, true)) . "</span>";
                    }
                }
            } else {
                $rtype = "";
            }
        }
        // reviewer identity
        $showtoken = $rr->reviewToken && $Me->can_review($prow, $rr);
        if (!$Me->can_view_review_identity($prow, $rr, null)) {
            $t .= $rtype ? "<td>{$rtype}</td>" : '<td class="empty"></td>';
        } else {
            if (!$showtoken || !Contact::is_anonymous_email($rr->email)) {
                $n = $Me->name_html_for($rr);
            } else {
                $n = "[Token " . encode_token((int) $rr->reviewToken) . "]";
            }
            if ($allow_admin) {
                $n .= _review_table_actas($rr);
            }
            $t .= '<td class="rl"><span class="taghl">' . $n . '</span>' . ($rtype ? " {$rtype}" : "") . "</td>";
            if ($show_colors && (get($rr, "contactRoles") || get($rr, "contactTags"))) {
                $tags = Contact::roles_all_contact_tags(get($rr, "contactRoles"), get($rr, "contactTags"));
                $tags = Tagger::strip_nonviewable($tags, $Me);
                if ($tags && ($color = TagInfo::color_classes($tags))) {
                    $tclass = $color;
                }
            }
        }
        // requester
        if ($mode === "assign") {
            if (($conflictType <= 0 || $admin) && $rr->reviewType == REVIEW_EXTERNAL && !$showtoken) {
                $t .= '<td style="font-size:smaller">';
                if ($rr->requestedBy == $Me->contactId) {
                    $t .= "you";
                } else {
                    if ($u = get($pcm, $rr->requestedBy)) {
                        $t .= $Me->reviewer_html_for($rr->requestedBy);
                    } else {
                        $t .= Text::user_html([$rr->reqFirstName, $rr->reqLastName, $rr->reqEmail]);
                    }
                }
                $t .= '</td>';
                $want_requested_by = true;
            } else {
                $t .= '<td class="empty"></td>';
            }
        }
        // actions
        if ($mode === "assign" && ($conflictType <= 0 || $admin) && $rr->reviewType == REVIEW_EXTERNAL && $rr->reviewModified <= 0 && ($rr->requestedBy == $Me->contactId || $admin)) {
            $t .= '<td>' . _retract_review_request_form($prow, $rr) . '</td>';
        }
        // scores
        $scores = array();
        if ($want_scores && $canView) {
            $view_score = $Me->view_score_bound($prow, $rr);
            $rf = ReviewForm::get();
            foreach ($rf->forder as $fid => $f) {
                if (!$f->has_options || $f->view_score <= $view_score || $f->round_mask && !$f->is_round_visible($rr)) {
                    /* do nothing */
                } else {
                    if ($rr->{$fid}) {
                        if (!get($score_header, $fid)) {
                            $score_header[$fid] = "<th>" . $f->web_abbreviation() . "</th>";
                        }
                        $scores[$fid] = '<td class="revscore" data-rf="' . $f->uid . '">' . $f->unparse_value($rr->{$fid}, ReviewField::VALUE_SC) . '</td>';
                    } else {
                        if (get($score_header, $fid) === null) {
                            $score_header[$fid] = "";
                        }
                    }
                }
            }
        }
        // affix
        if (!$rr->reviewSubmitted) {
            $nonsubrev[] = array($tclass, $t, $scores);
        } else {
            $subrev[] = array($tclass, $t, $scores);
        }
    }
    // proposed review rows
    if ($proposals) {
        foreach ($proposals as $rr) {
            $t = "";
            // review ID
            $t = "<td>Proposed review</td>";
            // reviewer identity
            $t .= "<td>" . Text::user_html($rr);
            if ($allow_admin) {
                $t .= _review_table_actas($rr);
            }
            $t .= "</td>";
            // requester
            if ($conflictType <= 0 || $admin) {
                $t .= '<td style="font-size:smaller">';
                if ($rr->requestedBy == $Me->contactId) {
                    $t .= "you";
                } else {
                    if ($u = get($pcm, $rr->requestedBy)) {
                        $t .= $Me->reviewer_html_for($rr->requestedBy);
                    } else {
                        $t .= Text::user_html([$rr->reqFirstName, $rr->reqLastName, $rr->reqEmail]);
                    }
                }
                $t .= '</td>';
                $want_requested_by = true;
            }
            $t .= '<td>';
            if ($admin) {
                $t .= '<small>' . Ht::form(hoturl_post("assign", "p={$prow->paperId}")) . '<div class="inline">' . Ht::hidden("name", $rr->name) . Ht::hidden("email", $rr->email) . Ht::hidden("reason", $rr->reason);
                if ($rr->reviewRound !== null) {
                    if ($rr->reviewRound == 0) {
                        $rname = "unnamed";
                    } else {
                        $rname = $Conf->round_name($rr->reviewRound);
                    }
                    if ($rname) {
                        $t .= Ht::hidden("round", $rname);
                    }
                }
                $t .= Ht::submit("add", "Approve review", array("style" => "font-size:smaller")) . ' ' . Ht::submit("deny", "Deny request", array("style" => "font-size:smaller")) . '</div></form>';
            } else {
                if ($rr->reqEmail === $Me->email) {
                    $t .= _retract_review_request_form($prow, $rr);
                }
            }
            $t .= '</td>';
            // affix
            $nonsubrev[] = array("", $t);
        }
    }
    // unfinished review notification
    $notetxt = "";
    if ($conflictType >= CONFLICT_AUTHOR && !$admin && $notShown && $Me->can_view_review($prow, null, null)) {
        if ($notShown == 1) {
            $t = "1 review remains outstanding.";
        } else {
            $t = "{$notShown} reviews remain outstanding.";
        }
        $t .= '<br /><span class="hint">You will be emailed if new reviews are submitted or existing reviews are changed.</span>';
        $notetxt = '<div class="revnotes">' . $t . "</div>";
    }
    // completion
    if (count($nonsubrev) + count($subrev)) {
        if ($want_requested_by) {
            array_unshift($score_header, '<th class="revsl">Requester</th>');
        }
        $score_header_text = join("", $score_header);
        $t = "<table class=\"reviewers";
        if ($score_header_text) {
            $t .= " reviewers_scores";
        }
        if ($list = SessionList::active()) {
            $t .= " has_hotcrp_list\" data-hotcrp-list=\"" . $list->listno;
        }
        $t .= "\">\n";
        if ($score_header_text) {
            $t .= '<tr><td class="empty" colspan="2"></td>' . $score_header_text . "</tr>\n";
        }
        foreach (array_merge($subrev, $nonsubrev) as $r) {
            $t .= '<tr class="rl' . ($r[0] ? " {$r['0']}" : "") . '">' . $r[1];
            if (get($r, 2)) {
                foreach ($score_header as $fid => $header_needed) {
                    if ($header_needed) {
                        $x = get($r[2], $fid);
                        $t .= $x ?: "<td class=\"revscore rs_{$fid}\"></td>";
                    }
                }
            } else {
                if (count($score_header)) {
                    $t .= '<td colspan="' . count($score_header) . '"></td>';
                }
            }
            $t .= "</tr>\n";
        }
        if ($score_header_text) {
            $Conf->footerScript("review_form.score_tooltips(\$(\"table.reviewers_scores\"))", "score_tooltips");
        }
        return $t . "</table>\n" . $notetxt;
    } else {
        return $notetxt;
    }
}
示例#9
0
 function show($prow, $rrows, $rrow, &$options)
 {
     global $Conf, $Opt, $Me, $useRequest;
     if (!$options) {
         $options = array();
     }
     $editmode = defval($options, "edit", false);
     $reviewOrdinal = unparseReviewOrdinal($rrow);
     self::check_review_author_seen($prow, $rrow, $Me);
     if (!$editmode) {
         $rj = $this->unparse_review_json($prow, $rrow, $Me);
         if (get($options, "editmessage")) {
             $rj->message_html = $options["editmessage"];
         }
         $Conf->echoScript("review_form.add_review(" . json_encode($rj) . ");\n");
         return;
     }
     // From here on, edit mode.
     $forceShow = $Me->is_admin_force() ? "&amp;forceShow=1" : "";
     $reviewLinkArgs = "p={$prow->paperId}" . ($rrow ? "&amp;r={$reviewOrdinal}" : "") . "&amp;m=re" . $forceShow;
     $reviewPostLink = hoturl_post("review", $reviewLinkArgs);
     $reviewDownloadLink = hoturl("review", $reviewLinkArgs . "&amp;downloadForm=1" . $forceShow);
     echo Ht::form($reviewPostLink, array("class" => "revcard")), '<div class="aahc">', Ht::hidden_default_submit("default", "");
     if ($rrow) {
         echo Ht::hidden("version", defval($rrow, "reviewEditVersion", 0) + 1);
     }
     echo '<div class="revcard" id="r', $reviewOrdinal, '"><div class="revcard_head">';
     // Links
     if ($rrow) {
         echo '<div class="floatright"><a href="' . hoturl("review", "r={$reviewOrdinal}&amp;text=1" . $forceShow) . '" class="xx">', Ht::img("txt.png", "[Text]", "b"), "&nbsp;<u>Plain text</u></a>", "</div>";
     }
     echo "<h3>";
     if ($rrow) {
         echo '<a href="', hoturl("review", "r={$reviewOrdinal}" . $forceShow), '" class="q">Edit Review';
         if ($rrow->reviewSubmitted) {
             echo "&nbsp;#", $reviewOrdinal;
         }
         echo "</a>";
     } else {
         echo "Write Review";
     }
     echo "</h3>\n";
     $open = $sep = " <span class='revinfo'>";
     $xsep = " <span class='barsep'>·</span> ";
     $showtoken = $rrow && $Me->review_token_cid($prow, $rrow);
     $type = "";
     if ($rrow && $Me->can_view_review_round($prow, $rrow, null)) {
         $type = review_type_icon($rrow->reviewType);
         if ($rrow->reviewRound > 0 && $Me->can_view_review_round($prow, $rrow, null)) {
             $type .= "&nbsp;<span class=\"revround\" title=\"Review round\">" . htmlspecialchars($Conf->round_name($rrow->reviewRound, true)) . "</span>";
         }
     }
     if ($rrow && $Me->can_view_review_identity($prow, $rrow, null) && (!$showtoken || !Contact::is_anonymous_email($rrow->email))) {
         echo $sep, $rrow->reviewBlind ? "[" : "", Text::user_html($rrow), $rrow->reviewBlind ? "]" : "", " &nbsp;", $type;
         $sep = $xsep;
     } else {
         if ($type) {
             echo $sep, $type;
             $sep = $xsep;
         }
     }
     if ($showtoken) {
         echo $sep, "Review token ", encode_token((int) $rrow->reviewToken);
         $sep = $xsep;
     }
     if ($rrow && $rrow->reviewModified > 0 && $Me->can_view_review_time($prow, $rrow)) {
         echo $sep, "Updated ", $Conf->printableTime($rrow->reviewModified);
         $sep = $xsep;
     }
     if ($sep != $open) {
         echo "</span>\n";
     }
     if (defval($options, "editmessage")) {
         echo "<div class='hint'>", defval($options, "editmessage"), "</div>\n";
     }
     // download?
     echo '<hr class="c" />';
     echo "<table class='revoff'><tr>\n      <td><strong>Offline reviewing</strong> &nbsp;</td>\n      <td>Upload form: &nbsp; <input type='file' name='uploadedFile' accept='text/plain' size='30' />\n      &nbsp; ", Ht::submit("uploadForm", "Go"), "</td>\n    </tr><tr>\n      <td></td>\n      <td><a href='{$reviewDownloadLink}'>Download form</a>\n      <span class='barsep'>·</span>\n      <span class='hint'><strong>Tip:</strong> Use <a href='", hoturl("search"), "'>Search</a> or <a href='", hoturl("offline"), "'>Offline reviewing</a> to download or upload many forms at once.</span></td>\n    </tr></table></div>\n";
     // ready?
     $ready = $useRequest ? defval($_REQUEST, "ready") : !($rrow && $rrow->reviewModified && !$rrow->reviewSubmitted);
     // review card
     echo '<div class="revcard_body">';
     // administrator?
     $admin = $Me->allow_administer($prow);
     if ($rrow && !$Me->is_my_review($rrow) && $admin) {
         echo Ht::xmsg("info", "This isn’t your review, but as an administrator you can still make changes.");
     }
     // delegate?
     if ($rrow && !$rrow->reviewSubmitted && $rrow->contactId == $Me->contactId && $rrow->reviewType == REVIEW_SECONDARY) {
         $ndelegated = 0;
         foreach ($rrows as $rr) {
             if ($rr->reviewType == REVIEW_EXTERNAL && $rr->requestedBy == $rrow->contactId) {
                 $ndelegated++;
             }
         }
         if ($ndelegated == 0) {
             $t = "As a secondary reviewer, you can <a href=\"" . hoturl("assign", "p={$rrow->paperId}") . "\">delegate this review to an external reviewer</a>, but if your external reviewer declines to review the paper, you should complete this review yourself.";
         } else {
             if ($rrow->reviewNeedsSubmit == 0) {
                 $t = "A delegated external reviewer has submitted their review, but you can still complete your own if you’d like.";
             } else {
                 $t = "Your delegated external reviewer has not yet submitted a review.  If they do not, you should complete this review yourself.";
             }
         }
         echo Ht::xmsg("info", $t);
     }
     // top save changes
     if ($Me->timeReview($prow, $rrow) || $admin) {
         $buttons = $this->_review_buttons($prow, $rrow, "top", $reviewPostLink);
         echo Ht::actions($buttons, array("class" => "aab", "style" => "margin-top:0"));
     }
     // blind?
     if ($Conf->review_blindness() == Conf::BLIND_OPTIONAL) {
         echo '<div class="revet"><span class="revfn">', Ht::checkbox_h("blind", 1, $useRequest ? defval($_REQUEST, 'blind') : !$rrow || $rrow->reviewBlind), "&nbsp;", Ht::label("Anonymous review"), "</span><hr class=\"c\" /></div>\n", '<div class="revhint">', htmlspecialchars(Conf::$gShortName), " allows either anonymous or open review.  Check this box to submit your review anonymously (the authors won’t know who wrote the review).</div>\n", '<div class="g"></div>', "\n";
     }
     // form body
     $this->webFormRows($Me, $prow, $rrow, $useRequest);
     // review actions
     if ($Me->timeReview($prow, $rrow) || $admin) {
         $buttons = $this->_review_buttons($prow, $rrow, "bottom", $reviewPostLink);
         echo Ht::actions($buttons, array("class" => "aab", "style" => "margin-bottom:0"));
         if ($rrow && $rrow->reviewSubmitted && !$admin) {
             echo '<div class="hint">Only administrators can remove or unsubmit the review at this point.</div>';
         }
     }
     echo "</div></div></div></form>\n\n";
     Ht::stash_script('hiliter_children("form.revcard")', "form_revcard");
 }