Пример #1
1
/**
 * Called to display the Special:ReviewMerge page
 *
 * @param unknown_type $par
 * @param unknown_type $specialPage
 */
function wfSpecialReviewMerge($par = NULL, $specialPage)
{
    global $wgOut, $wgScriptPath, $wgUser, $wrSidebarHtml;
    $reviewForm = new ReviewForm();
    // read query parameters into variables
    $unmerge = '';
    if (!$reviewForm->readQueryParms($par)) {
        $wgOut->setPageTitle('Review merge');
        $results = '<p>You must click on a "review" link on Recent Changes or a page history in order to review the merge.</p>';
    } else {
        if ($reviewForm->isMarkPatrolled()) {
            $wgOut->setPagetitle(wfMsg('markedaspatrolled'));
            $results = $reviewForm->markPatrolled();
        } else {
            if ($reviewForm->isUnmerge()) {
                if (!$wgUser->isLoggedIn()) {
                    if (!$wgCommandLineMode && !isset($_COOKIE[session_name()])) {
                        User::SetupSession();
                    }
                    $title = Title::makeTitle(NS_SPECIAL, 'ReviewMerge/' . $par);
                    $requestData = array();
                    if ($title) {
                        $requestData['returnto'] = $title->getPrefixedUrl();
                    }
                    $request = new FauxRequest($requestData);
                    require_once 'includes/SpecialUserlogin.php';
                    $form = new LoginForm($request);
                    $form->mainLoginForm("You need to sign in to unmerge pages<br/><br/>", '');
                    return;
                }
                if ($wgUser->isBlocked()) {
                    $wgOut->blockedPage();
                    return;
                } else {
                    if (wfReadOnly()) {
                        $wgOut->readOnlyPage();
                        return;
                    }
                }
                $wgOut->setPagetitle('Unmerge');
                $results = $reviewForm->unmerge();
            } else {
                $wgOut->setPageTitle('Review merge');
                $wrSidebarHtml = $reviewForm->getReviewSideText();
                $results = $reviewForm->getReviewResults();
                $unmerge = $reviewForm->getUnmergeInfo();
            }
        }
    }
    $wgOut->addHTML($unmerge . $results);
}
Пример #2
0
 /**
  * Save review form.
  */
 function execute()
 {
     $conference =& Request::getConference();
     $conferenceId = $conference->getId();
     $reviewFormDao =& DAORegistry::getDAO('ReviewFormDAO');
     if ($this->reviewFormId != null) {
         $reviewForm =& $reviewFormDao->getReviewForm($this->reviewFormId, $conferenceId);
     }
     if (!isset($reviewForm)) {
         $reviewForm = new ReviewForm();
         $reviewForm->setConferenceId($conferenceId);
         $reviewForm->setActive(0);
         $reviewForm->setSequence(REALLY_BIG_NUMBER);
     }
     $reviewForm->setTitle($this->getData('title'), null);
     // Localized
     $reviewForm->setDescription($this->getData('description'), null);
     // Localized
     if ($reviewForm->getId() != null) {
         $reviewFormDao->updateReviewForm($reviewForm);
         $reviewFormId = $reviewForm->getId();
     } else {
         $reviewFormId = $reviewFormDao->insertReviewForm($reviewForm);
         $reviewFormDao->resequenceReviewForms($conferenceId, 0);
     }
 }
Пример #3
0
 /**
  * Internal function to return a ReviewForm object from a row.
  * @param $row array
  * @return ReviewForm
  */
 function &_returnReviewFormFromRow(&$row)
 {
     $reviewForm = new ReviewForm();
     $reviewForm->setId($row['review_form_id']);
     $reviewForm->setConferenceId($row['conference_id']);
     $reviewForm->setSequence($row['seq']);
     $reviewForm->setActive($row['is_active']);
     $reviewForm->setCompleteCount($row['complete_count']);
     $reviewForm->setIncompleteCount($row['incomplete_count']);
     $this->getDataObjectSettings('review_form_settings', 'review_form_id', $row['review_form_id'], $reviewForm);
     HookRegistry::call('ReviewFormDAO::_returnReviewFormFromRow', array(&$reviewForm, &$row));
     return $reviewForm;
 }
function update_schema_review_word_counts($Conf)
{
    $rf = new ReviewForm($Conf->review_form_json());
    do {
        $q = array();
        $result = Dbl::ql("select * from PaperReview where reviewWordCount is null limit 32");
        while ($rrow = edb_orow($result)) {
            $q[] = "update PaperReview set reviewWordCount=" . $rf->word_count($rrow) . " where reviewId=" . $rrow->reviewId;
        }
        Dbl::free($result);
        $Conf->dblink->multi_query(join(";", $q));
        while ($Conf->dblink->more_results()) {
            Dbl::free($Conf->dblink->next_result());
        }
    } while (count($q) == 32);
}
 function addScores($a)
 {
     global $Conf;
     if ($this->contact->isPC) {
         foreach (ReviewForm::all_fields() as $f) {
             if ($f->has_options && strpos(displayOptionsSet("uldisplay"), " {$f->id} ") !== false) {
                 array_push($a, $f->id);
             }
         }
         $this->scoreMax = array();
     }
     return $a;
 }
Пример #6
0
 function paperQuery($contact, $options = array())
 {
     // Options:
     //   "paperId" => $pid  Only paperId $pid (if array, any of those)
     //   "reviewId" => $rid Only paper reviewed by $rid
     //   "commentId" => $c  Only paper where comment is $c
     //   "finalized"        Only submitted papers
     //   "unsub"            Only unsubmitted papers
     //   "accepted"         Only accepted papers
     //   "active"           Only nonwithdrawn papers
     //   "author"           Only papers authored by $contactId
     //   "myReviewRequests" Only reviews requested by $contactId
     //   "myReviews"        All reviews authored by $contactId
     //   "myOutstandingReviews" All unsubmitted reviews auth by $contactId
     //   "myReviewsOpt"     myReviews, + include papers not yet reviewed
     //   "allReviews"       All reviews (multiple rows per paper)
     //   "allReviewScores"  All review scores (multiple rows per paper)
     //   "allComments"      All comments (multiple rows per paper)
     //   "reviewerName"     Include reviewer names
     //   "commenterName"    Include commenter names
     //   "reviewer" => $cid Include reviewerConflictType/reviewerReviewType
     //   "tags"             Include paperTags
     //   "tagIndex" => $tag Include tagIndex of named tag
     //   "tagIndex" => tag array -- include tagIndex, tagIndex1, ...
     //   "topics"
     //   "options"
     //   "scores" => array(fields to score)
     //   "assignments"
     //   "order" => $sql    $sql is SQL 'order by' clause (or empty)
     global $Opt;
     $reviewerQuery = isset($options["myReviews"]) || isset($options["allReviews"]) || isset($options["myReviewRequests"]) || isset($options["myReviewsOpt"]) || isset($options["myOutstandingReviews"]);
     $allReviewerQuery = isset($options["allReviews"]) || isset($options["allReviewScores"]);
     $scoresQuery = !$reviewerQuery && isset($options["allReviewScores"]);
     if (is_object($contact)) {
         $contactId = $contact->contactId;
     } else {
         $contactId = (int) $contact;
         $contact = null;
     }
     if (isset($options["reviewer"]) && is_object($options["reviewer"])) {
         $reviewerContactId = $options["reviewer"]->contactId;
     } else {
         if (isset($options["reviewer"])) {
             $reviewerContactId = $options["reviewer"];
         } else {
             $reviewerContactId = $contactId;
         }
     }
     if (get($options, "author")) {
         $myPaperReview = null;
     } else {
         if ($allReviewerQuery) {
             $myPaperReview = "MyPaperReview";
         } else {
             $myPaperReview = "PaperReview";
         }
     }
     // paper selection
     $paperset = array();
     if (isset($options["paperId"])) {
         $paperset[] = self::_cvt_numeric_set($options["paperId"]);
     }
     if (isset($options["reviewId"])) {
         if (is_numeric($options["reviewId"])) {
             $result = Dbl::qe("select paperId from PaperReview where reviewId=" . $options["reviewId"]);
             $paperset[] = self::_cvt_numeric_set(edb_first_columns($result));
         } else {
             if (preg_match('/^(\\d+)([A-Z][A-Z]?)$/i', $options["reviewId"], $m)) {
                 $result = Dbl::qe("select paperId from PaperReview where paperId={$m['1']} and reviewOrdinal=" . parseReviewOrdinal($m[2]));
                 $paperset[] = self::_cvt_numeric_set(edb_first_columns($result));
             } else {
                 $paperset[] = array();
             }
         }
     }
     if (isset($options["commentId"])) {
         $result = Dbl::qe("select paperId from PaperComment where commentId" . sql_in_numeric_set(self::_cvt_numeric_set($options["commentId"])));
         $paperset[] = self::_cvt_numeric_set(edb_first_columns($result));
     }
     if (count($paperset) > 1) {
         $paperset = array(call_user_func_array("array_intersect", $paperset));
     }
     $papersel = "";
     if (count($paperset)) {
         $papersel = "paperId" . sql_in_numeric_set($paperset[0]) . " and ";
     }
     // prepare query: basic tables
     $where = array();
     $joins = array("Paper");
     $cols = array("Paper.*, PaperConflict.conflictType");
     $aujoinwhere = null;
     if (get($options, "author") && $contact && ($aujoinwhere = $contact->actAuthorSql("PaperConflict", true))) {
         $where[] = $aujoinwhere;
     }
     if (get($options, "author") && !$aujoinwhere) {
         $joins[] = "join PaperConflict on (PaperConflict.paperId=Paper.paperId and PaperConflict.contactId={$contactId} and PaperConflict.conflictType>=" . CONFLICT_AUTHOR . ")";
     } else {
         $joins[] = "left join PaperConflict on (PaperConflict.paperId=Paper.paperId and PaperConflict.contactId={$contactId})";
     }
     // my review
     $qr = "";
     if ($contact && ($tokens = $contact->review_tokens())) {
         $qr = " or PaperReview.reviewToken in (" . join(", ", $tokens) . ")";
     }
     if (get($options, "myReviewRequests")) {
         $joins[] = "join PaperReview on (PaperReview.paperId=Paper.paperId and PaperReview.requestedBy={$contactId} and PaperReview.reviewType=" . REVIEW_EXTERNAL . ")";
     } else {
         if (get($options, "myReviews")) {
             $joins[] = "join PaperReview on (PaperReview.paperId=Paper.paperId and (PaperReview.contactId={$contactId}{$qr}))";
         } else {
             if (get($options, "myOutstandingReviews")) {
                 $joins[] = "join PaperReview on (PaperReview.paperId=Paper.paperId and (PaperReview.contactId={$contactId}{$qr}) and PaperReview.reviewNeedsSubmit!=0)";
             } else {
                 if (get($options, "myReviewsOpt")) {
                     $joins[] = "left join PaperReview on (PaperReview.paperId=Paper.paperId and (PaperReview.contactId={$contactId}{$qr}))";
                 } else {
                     if (get($options, "allReviews") || get($options, "allReviewScores")) {
                         $x = get($options, "reviewLimitSql") ? " and (" . $options["reviewLimitSql"] . ")" : "";
                         $joins[] = "join PaperReview on (PaperReview.paperId=Paper.paperId{$x})";
                     } else {
                         if (!get($options, "author")) {
                             $joins[] = "left join PaperReview on (PaperReview.paperId=Paper.paperId and (PaperReview.contactId={$contactId}{$qr}))";
                         }
                     }
                 }
             }
         }
     }
     // started reviews
     if (get($options, "startedReviewCount")) {
         $joins[] = "left join (select paperId, count(*) count from PaperReview where {$papersel}(reviewSubmitted or reviewNeedsSubmit>0) group by paperId) R_started on (R_started.paperId=Paper.paperId)";
         $cols[] = "coalesce(R_started.count,0) startedReviewCount";
     }
     // submitted reviews
     $j = "select paperId, count(*) count";
     $before_ncols = count($cols);
     if (get($options, "startedReviewCount")) {
         $cols[] = "coalesce(R_submitted.count,0) reviewCount";
     }
     if (get($options, "scores")) {
         foreach ($options["scores"] as $fid) {
             $cols[] = "R_submitted.{$fid}Scores";
             if ($myPaperReview) {
                 $cols[] = "{$myPaperReview}.{$fid}";
             }
             $j .= ", group_concat({$fid} order by reviewId) {$fid}Scores";
         }
     }
     if (get($options, "reviewTypes") || get($options, "reviewIdentities")) {
         $cols[] = "R_submitted.reviewTypes";
         $j .= ", group_concat(reviewType order by reviewId) reviewTypes";
     }
     if (get($options, "reviewIdentities")) {
         $cols[] = "R_submitted.reviewRequestedBys";
         $j .= ", group_concat(requestedBy order by reviewId) reviewRequestedBys";
         if ($this->review_blindness() == self::BLIND_OPTIONAL) {
             $cols[] = "R_submitted.reviewBlinds";
             $j .= ", group_concat(reviewBlind order by reviewId) reviewBlinds";
         }
         if ($contact && $contact->review_tokens()) {
             $cols[] = "R_submitted.reviewTokens";
             $j .= ", group_concat(reviewToken order by reviewId) reviewTokens";
         }
     }
     if (get($options, "reviewRounds")) {
         $cols[] = "R_submitted.reviewRounds";
         $j .= ", group_concat(reviewRound order by reviewId) reviewRounds";
     }
     if (get($options, "reviewWordCounts") && $this->sversion >= 99) {
         $cols[] = "R_submitted.reviewWordCounts";
         $j .= ", group_concat(reviewWordCount order by reviewId) reviewWordCounts";
     }
     if (get($options, "reviewOrdinals")) {
         $cols[] = "R_submitted.reviewOrdinals";
         $j .= ", group_concat(reviewOrdinal order by reviewId) reviewOrdinals";
     }
     if (get($options, "reviewTypes") || get($options, "scores") || get($options, "reviewContactIds") || get($options, "reviewOrdinals") || get($options, "reviewIdentities")) {
         $cols[] = "R_submitted.reviewContactIds";
         $j .= ", group_concat(contactId order by reviewId) reviewContactIds";
     }
     if (count($cols) != $before_ncols) {
         $joins[] = "left join ({$j} from PaperReview where {$papersel}reviewSubmitted>0 group by paperId) R_submitted on (R_submitted.paperId=Paper.paperId)";
     }
     // assignments
     if (get($options, "assignments")) {
         $j = "select paperId, group_concat(contactId order by reviewId) allReviewContactIds, group_concat(reviewType order by reviewId) allReviewTypes, group_concat(reviewRound order by reviewId) allReviewRounds";
         $cols[] = "R_all.allReviewContactIds, R_all.allReviewTypes, R_all.allReviewRounds";
         $joins[] = "left join ({$j} from PaperReview where {$papersel}true group by paperId) R_all on (R_all.paperId=Paper.paperId)";
     }
     // fields
     if (get($options, "author")) {
         $cols[] = "null reviewType, null reviewId, null myReviewType";
     } else {
         // see also papercolumn.php
         array_push($cols, "PaperReview.reviewType, PaperReview.reviewId", "PaperReview.reviewModified, PaperReview.reviewSubmitted", "PaperReview.reviewNeedsSubmit, PaperReview.reviewOrdinal", "PaperReview.reviewBlind, PaperReview.reviewToken", "PaperReview.contactId as reviewContactId, PaperReview.requestedBy", "max({$myPaperReview}.reviewType) as myReviewType", "max({$myPaperReview}.reviewSubmitted) as myReviewSubmitted", "min({$myPaperReview}.reviewNeedsSubmit) as myReviewNeedsSubmit", "{$myPaperReview}.contactId as myReviewContactId", "PaperReview.reviewRound");
     }
     if ($reviewerQuery || $scoresQuery) {
         $cols[] = "PaperReview.reviewEditVersion as reviewEditVersion";
         $cols[] = ($this->sversion >= 105 ? "PaperReview.reviewFormat" : "null") . " as reviewFormat";
         foreach (ReviewForm::all_fields() as $f) {
             if ($reviewerQuery || $f->has_options) {
                 $cols[] = "PaperReview.{$f->id} as {$f->id}";
             }
         }
     }
     if ($myPaperReview == "MyPaperReview") {
         $joins[] = "left join PaperReview as MyPaperReview on (MyPaperReview.paperId=Paper.paperId and MyPaperReview.contactId={$contactId})";
     }
     if (get($options, "topics")) {
         $cols[] = "(select group_concat(topicId) from PaperTopic where PaperTopic.paperId=Paper.paperId) topicIds";
     }
     if (get($options, "options") && (isset($this->settingTexts["options"]) || isset($Opt["optionsInclude"])) && PaperOption::count_option_list()) {
         $cols[] = "(select group_concat(PaperOption.optionId, '#', value) from PaperOption where paperId=Paper.paperId) optionIds";
     } else {
         if (get($options, "options")) {
             $cols[] = "'' as optionIds";
         }
     }
     if (get($options, "tags")) {
         $cols[] = "(select group_concat(' ', tag, '#', tagIndex order by tag separator '') from PaperTag where PaperTag.paperId=Paper.paperId) paperTags";
     }
     if (get($options, "tagIndex") && !is_array($options["tagIndex"])) {
         $options["tagIndex"] = array($options["tagIndex"]);
     }
     if (get($options, "tagIndex")) {
         foreach ($options["tagIndex"] as $i => $tag) {
             $cols[] = "(select tagIndex from PaperTag where PaperTag.paperId=Paper.paperId and PaperTag.tag='" . sqlq($tag) . "') tagIndex" . ($i ?: "");
         }
     }
     if (get($options, "reviewerPreference")) {
         $joins[] = "left join PaperReviewPreference on (PaperReviewPreference.paperId=Paper.paperId and PaperReviewPreference.contactId={$reviewerContactId})";
         $cols[] = "coalesce(PaperReviewPreference.preference, 0) as reviewerPreference";
         $cols[] = "PaperReviewPreference.expertise as reviewerExpertise";
     }
     if (get($options, "allReviewerPreference") || get($options, "desirability")) {
         $subq = "select paperId";
         if (get($options, "allReviewerPreference")) {
             $subq .= ", " . $this->query_all_reviewer_preference() . " as allReviewerPreference";
             $cols[] = "APRP.allReviewerPreference";
         }
         if (get($options, "desirability")) {
             $subq .= ", sum(if(preference<=-100,0,greatest(least(preference,1),-1))) as desirability";
             $cols[] = "coalesce(APRP.desirability,0) as desirability";
         }
         $subq .= " from PaperReviewPreference where {$papersel}true group by paperId";
         $joins[] = "left join ({$subq}) as APRP on (APRP.paperId=Paper.paperId)";
     }
     if (get($options, "allConflictType")) {
         $joins[] = "left join (select paperId, group_concat(concat(contactId,' ',conflictType) separator ',') as allConflictType from PaperConflict where {$papersel}conflictType>0 group by paperId) as AllConflict on (AllConflict.paperId=Paper.paperId)";
         $cols[] = "AllConflict.allConflictType";
     }
     if (get($options, "reviewer")) {
         $joins[] = "left join PaperConflict RPC on (RPC.paperId=Paper.paperId and RPC.contactId={$reviewerContactId})";
         $joins[] = "left join PaperReview RPR on (RPR.paperId=Paper.paperId and RPR.contactId={$reviewerContactId})";
         $cols[] = "RPC.conflictType reviewerConflictType, RPR.reviewType reviewerReviewType";
     }
     if (get($options, "allComments")) {
         $joins[] = "join PaperComment on (PaperComment.paperId=Paper.paperId)";
         $joins[] = "left join PaperConflict as CommentConflict on (CommentConflict.paperId=PaperComment.paperId and CommentConflict.contactId=PaperComment.contactId)";
         array_push($cols, "PaperComment.commentId, PaperComment.contactId as commentContactId", "CommentConflict.conflictType as commentConflictType", "PaperComment.timeModified, PaperComment.comment", "PaperComment.replyTo, PaperComment.commentType");
     }
     if (get($options, "reviewerName")) {
         if ($options["reviewerName"] === "lead" || $options["reviewerName"] === "shepherd") {
             $joins[] = "left join ContactInfo as ReviewerContactInfo on (ReviewerContactInfo.contactId=Paper." . $options['reviewerName'] . "ContactId)";
         } else {
             if (get($options, "allComments")) {
                 $joins[] = "left join ContactInfo as ReviewerContactInfo on (ReviewerContactInfo.contactId=PaperComment.contactId)";
             } else {
                 if (get($options, "reviewerName")) {
                     $joins[] = "left join ContactInfo as ReviewerContactInfo on (ReviewerContactInfo.contactId=PaperReview.contactId)";
                 }
             }
         }
         array_push($cols, "ReviewerContactInfo.firstName as reviewFirstName", "ReviewerContactInfo.lastName as reviewLastName", "ReviewerContactInfo.email as reviewEmail", "ReviewerContactInfo.lastLogin as reviewLastLogin");
     }
     if (get($options, "foldall")) {
         $cols[] = "1 as folded";
     }
     // conditions
     if (count($paperset)) {
         $where[] = "Paper.paperId" . sql_in_numeric_set($paperset[0]);
     }
     if (get($options, "finalized")) {
         $where[] = "timeSubmitted>0";
     } else {
         if (get($options, "unsub")) {
             $where[] = "timeSubmitted<=0";
         }
     }
     if (get($options, "accepted")) {
         $where[] = "outcome>0";
     }
     if (get($options, "undecided")) {
         $where[] = "outcome=0";
     }
     if (get($options, "active") || get($options, "myReviews") || get($options, "myReviewRequests")) {
         $where[] = "timeWithdrawn<=0";
     }
     if (get($options, "myLead")) {
         $where[] = "leadContactId={$contactId}";
     }
     if (get($options, "unmanaged")) {
         $where[] = "managerContactId=0";
     }
     $pq = "select " . join(",\n    ", $cols) . "\nfrom " . join("\n    ", $joins);
     if (count($where)) {
         $pq .= "\nwhere " . join("\n    and ", $where);
     }
     // grouping and ordering
     if (get($options, "allComments")) {
         $pq .= "\ngroup by Paper.paperId, PaperComment.commentId";
     } else {
         if ($reviewerQuery || $scoresQuery) {
             $pq .= "\ngroup by Paper.paperId, PaperReview.reviewId";
         } else {
             $pq .= "\ngroup by Paper.paperId";
         }
     }
     if (get($options, "order") && $options["order"] != "order by Paper.paperId") {
         $pq .= "\n" . $options["order"];
     } else {
         $pq .= "\norder by Paper.paperId";
         if ($reviewerQuery || $scoresQuery) {
             $pq .= ", PaperReview.reviewOrdinal";
         }
         if (isset($options["allComments"])) {
             $pq .= ", PaperComment.commentId";
         }
     }
     //Conf::msg_debugt($pq);
     return $pq . "\n";
 }
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;
    }
}
Пример #8
0
function do_setting_update($sv)
{
    global $Conf, $Group, $Me, $Now, $Opt, $OptOverride;
    // parse settings
    foreach (Si::$all as $si) {
        account_value($sv, $si);
    }
    // check date relationships
    foreach (array("sub_reg" => "sub_sub", "final_soft" => "final_done") as $dn1 => $dn2) {
        list($dv1, $dv2) = [$sv->savedv($dn1), $sv->savedv($dn2)];
    }
    if (!$dv1 && $dv2) {
        $sv->save($dn1, $dv2);
    } else {
        if ($dv2 && $dv1 > $dv2) {
            $sv->set_error($dn1, unparse_setting_error(Si::get($dn1), "Must come before " . Si::get($dn2, "short_description") . "."));
            $sv->set_error($dn2);
        }
    }
    if ($sv->has_savedv("sub_sub")) {
        $sv->save("sub_update", $sv->savedv("sub_sub"));
    }
    if (get($Opt, "defaultSiteContact")) {
        if ($sv->has_savedv("opt.contactName") && get($Opt, "contactName") === $sv->savedv("opt.contactName")) {
            $sv->save("opt.contactName", null);
        }
        if ($sv->has_savedv("opt.contactEmail") && get($Opt, "contactEmail") === $sv->savedv("opt.contactEmail")) {
            $sv->save("opt.contactEmail", null);
        }
    }
    if ($sv->has_savedv("resp_active") && $sv->savedv("resp_active")) {
        foreach (explode(" ", $sv->newv("resp_rounds")) as $i => $rname) {
            $isuf = $i ? "_{$i}" : "";
            if ($sv->newv("resp_open{$isuf}") > $sv->newv("resp_done{$isuf}")) {
                $sv->set_error("resp_open{$isuf}", unparse_setting_error(Si::get("resp_open"), "Must come before " . Si::get("resp_done", "short_description") . "."));
                $sv->set_error("resp_done{$isuf}");
            }
        }
    }
    // update 'papersub'
    if ($sv->has_savedv("pc_seeall")) {
        // see also conference.php
        if ($sv->savedv("pc_seeall") <= 0) {
            $x = "timeSubmitted>0";
        } else {
            $x = "timeWithdrawn<=0";
        }
        $num = Dbl::fetch_ivalue("select paperId from Paper where {$x} limit 1") ? 1 : 0;
        if ($num != $Conf->setting("papersub")) {
            $sv->save("papersub", $num);
        }
    }
    // Setting relationships
    if ($sv->has_savedv("sub_open") && $sv->newv("sub_open", 1) <= 0 && $sv->oldv("sub_open") > 0 && $sv->newv("sub_sub") <= 0) {
        $sv->save("sub_close", $Now);
    }
    if ($sv->has_savedv("msg.clickthrough_submit")) {
        $sv->save("clickthrough_submit", null);
    }
    // make settings
    $changedn = [];
    if (!$sv->has_errors() && (count($sv->savedv) || count($sv->save_callbacks))) {
        $tables = "Settings write";
        foreach ($sv->need_lock as $t => $need) {
            if ($need) {
                $tables .= ", {$t} write";
            }
        }
        $Conf->qe("lock tables {$tables}");
        // load db settings, pre-crosscheck
        $dbsettings = array();
        $result = Dbl::qe("select name, value, data from Settings");
        while ($row = edb_row($result)) {
            $dbsettings[$row[0]] = $row;
        }
        Dbl::free($result);
        // apply settings
        foreach ($sv->save_callbacks as $si) {
            $p = $sv->parser($si);
            $p->save($sv, $si);
        }
        $dv = $aq = $av = array();
        foreach ($sv->savedv as $n => $v) {
            if (substr($n, 0, 4) === "opt." && $v !== null) {
                $okey = substr($n, 4);
                $oldv = array_key_exists($okey, $OptOverride) ? $OptOverride[$okey] : get($Opt, $okey);
                $Opt[$okey] = $v[1] === null ? $v[0] : $v[1];
                if ($oldv === $Opt[$okey]) {
                    $v = null;
                } else {
                    if (!array_key_exists($okey, $OptOverride)) {
                        $OptOverride[$okey] = $oldv;
                    }
                }
            }
            if ($v === null ? !isset($dbsettings[$n]) : isset($dbsettings[$n]) && (int) $dbsettings[$n][1] === $v[0] && $dbsettings[$n][2] === $v[1]) {
                continue;
            }
            $changedn[] = $n;
            if ($v !== null) {
                $aq[] = "(?, ?, ?)";
                array_push($av, $n, $v[0], $v[1]);
            } else {
                $dv[] = $n;
            }
        }
        if (count($dv)) {
            Dbl::qe_apply("delete from Settings where name?a", array($dv));
            //Conf::msg_info(Ht::pre_text_wrap(Dbl::format_query_apply("delete from Settings where name?a", array($dv))));
        }
        if (count($aq)) {
            Dbl::qe_apply("insert into Settings (name, value, data) values\n\t" . join(",\n\t", $aq) . "\n\ton duplicate key update value=values(value), data=values(data)", $av);
            //Conf::msg_info(Ht::pre_text_wrap(Dbl::format_query_apply("insert into Settings (name, value, data) values\n\t" . join(",\n\t", $aq) . "\n\ton duplicate key update value=values(value), data=values(data)", $av)));
        }
        $Conf->qe("unlock tables");
        if (count($changedn)) {
            $Me->log_activity("Updated settings " . join(", ", $changedn));
        }
        $Conf->load_settings();
        // contactdb may need to hear about changes to shortName
        if ($sv->has_savedv("opt.shortName") && get($Opt, "contactdb_dsn") && ($cdb = Contact::contactdb())) {
            Dbl::ql($cdb, "update Conferences set shortName=? where dbName=?", $Opt["shortName"], $Opt["dbName"]);
        }
    }
    // update the review form in case it's changed
    ReviewForm::clear_cache();
    if (!$sv->has_errors()) {
        $Conf->save_session("settings_highlight", $sv->error_fields());
        if (count($changedn)) {
            $Conf->confirmMsg("Changes saved.");
        } else {
            $Conf->warnMsg("No changes.");
        }
        $sv->report();
        redirectSelf();
    } else {
        SettingGroup::crosscheck($sv, $Group);
        $sv->report();
    }
}
    function render($sv)
    {
        global $Conf, $ConfSitePATH;
        $rf = ReviewForm::get();
        $fmap = array();
        foreach ($rf->fmap as $fid => $f) {
            $fmap[$fid] = $f->has_options;
        }
        $samples = json_decode(file_get_contents("{$ConfSitePATH}/src/reviewformlibrary.json"));
        $req = array();
        if ($sv->use_req()) {
            foreach ($rf->fmap as $fid => $f) {
                foreach (ReviewForm_SettingParser::$setting_prefixes as $fx) {
                    if (isset($sv->req["{$fx}{$fid}"])) {
                        $req["{$fx}{$fid}"] = $sv->req["{$fx}{$fid}"];
                    }
                }
            }
        }
        $Conf->footerHtml('<div id="review_form_caption_description" style="display:none">' . '<p>Enter an HTML description for the review form.
Include any guidance you’d like to provide for reviewers.
Note that complex HTML will not appear on offline review forms.</p></div>' . '<div id="review_form_caption_options" style="display:none">' . '<p>Enter one option per line, numbered starting from 1 (higher numbers
are better). For example:</p>
<pre class="entryexample dark">1. Reject
2. Weak reject
3. Weak accept
4. Accept</pre>
<p>Or use consecutive capital letters (lower letters are better).</p>
<p>Normally scores are mandatory: a review with a missing score cannot be
submitted. Add a line “<code>No entry</code>” to make the score optional.</p></div>');
        $Conf->footerScript("review_form_settings(" . json_encode($fmap) . "," . json_encode($rf->unparse_full_json()) . "," . json_encode($samples) . "," . json_encode($sv->error_fields()) . "," . json_encode($req) . ")");
        echo Ht::hidden("has_review_form", 1), "<div id=\"reviewform_removedcontainer\"></div>", "<div id=\"reviewform_container\"></div>", Ht::button("Add score field", array("onclick" => "review_form_settings.add(1)")), "<span class='sep'></span>", Ht::button("Add text field", array("onclick" => "review_form_settings.add(0)"));
    }
Пример #10
0
function save_review($pid, $contact, $revreq)
{
    $pid = is_object($pid) ? $pid->paperId : $pid;
    $rf = ReviewForm::get();
    $rf->save_review($revreq, fetch_review($pid, $contact), fetch_paper($pid, $contact), $contact);
    return fetch_review($pid, $contact);
}
 private function preferences_paperpc($scoreinfo)
 {
     global $Conf;
     $time = microtime(true);
     $this->prefs = array();
     foreach ($this->pcm as $cid => $p) {
         $this->prefs[$cid] = array();
     }
     $all_fields = ReviewForm::all_fields();
     $scoredir = 1;
     if ($scoreinfo === "x") {
         $score = "1";
     } else {
         if ((substr($scoreinfo, 0, 1) === "-" || substr($scoreinfo, 0, 1) === "+") && isset($all_fields[substr($scoreinfo, 1)])) {
             $score = "PaperReview." . substr($scoreinfo, 1);
             $scoredir = substr($scoreinfo, 0, 1) === "-" ? -1 : 1;
         } else {
             $score = "PaperReview.overAllMerit";
         }
     }
     $query = "select Paper.paperId, ? contactId,\n            coalesce(PaperConflict.conflictType, 0) as conflictType,\n            coalesce(PaperReview.reviewType, 0) as myReviewType,\n            coalesce(PaperReview.reviewSubmitted, 0) as myReviewSubmitted,\n            coalesce({$score}, 0) as reviewScore,\n            Paper.outcome,\n            Paper.managerContactId\n        from Paper\n        left join PaperConflict on (PaperConflict.paperId=Paper.paperId and PaperConflict.contactId=?)\n        left join PaperReview on (PaperReview.paperId=Paper.paperId and PaperReview.contactId=?)\n        where Paper.paperId ?a\n        group by Paper.paperId";
     $nmade = 0;
     foreach ($this->pcm as $cid => $p) {
         $result = Dbl::qe($query, $cid, $cid, $cid, $this->papersel);
         // First, collect score extremes
         $scoreextreme = array();
         $rows = array();
         while ($row = edb_orow($result)) {
             if ($row->conflictType > 0 || $row->myReviewType == 0 || $row->myReviewSubmitted == 0 || $row->reviewScore == 0) {
                 $this->prefs[$row->contactId][$row->paperId] = self::PNOASSIGN;
             } else {
                 if (!isset($scoreextreme[$row->paperId]) || $scoredir * $row->reviewScore > $scoredir * $scoreextreme[$row->paperId]) {
                     $scoreextreme[$row->paperId] = $row->reviewScore;
                 }
                 $rows[] = $row;
             }
         }
         // Then, collect preferences; ignore score differences farther
         // than 1 score away from the relevant extreme
         foreach ($rows as $row) {
             $scoredifference = $scoredir * ($row->reviewScore - $scoreextreme[$row->paperId]);
             if ($scoredifference >= -1) {
                 $this->prefs[$row->contactId][$row->paperId] = $scoredifference;
             }
         }
         unset($rows);
         // don't need the memory any more
         Dbl::free($result);
         ++$nmade;
         if ($nmade % 4 == 0) {
             $this->set_progress(sprintf("Loading reviewer preferences (%d%% done)", (int) ($nmade * 100 / count($this->pcm) + 0.5)));
         }
     }
     $this->make_pref_groups();
     $this->profile["preferences"] = microtime(true) - $time;
 }
Пример #12
0
function downloadForm($editable)
{
    global $rf, $Conf, $Me, $prow, $paperTable, $Opt;
    $explicit = true;
    if ($paperTable->rrow) {
        $rrows = array($paperTable->rrow);
    } else {
        if ($editable) {
            $rrows = array();
        } else {
            $rrows = $paperTable->viewable_rrows;
            $explicit = false;
        }
    }
    $text = "";
    foreach ($rrows as $rr) {
        if ($rr->reviewSubmitted) {
            $text .= downloadView($prow, $rr, $editable);
        }
    }
    foreach ($rrows as $rr) {
        if (!$rr->reviewSubmitted && ($explicit || $rr->reviewModified)) {
            $text .= downloadView($prow, $rr, $editable);
        }
    }
    if (count($rrows) == 0 && $editable) {
        $text .= downloadView($prow, null, $editable);
    }
    if (!$explicit) {
        $paperTable->resolveComments();
        foreach ($paperTable->crows as $cr) {
            if ($Me->can_view_comment($prow, $cr, false)) {
                $text .= $cr->unparse_text($Me, true) . "\n";
            }
        }
    }
    if (!$text) {
        $whyNot = $Me->perm_view_review($prow, null, null);
        return Conf::msg_error(whyNotText($whyNot ?: array("fail" => 1), "review"));
    }
    if ($editable) {
        $text = ReviewForm::textFormHeader(count($rrows) > 1) . $text;
    }
    $filename = (count($rrows) > 1 ? "reviews" : "review") . "-" . $prow->paperId;
    if (count($rrows) == 1 && $rrows[0]->reviewSubmitted) {
        $filename .= unparseReviewOrdinal($rrows[0]->reviewOrdinal);
    }
    downloadText($text, $filename, !$editable);
}
Пример #13
0
 /**
  * Save review form.
  * @see Form::execute()
  */
 function execute()
 {
     $press =& Request::getPress();
     $pressId = $press->getId();
     $reviewFormDao =& DAORegistry::getDAO('ReviewFormDAO');
     if ($this->reviewFormId != null) {
         $reviewForm =& $reviewFormDao->getReviewForm($this->reviewFormId, ASSOC_TYPE_PRESS, $pressId);
     }
     if (!isset($reviewForm)) {
         $reviewForm = new ReviewForm();
         $reviewForm->setPressId($pressId);
         $reviewForm->setActive(0);
         $reviewForm->setSequence(REALLY_BIG_NUMBER);
     }
     $reviewForm->setTitle($this->getData('title'), null);
     // Localized
     $reviewForm->setDescription($this->getData('description'), null);
     // Localized
     if ($reviewForm->getId() != null) {
         $reviewFormDao->updateObject($reviewForm);
         $this->reviewFormId = $reviewForm->getId();
     } else {
         $this->reviewFormId = $reviewFormDao->insertObject($reviewForm);
         $reviewFormDao->resequenceReviewForms(ASSOC_TYPE_PRESS, $pressId);
     }
     $this->reviewForm = $reviewForm;
 }
Пример #14
0
function searchQuickref()
{
    global $rowidx, $Conf, $Opt, $Me;
    // how to report author searches?
    if ($Conf->subBlindNever()) {
        $aunote = "";
    } else {
        if (!$Conf->subBlindAlways()) {
            $aunote = "<br /><span class='hint'>Search uses fields visible to the searcher. For example, PC member searches do not examine anonymous authors.</span>";
        } else {
            $aunote = "<br /><span class='hint'>Search uses fields visible to the searcher. For example, PC member searches do not examine authors.</span>";
        }
    }
    // does a reviewer tag exist?
    $retag = meaningful_pc_tag() ?: "";
    _searchQuickrefRow("Basics", "", "all papers in the search category");
    _searchQuickrefRow("", "story", "“story” in title, abstract, authors{$aunote}");
    _searchQuickrefRow("", "119", "paper #119");
    _searchQuickrefRow("", "1 2 5 12-24 kernel", "papers in the numbered set with “kernel” in title, abstract, authors");
    _searchQuickrefRow("", "\"802\"", "“802” in title, abstract, authors (not paper #802)");
    _searchQuickrefRow("", "very new", "“very” <em>and</em> “new” in title, abstract, authors");
    _searchQuickrefRow("", "very AND new", "the same");
    _searchQuickrefRow("", "\"very new\"", "the phrase “very new” in title, abstract, authors");
    _searchQuickrefRow("", "very OR new", "<em>either</em> “very” <em>or</em> “new” in title, abstract, authors");
    _searchQuickrefRow("", "(very AND new) OR newest", "use parentheses to group");
    _searchQuickrefRow("", "very -new", "“very” <em>but not</em> “new” in title, abstract, authors");
    _searchQuickrefRow("", "very NOT new", "the same");
    _searchQuickrefRow("", "ve*", "words that <em>start with</em> “ve” in title, abstract, authors");
    _searchQuickrefRow("", "*me*", "words that <em>contain</em> “me” in title, abstract, authors");
    _searchQuickrefRow("Title", "ti:flexible", "title contains “flexible”");
    _searchQuickrefRow("Abstract", "ab:\"very novel\"", "abstract contains “very novel”");
    _searchQuickrefRow("Authors", "au:poletto", "author list contains “poletto”");
    if ($Me->isPC) {
        _searchQuickrefRow("", "au:pc", "one or more authors are PC members (author email matches PC email)");
    }
    _searchQuickrefRow("Collaborators", "co:liskov", "collaborators contains “liskov”");
    _searchQuickrefRow("Topics", "topic:link", "selected topics match “link”");
    $oex = array();
    foreach (PaperOption::option_list() as $o) {
        $oex = array_merge($oex, $o->example_searches());
    }
    if (count($oex)) {
        $section = "Options";
        foreach ($oex as $extype => $oex) {
            if ($extype === "has") {
                $desc = "paper has “" . htmlspecialchars($oex[1]->name) . "” submission option";
                $oabbr = array();
                foreach (PaperOption::option_list() as $ox) {
                    if ($ox !== $oex[1]) {
                        $oabbr[] = "“has:" . htmlspecialchars($ox->abbr) . "”";
                    }
                }
                if (count($oabbr)) {
                    $desc .= '<div class="hint">Other option ' . pluralx(count($oabbr), "search") . ': ' . commajoin($oabbr) . '</div>';
                }
            } else {
                if ($extype === "yes") {
                    $desc = "same meaning; abbreviations also accepted";
                } else {
                    if ($extype === "numeric") {
                        $desc = "paper’s “" . htmlspecialchars($oex[1]->name) . "” option has value &gt; 100";
                    } else {
                        if ($extype === "selector") {
                            $desc = "paper’s “" . htmlspecialchars($oex[1]->name) . "” option has value “" . htmlspecialchars($oex[1]->selector[1]) . "”";
                        } else {
                            if ($extype === "attachment-count") {
                                $desc = "paper has more than 2 “" . htmlspecialchars($oex[1]->name) . "” attachments";
                            } else {
                                if ($extype === "attachment-filename") {
                                    $desc = "paper has an “" . htmlspecialchars($oex[1]->name) . "” attachment with a .gif extension";
                                } else {
                                    continue;
                                }
                            }
                        }
                    }
                }
            }
            _searchQuickrefRow($section, $oex[0], $desc);
            $section = "";
        }
    }
    _searchQuickrefRow("<a href='" . hoturl("help", "t=tags") . "'>Tags</a>", "#discuss", "tagged “discuss” (“tag:discuss” also works)");
    _searchQuickrefRow("", "-#discuss", "not tagged “discuss”");
    _searchQuickrefRow("", "order:discuss", "tagged “discuss”, sort by tag order (“rorder:” for reverse order)");
    _searchQuickrefRow("", "#disc*", "matches any tag that <em>starts with</em> “disc”");
    $cx = null;
    $cm = array();
    foreach (TagInfo::defined_tags() as $t) {
        foreach ($t->colors ?: array() as $c) {
            $cx = $cx ?: $c;
            if ($cx === $c) {
                $cm[] = "“{$t->tag}”";
            }
        }
    }
    if (count($cm)) {
        array_unshift($cm, "“{$cx}”");
        _searchQuickrefRow("", "style:{$cx}", "tagged to appear {$cx} (tagged " . commajoin($cm, "or") . ")");
    }
    _searchQuickrefRow("Reviews", "re:me", "you are a reviewer");
    _searchQuickrefRow("", "re:fdabek", "“fdabek” in reviewer name/email");
    if ($retag) {
        _searchQuickrefRow("", "re:#{$retag}", "has a reviewer tagged “#" . $retag . "”");
    }
    _searchQuickrefRow("", "re:4", "four reviewers (assigned and/or completed)");
    if ($retag) {
        _searchQuickrefRow("", "re:#{$retag}>1", "at least two reviewers (assigned and/or completed) tagged “#" . $retag . "”");
    }
    _searchQuickrefRow("", "re:complete<3", "less than three completed reviews<br /><span class=\"hint\">Use “cre:<3” for short.</span>");
    _searchQuickrefRow("", "re:incomplete>0", "at least one incomplete review");
    _searchQuickrefRow("", "re:inprogress", "at least one in-progress review (started, but not completed)");
    _searchQuickrefRow("", "re:primary>=2", "at least two primary reviewers");
    _searchQuickrefRow("", "re:secondary", "at least one secondary reviewer");
    _searchQuickrefRow("", "re:external", "at least one external reviewer");
    _searchQuickrefRow("", "re:primary:fdabek:complete", "“fdabek” has completed a primary review");
    if ($r = meaningful_round_name()) {
        _searchQuickrefRow("", "re:{$r}", "review in round “" . htmlspecialchars($r) . "”");
    }
    _searchQuickrefRow("", "re:auwords<100", "has a review with less than 100 words in author-visible fields");
    if ($Conf->setting("rev_ratings") != REV_RATINGS_NONE) {
        _searchQuickrefRow("", "rate:+", "review was rated positively (“rate:-” and “rate:+>2” also work; can combine with “re:”)");
    }
    _searchQuickrefRow("Comments", "has:cmt", "at least one visible reviewer comment (not including authors’ response)");
    _searchQuickrefRow("", "cmt:>=3", "at least <em>three</em> visible reviewer comments");
    _searchQuickrefRow("", "has:aucmt", "at least one reviewer comment visible to authors");
    _searchQuickrefRow("", "cmt:sylvia", "“sylvia” (in name/email) wrote at least one visible comment; can combine with counts, use reviewer tags");
    $rnames = $Conf->resp_round_list();
    if (count($rnames) > 1) {
        _searchQuickrefRow("", "has:response", "has an author’s response");
        _searchQuickrefRow("", "has:{$rnames[1]}response", "has {$rnames['1']} response");
    } else {
        _searchQuickrefRow("", "has:response", "has author’s response");
    }
    _searchQuickrefRow("", "anycmt:>1", "at least two visible comments, possibly <em>including</em> author’s response");
    _searchQuickrefRow("Leads", "lead:fdabek", "“fdabek” (in name/email) is discussion lead");
    _searchQuickrefRow("", "lead:none", "no assigned discussion lead");
    _searchQuickrefRow("", "lead:any", "some assigned discussion lead");
    _searchQuickrefRow("Shepherds", "shep:fdabek", "“fdabek” (in name/email) is shepherd (“none” and “any” also work)");
    _searchQuickrefRow("Conflicts", "conflict:me", "you have a conflict with the paper");
    _searchQuickrefRow("", "conflict:fdabek", "“fdabek” (in name/email) has a conflict with the paper<br /><span class='hint'>This search is only available to chairs and to PC members who can see the paper’s author list.</span>");
    _searchQuickrefRow("", "conflict:pc", "some PC member has a conflict with the paper");
    _searchQuickrefRow("", "conflict:pc>2", "at least three PC members have conflicts with the paper");
    _searchQuickrefRow("", "reconflict:\"1 2 3\"", "a reviewer of paper 1, 2, or 3 has a conflict with the paper");
    _searchQuickrefRow("Preferences", "pref:fdabek>0", "“fdabek” (in name/email) has review preference &gt;&nbsp;0<br /><span class='hint'>PC members can search their own preferences; chairs can search anyone’s preferences.</span>");
    _searchQuickrefRow("", "pref:X", "some PC member has a preference expertise of “X” (expert)");
    _searchQuickrefRow("Status", "status:sub", "paper is submitted for review", "t=all");
    _searchQuickrefRow("", "status:unsub", "paper is neither submitted nor withdrawn", "t=all");
    _searchQuickrefRow("", "status:withdrawn", "paper has been withdrawn", "t=all");
    _searchQuickrefRow("", "has:final", "final copy uploaded");
    foreach ($Conf->decision_map() as $dnum => $dname) {
        if ($dnum) {
            break;
        }
    }
    $qdname = strtolower($dname);
    if (strpos($qdname, " ") !== false) {
        $qdname = "\"{$qdname}\"";
    }
    _searchQuickrefRow("Decision", "dec:{$qdname}", "decision is “" . htmlspecialchars($dname) . "” (partial matches OK)");
    _searchQuickrefRow("", "dec:yes", "one of the accept decisions");
    _searchQuickrefRow("", "dec:no", "one of the reject decisions");
    _searchQuickrefRow("", "dec:any", "decision specified");
    _searchQuickrefRow("", "dec:none", "decision unspecified");
    // find names of review fields to demonstrate syntax
    $farr = array(array(), array());
    foreach (ReviewForm::all_fields() as $f) {
        $fx = $f->has_options ? 0 : 1;
        $farr[$fx][] = $f->analyze();
    }
    $t = "Review&nbsp;fields";
    if (count($farr[0])) {
        $r = $farr[0][0];
        _searchQuickrefRow($t, $r->abbreviation1() . ":{$r->typical_score}", "at least one completed review has {$r->name_html} score {$r->typical_score}");
        _searchQuickrefRow("", "{$r->abbreviation}:{$r->typical_score}", "other abbreviations accepted");
        if (count($farr[0]) > 1) {
            $r2 = $farr[0][1];
            _searchQuickrefRow("", strtolower($r2->abbreviation) . ":{$r2->typical_score}", "other fields accepted (here, {$r2->name_html})");
        }
        if (isset($r->typical_score_range)) {
            _searchQuickrefRow("", "{$r->abbreviation}:{$r->typical_score0}..{$r->typical_score}", "completed reviews’ {$r->name_html} scores are in the {$r->typical_score0}&ndash;{$r->typical_score} range<br /><small>(all scores between {$r->typical_score0} and {$r->typical_score})</small>");
            _searchQuickrefRow("", "{$r->abbreviation}:{$r->typical_score_range}", "completed reviews’ {$r->name_html} scores <em>fill</em> the {$r->typical_score0}&ndash;{$r->typical_score} range<br /><small>(all scores between {$r->typical_score0} and {$r->typical_score}, with at least one {$r->typical_score0} and at least one {$r->typical_score})</small>");
        }
        if (!$r->option_letter) {
            list($greater, $less, $hint) = array("greater", "less", "");
        } else {
            $hint = "<br /><small>(better scores are closer to A than Z)</small>";
            if (defval($Opt, "smartScoreCompare")) {
                list($greater, $less) = array("better", "worse");
            } else {
                list($greater, $less) = array("worse", "better");
            }
        }
        _searchQuickrefRow("", "{$r->abbreviation}:>{$r->typical_score}", "at least one completed review has {$r->name_html} score {$greater} than {$r->typical_score}" . $hint);
        _searchQuickrefRow("", "{$r->abbreviation}:2<={$r->typical_score}", "at least two completed reviews have {$r->name_html} score {$less} than or equal to {$r->typical_score}");
        _searchQuickrefRow("", "{$r->abbreviation}:pc>{$r->typical_score}", "at least one completed PC review has {$r->name_html} score {$greater} than {$r->typical_score}");
        _searchQuickrefRow("", "{$r->abbreviation}:pc:2>{$r->typical_score}", "at least two completed PC reviews have {$r->name_html} score {$greater} than {$r->typical_score}");
        _searchQuickrefRow("", "{$r->abbreviation}:sylvia={$r->typical_score}", "“sylvia” (reviewer name/email) gave {$r->name_html} score {$r->typical_score}");
        $t = "";
    }
    if (count($farr[1])) {
        $r = $farr[1][0];
        _searchQuickrefRow($t, $r->abbreviation1() . ":finger", "at least one completed review has “finger” in the {$r->name_html} field");
        _searchQuickrefRow($t, "{$r->abbreviation}:finger", "other abbreviations accepted");
        _searchQuickrefRow($t, "{$r->abbreviation}:any", "at least one completed review has text in the {$r->name_html} field");
    }
    if (count($farr[0])) {
        $r = $farr[0][0];
        _searchQuickrefRow("<a href=\"" . hoturl("help", "t=formulas") . "\">Formulas</a>", "formula:all({$r->abbreviation}={$r->typical_score})", "all reviews have {$r->name_html} score {$r->typical_score}<br />" . "<span class='hint'><a href=\"" . hoturl("help", "t=formulas") . "\">Formulas</a> can express complex numerical queries across review scores and preferences.</span>");
        _searchQuickrefRow("", "f:all({$r->abbreviation}={$r->typical_score})", "“f” is shorthand for “formula”");
        _searchQuickrefRow("", "formula:var({$r->abbreviation})>0.5", "variance in {$r->abbreviation} is above 0.5");
        _searchQuickrefRow("", "formula:any({$r->abbreviation}={$r->typical_score} && pref<0)", "at least one reviewer had {$r->name_html} score {$r->typical_score} and review preference &lt; 0");
    }
    _searchQuickrefRow("Display", "show:tags show:conflicts", "show tags and PC conflicts in the results");
    _searchQuickrefRow("", "hide:title", "hide title in the results");
    if (count($farr[0])) {
        $r = $farr[0][0];
        _searchQuickrefRow("", "show:max({$r->abbreviation})", "show a <a href=\"" . hoturl("help", "t=formulas") . "\">formula</a>");
        _searchQuickrefRow("", "show:statistics", "show summary statistics for formulas");
        _searchQuickrefRow("", "sort:{$r->abbreviation}", "sort by score");
        _searchQuickrefRow("", "sort:\"{$r->abbreviation} variance\"", "sort by score variance");
    }
    _searchQuickrefRow("", "sort:-status", "sort by reverse status");
    _searchQuickrefRow("", "edit:#discuss", "edit the values for tag “#discuss”");
    _searchQuickrefRow("", "search1 THEN search2", "like “search1 OR search2”, but papers matching “search1” are grouped together and appear earlier in the sorting order");
    _searchQuickrefRow("", "1-5 THEN 6-10 show:compact", "display searches in compact columns");
    _searchQuickrefRow("", "search1 HIGHLIGHT search2", "search for “search1”, but <span class=\"taghl highlightmark\">highlight</span> papers in that list that match “search2” (also try HIGHLIGHT:pink, HIGHLIGHT:green, HIGHLIGHT:blue)");
}
Пример #15
0
// offline.php -- HotCRP offline review management page
// HotCRP is Copyright (c) 2006-2016 Eddie Kohler and Regents of the UC
// Distributed under an MIT-like license; see LICENSE
require_once "src/initweb.php";
if ($Me->is_empty()) {
    $Me->escape();
}
$rf = ReviewForm::get();
// general error messages
if (defval($_REQUEST, "post") && !count($_POST)) {
    $Conf->post_missing_msg();
}
// download blank review form action
if (isset($_REQUEST["downloadForm"])) {
    $text = ReviewForm::textFormHeader("blank") . $rf->textForm(null, null, $Me, null) . "\n";
    downloadText($text, "review");
}
// upload review form action
if (isset($_REQUEST["uploadForm"]) && fileUploaded($_FILES["uploadedFile"]) && check_post()) {
    $tf = $rf->beginTextForm($_FILES["uploadedFile"]["tmp_name"], $_FILES["uploadedFile"]["name"]);
    while ($req = $rf->parseTextForm($tf)) {
        $rf->check_save_review($req, $tf, $Me);
    }
    $rf->textFormMessages($tf);
    // Uploading forms may have completed the reviewer's task; recheck roles.
    Contact::update_rights();
} else {
    if (isset($_REQUEST["uploadForm"])) {
        Conf::msg_error("Choose a file first.");
    }
Пример #16
0
            $Conf->save_session($m[1], $val !== null ? intval($val) : null);
        }
        json_exit(["ok" => true]);
    } else {
        json_exit(["ok" => false]);
    }
}
if ($qreq->fn === "events" && $Me->is_reviewer()) {
    $from = $qreq->from;
    if (!$from || !ctype_digit($from)) {
        $from = $Now;
    }
    $entries = $Conf->reviewerActivity($Me, $from, 10);
    $when = $from;
    $rows = array();
    $rf = ReviewForm::get();
    foreach ($entries as $which => $xr) {
        if ($xr->isComment) {
            $rows[] = CommentInfo::unparse_flow_entry($xr, $Me, "");
            $when = $xr->timeModified;
        } else {
            $rows[] = $rf->reviewFlowEntry($Me, $xr, "");
            $when = $xr->reviewSubmitted;
        }
    }
    json_exit(["ok" => true, "from" => (int) $from, "to" => (int) $when - 1, "rows" => $rows]);
} else {
    if ($qreq->fn === "events") {
        json_exit(["ok" => false]);
    }
}
Пример #17
0
     if (isset($_REQUEST[$x])) {
         echo Ht::hidden($x, $_REQUEST[$x]);
     }
 }
 echo "<table><tr><td><strong>Show:</strong> &nbsp;</td>\n  <td class='pad'>";
 $Conf->footerScript('foldmap.ul={"aff":2,"tags":3,"topics":1};');
 foreach (array("aff" => "Affiliations", "collab" => "Collaborators", "tags" => "Tags", "topics" => "Topics") as $fold => $text) {
     if (@$pl->have_folds[$fold] !== null) {
         echo Ht::checkbox("show{$fold}", 1, $pl->have_folds[$fold], array("onchange" => "fold('ul',!this.checked,'{$fold}')")), "&nbsp;", Ht::label($text), "<br />\n";
     }
 }
 echo "</td>";
 if (isset($pl->scoreMax)) {
     echo "<td class='pad'>";
     $revViewScore = $Me->aggregated_view_score_bound();
     foreach (ReviewForm::all_fields() as $f) {
         if ($f->view_score > $revViewScore && $f->has_options) {
             $checked = strpos(displayOptionsSet("uldisplay"), $f->id) !== false;
             echo Ht::checkbox("show{$f->id}", 1, $checked), "&nbsp;", Ht::label($f->name_html), "<br />";
         }
     }
     echo "</td>";
 }
 echo "<td>", Ht::submit("redisplay", "Redisplay"), "</td></tr>\n";
 if (isset($pl->scoreMax)) {
     $ss = array();
     foreach (array("A", "V", "D") as $k) {
         /* ghetto array_intersect_key */
         if (isset(ListSorter::$score_sorts[$k])) {
             $ss[$k] = ListSorter::$score_sorts[$k];
         }
Пример #18
0
 public function viewable_scores($field, $contact, $forceShow)
 {
     $field = is_object($field) ? $field : ReviewForm::field($field);
     $view = $contact->can_view_review($this, $field->view_score, $forceShow);
     if ($view || $this->review_type($contact)) {
         $s = $this->scores($field->id);
         if ($view) {
             return $s;
         } else {
             if (($my_score = get($s, $contact->contactId)) !== null) {
                 return array($contact->contactId => $my_score);
             }
         }
     }
     return null;
 }
Пример #19
0
// Formula experiment
function formulas_qrow($i, $q, $s, $errf)
{
    if ($q === "all") {
        $q = "";
    }
    $klass = ($errf ? "setting_error " : "") . "hotcrp_searchbox";
    $t = '<tr><td class="lentry">' . Ht::entry("q{$i}", $q, array("size" => 40, "placeholder" => "(All)", "class" => $klass));
    $t .= " <span style=\"padding-left:1em\">Style:</span> &nbsp;" . Ht::select("s{$i}", array("plain" => "plain", "by-tag" => "by tag", "redtag" => "red", "orangetag" => "orange", "yellowtag" => "yellow", "greentag" => "green", "bluetag" => "blue", "purpletag" => "purple", "graytag" => "gray"), $s !== "" ? $s : "by-tag");
    $t .= '</td><td class="nw"><a href="#" class="qx row_up" onclick="return author_change(this,-1)" tabindex="-1">&#x25b2;</a><a href="#" class="qx row_down" onclick="return author_change(this,1)" tabindex="-1">&#x25bc;</a><a href="#" class="qx row_kill" onclick="return author_change(this,Infinity)" tabindex="-1">x</a></td></tr>';
    return $t;
}
if ($Graph == "formula") {
    // derive a sample graph
    if (!isset($_REQUEST["fx"]) || !isset($_REQUEST["fy"])) {
        $all_review_fields = ReviewForm::all_fields();
        $field1 = @$all_review_fields["overAllMerit"];
        $field2 = null;
        foreach ($all_review_fields as $f) {
            if ($f->has_options && !$field1) {
                $field1 = $f;
            } else {
                if ($f->has_options && !$field2 && $field1 != $f) {
                    $field2 = $f;
                }
            }
        }
        unset($_REQUEST["fx"], $_REQUEST["fy"]);
        if ($field1) {
            $_REQUEST["fy"] = "avg(" . $field1->analyze()->abbreviation . ")";
        }
Пример #20
0
 private function _parse_expr(&$t, $level, $in_qc)
 {
     global $Conf;
     if (($t = ltrim($t)) === "") {
         return null;
     }
     $lpos = -strlen($t);
     $e = null;
     if ($t[0] === "(") {
         $t = substr($t, 1);
         $e = $this->_parse_ternary($t, false);
         $t = ltrim($t);
         if (!$e || $t === "" || $t[0] !== ")") {
             return null;
         }
         $t = substr($t, 1);
     } else {
         if ($t[0] === "-" || $t[0] === "+" || $t[0] === "!") {
             $op = $t[0];
             $t = substr($t, 1);
             if (!($e = $this->_parse_expr($t, self::$opprec["u{$op}"], $in_qc))) {
                 return null;
             }
             $e = $op == "!" ? new NegateFexpr($e) : new Fexpr($op, $e);
         } else {
             if (preg_match('/\\Aopt(?:ion)?:\\s*(.*)\\z/s', $t, $m)) {
                 $rest = self::_pop_argument($m[1]);
                 $os = PaperSearch::analyze_option_search($rest[1]);
                 foreach ($os->warn as $w) {
                     $this->_error_html[] = $w;
                 }
                 if (!count($os->os) && !count($os->warn)) {
                     $this->_error_html[] = "“" . htmlspecialchars($rest[1]) . "” doesn’t match a submission option.";
                 }
                 if (!count($os->os)) {
                     return null;
                 }
                 foreach ($os->os as $o) {
                     $ex = new OptionFexpr($o->option);
                     if ($o->kind) {
                         $this->_error_html[] = "“" . htmlspecialchars($rest[1]) . "” can’t be used in formulas.";
                     } else {
                         if ($o->value_word === "") {
                             /* stick with raw option fexpr */
                         } else {
                             if (is_array($o->value) && $o->compar === "!=") {
                                 $ex = new NegateFexpr(new InFexpr($ex, $o->value));
                             } else {
                                 if (is_array($o->value)) {
                                     $ex = new InFexpr($ex, $o->value);
                                 } else {
                                     $ex = new Fexpr(get(self::$_oprewrite, $o->compar, $o->compar), $ex, new ConstantFexpr($o->value, $o->option));
                                 }
                             }
                         }
                     }
                     $e = $e ? new Fexpr("||", $e, $ex) : $ex;
                 }
                 if ($os->negate) {
                     $e = new NegateFexpr($e);
                 }
                 $t = $rest[2];
             } else {
                 if (preg_match('/\\Anot([\\s(].*|)\\z/i', $t, $m)) {
                     $t = $m[1];
                     if (!($e = $this->_parse_expr($t, self::$opprec["u!"], $in_qc))) {
                         return null;
                     }
                     $e = new NegateFexpr($e);
                 } else {
                     if (preg_match('/\\A(\\d+\\.?\\d*|\\.\\d+)(.*)\\z/s', $t, $m)) {
                         $e = new ConstantFexpr($m[1] + 0.0);
                         $t = $m[2];
                     } else {
                         if (preg_match('/\\A(false|true)\\b(.*)\\z/si', $t, $m)) {
                             $e = new ConstantFexpr($m[1], Fexpr::FBOOL);
                             $t = $m[2];
                         } else {
                             if (preg_match('/\\A(?:pid|paperid)\\b(.*)\\z/si', $t, $m)) {
                                 $e = new PidFexpr();
                                 $t = $m[1];
                             } else {
                                 if (preg_match('/\\A(?:dec|decision):\\s*' . self::ARGUMENT_REGEX . '(.*)\\z/si', $t, $m)) {
                                     $e = $this->field_search_fexpr(["outcome", PaperSearch::matching_decisions($m[1])]);
                                     $t = $m[2];
                                 } else {
                                     if (preg_match('/\\A(?:dec|decision)\\b(.*)\\z/si', $t, $m)) {
                                         $e = new DecisionFexpr();
                                         $t = $m[1];
                                     } else {
                                         if (preg_match('/\\A(?:is|status):\\s*' . self::ARGUMENT_REGEX . '(.*)\\z/si', $t, $m)) {
                                             $e = $this->field_search_fexpr(PaperSearch::status_field_matcher($m[1]));
                                             $t = $m[2];
                                         } else {
                                             if (preg_match('/\\A(?:tag(?:\\s*:\\s*|\\s+)|#)(' . TAG_REGEX . ')(.*)\\z/is', $t, $m) || preg_match('/\\Atag\\s*\\(\\s*(' . TAG_REGEX . ')\\s*\\)(.*)\\z/is', $t, $m)) {
                                                 $e = new TagFexpr($m[1], false);
                                                 $t = $m[2];
                                             } else {
                                                 if (preg_match('/\\Atag(?:v|-?val|-?value)(?:\\s*:\\s*|\\s+)(' . TAG_REGEX . ')(.*)\\z/is', $t, $m) || preg_match('/\\Atag(?:v|-?val|-?value)\\s*\\(\\s*(' . TAG_REGEX . ')\\s*\\)(.*)\\z/is', $t, $m)) {
                                                     $e = new TagFexpr($m[1], true);
                                                     $t = $m[2];
                                                 } else {
                                                     if (preg_match('/\\A(r|re|rev|review|r(?:|e|ev|eview)type|(?:|r|re|rev|review)round|reviewer|r(?:|e|ev|eview)(?:|au)words)(?::|(?=#))\\s*' . self::ARGUMENT_REGEX . '(.*)\\z/is', $t, $m)) {
                                                         $e = $this->_reviewer_decoration($this->_reviewer_base($m[1]), $m[2]);
                                                         $t = $m[3];
                                                     } else {
                                                         if (preg_match('/\\A((?:r|re|rev|review)(?:type|round|(?:|au)words)|(?:round|reviewer))\\b(.*)\\z/is', $t, $m)) {
                                                             $e = $this->_reviewer_base($m[1]);
                                                             $t = $m[2];
                                                         } else {
                                                             if (preg_match('/\\A(my|all|any|avg|average|mean|median|quantile|count|min|max|atminof|atmaxof|argmin|argmax|std(?:d?ev(?:_pop|_samp|[_.][ps])?)?|sum|var(?:iance)?(?:_pop|_samp|[_.][ps])?|wavg)\\b(.*)\\z/is', $t, $m)) {
                                                                 $t = $m[2];
                                                                 if (!($e = $this->_parse_function($m[1], $t, true))) {
                                                                     return null;
                                                                 }
                                                             } else {
                                                                 if (preg_match('/\\A(greatest|least|round|floor|trunc|ceil|log|sqrt|pow|exp)\\b(.*)\\z/is', $t, $m)) {
                                                                     $t = $m[2];
                                                                     if (!($e = $this->_parse_function($m[1], $t, false))) {
                                                                         return null;
                                                                     }
                                                                 } else {
                                                                     if (preg_match('/\\Anull\\b(.*)\\z/s', $t, $m)) {
                                                                         $e = ConstantFexpr::cnull();
                                                                         $t = $m[1];
                                                                     } else {
                                                                         if (preg_match('/\\A(?:is:?)?(rev?|pc(?:rev?)?|pri(?:mary)?|sec(?:ondary)?|ext(?:ernal)?)\\b(.*)\\z/is', $t, $m)) {
                                                                             $rt = ReviewSearchMatcher::parse_review_type($m[1]);
                                                                             $op = $rt == 0 || $rt == REVIEW_PC ? ">=" : "==";
                                                                             $e = new Fexpr($op, new RevtypeFexpr(), new ConstantFexpr($rt, Fexpr::FREVTYPE));
                                                                             $t = $m[2];
                                                                         } else {
                                                                             if (preg_match('/\\Atopicscore\\b(.*)\\z/is', $t, $m)) {
                                                                                 $e = new TopicScoreFexpr();
                                                                                 $t = $m[1];
                                                                             } else {
                                                                                 if (preg_match('/\\Aconf(?:lict)?\\b(.*)\\z/is', $t, $m)) {
                                                                                     $e = new ConflictFexpr(false);
                                                                                     $t = $m[1];
                                                                                 } else {
                                                                                     if (preg_match('/\\Apcconf(?:lict)?\\b(.*)\\z/is', $t, $m)) {
                                                                                         $e = new ConflictFexpr(true);
                                                                                         $t = $m[1];
                                                                                     } else {
                                                                                         if (preg_match('/\\A(?:rev)?pref\\b(.*)\\z/is', $t, $m)) {
                                                                                             $e = new PrefFexpr(false);
                                                                                             $t = $m[1];
                                                                                         } else {
                                                                                             if (preg_match('/\\A(?:rev)?prefexp(?:ertise)?\\b(.*)\\z/is', $t, $m)) {
                                                                                                 $e = new PrefFexpr(true);
                                                                                                 $t = $m[1];
                                                                                             } else {
                                                                                                 if (preg_match('/\\A([A-Za-z0-9_]+|\\".*?\\")(.*)\\z/s', $t, $m) && $m[1] !== "\"\"" && !preg_match('/\\A\\s*\\(/', $m[2])) {
                                                                                                     $field = $m[1];
                                                                                                     $t = $m[2];
                                                                                                     if ($quoted = $field[0] === "\"") {
                                                                                                         $field = substr($field, 1, strlen($field) - 2);
                                                                                                     }
                                                                                                     if (($f = ReviewForm::field_search($field)) && $f->has_options) {
                                                                                                         $e = new ScoreFexpr($f);
                                                                                                     } else {
                                                                                                         if (!$quoted) {
                                                                                                             $e = new ConstantFexpr($field, false);
                                                                                                         } else {
                                                                                                             return null;
                                                                                                         }
                                                                                                     }
                                                                                                 }
                                                                                             }
                                                                                         }
                                                                                     }
                                                                                 }
                                                                             }
                                                                         }
                                                                     }
                                                                 }
                                                             }
                                                         }
                                                     }
                                                 }
                                             }
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     if (!$e) {
         return null;
     }
     $e->set_landmark($lpos, -strlen($t));
     while (1) {
         if (($t = ltrim($t)) === "") {
             return $e;
         } else {
             if (preg_match(self::BINARY_OPERATOR_REGEX, $t, $m)) {
                 $op = $m[0];
                 $tn = substr($t, strlen($m[0]));
             } else {
                 if (preg_match('/\\A(and|or)([\\s(].*|)\\z/i', $t, $m)) {
                     $op = strlen($m[1]) == 3 ? "&&" : "||";
                     $tn = $m[2];
                 } else {
                     if (!$in_qc && substr($t, 0, 1) === ":") {
                         $op = ":";
                         $tn = substr($t, 1);
                     } else {
                         return $e;
                     }
                 }
             }
         }
         $opprec = self::$opprec[$op];
         if ($opprec < $level) {
             return $e;
         }
         $t = $tn;
         $op = get(self::$_oprewrite, $op) ?: $op;
         if (!($e2 = $this->_parse_expr($t, get(self::$_oprassoc, $op) ? $opprec : $opprec + 1, $in_qc))) {
             return null;
         }
         $e = new Fexpr($op, $e, $e2);
         $e->set_landmark($lpos, -strlen($t));
     }
 }
Пример #21
0
 public function completion_name()
 {
     if ($this->score && ($ff = ReviewForm::field($this->score))) {
         return $ff->abbreviation;
     } else {
         return null;
     }
 }
Пример #22
0
 private static function check_review_author_seen($prow, $rrow, $contact, $no_update = false)
 {
     global $Now;
     if ($rrow && !get($rrow, "reviewAuthorSeen") && $contact->act_author_view($prow) && !$contact->is_actas_user()) {
         $rrow->reviewAuthorSeen = $Now;
         if (!$no_update) {
             if (!self::$review_author_seen) {
                 register_shutdown_function("ReviewForm::update_review_author_seen");
                 self::$review_author_seen = array();
             }
             self::$review_author_seen[] = $rrow->reviewId;
         }
     }
 }
Пример #23
0
 function _searchQueryWord($word, $report_error)
 {
     global $Conf;
     // check for paper number or "#TAG"
     if (preg_match('/\\A#?(\\d+)(?:-#?(\\d+))?\\z/', $word, $m)) {
         $m[2] = isset($m[2]) && $m[2] ? $m[2] : $m[1];
         return new SearchTerm("pn", 0, array(range($m[1], $m[2]), array()));
     } else {
         if (substr($word, 0, 1) === "#") {
             $qe = $this->_searchQueryWord("tag:" . $word, false);
             if (!$qe->is_false()) {
                 return $qe;
             }
         }
     }
     // Allow searches like "ovemer>2"; parse as "ovemer:>2".
     if (preg_match('/\\A([-_A-Za-z0-9]+)((?:[=!<>]=?|≠|≤|≥)[^:]+)\\z/', $word, $m)) {
         $qe = $this->_searchQueryWord($m[1] . ":" . $m[2], false);
         if (!$qe->is_false()) {
             return $qe;
         }
     }
     $keyword = null;
     if (($colon = strpos($word, ":")) > 0) {
         $x = substr($word, 0, $colon);
         if (strpos($x, '"') === false) {
             $keyword = get(self::$_keywords, $x) ?: $x;
             $word = substr($word, $colon + 1);
             if ($word === false) {
                 $word = "";
             }
         }
     }
     // Treat unquoted "*", "ANY", and "ALL" as special; return true.
     if ($word === "*" || $word === "ANY" || $word === "ALL" || $word === "") {
         return new SearchTerm("t");
     } else {
         if ($word === "NONE") {
             return new SearchTerm("f");
         }
     }
     $qword = $word;
     $quoted = $word[0] === '"';
     $negated = false;
     if ($quoted) {
         $word = str_replace('*', '\\*', preg_replace('/(?:\\A"|"\\z)/', '', $word));
     }
     if ($keyword === "notag") {
         $keyword = "tag";
         $negated = true;
     }
     $qt = array();
     if ($keyword ? $keyword === "ti" : isset($this->fields["ti"])) {
         $this->_searchField($word, "ti", $qt);
     }
     if ($keyword ? $keyword === "ab" : isset($this->fields["ab"])) {
         $this->_searchField($word, "ab", $qt);
     }
     if ($keyword ? $keyword === "au" : isset($this->fields["au"])) {
         $this->_searchAuthors($word, $qt, $keyword, $quoted);
     }
     if ($keyword ? $keyword === "co" : isset($this->fields["co"])) {
         $this->_searchField($word, "co", $qt);
     }
     if ($keyword ? $keyword === "re" : isset($this->fields["re"])) {
         $this->_search_reviewer($qword, "re", $qt);
     } else {
         if ($keyword && get(self::$_canonical_review_keywords, $keyword)) {
             $this->_search_reviewer($qword, $keyword, $qt);
         }
     }
     if (preg_match('/\\A(?:(?:draft-?)?\\w*resp(?:onse)|\\w*resp(?:onse)?(-?draft)?|cmt|aucmt|anycmt)\\z/', $keyword)) {
         $this->_search_comment($word, $keyword, $qt, $quoted);
     }
     if ($keyword === "pref" && $this->amPC) {
         $this->_search_revpref($word, $qt, $quoted, false);
     }
     if ($keyword === "prefexp" && $this->amPC) {
         $this->_search_revpref($word, $qt, $quoted, true);
     }
     foreach (array("lead", "shepherd", "manager") as $ctype) {
         if ($keyword === $ctype) {
             $x = $this->_one_pc_matcher($word, $quoted);
             $qt[] = new SearchTerm("pf", self::F_XVIEW, array("{$ctype}ContactId", $x));
             if ($ctype === "manager" && $word === "me" && !$quoted && $this->privChair) {
                 $qt[] = new SearchTerm("pf", self::F_XVIEW, array("{$ctype}ContactId", "=0"));
             }
         }
     }
     if (($keyword ? $keyword === "tag" : isset($this->fields["tag"])) || $keyword === "order" || $keyword === "rorder") {
         $this->_search_tags($word, $keyword, $qt);
     }
     if ($keyword === "color") {
         $this->_search_color($word, $qt);
     }
     if ($keyword === "topic") {
         $type = "topic";
         $value = null;
         if ($word === "none" || $word === "any") {
             $value = $word;
         } else {
             $x = strtolower(simplify_whitespace($word));
             $tids = array();
             foreach ($Conf->topic_map() as $tid => $tname) {
                 if (strstr(strtolower($tname), $x) !== false) {
                     $tids[] = $tid;
                 }
             }
             if (count($tids) == 0 && $word !== "none" && $word !== "any") {
                 $this->warn("“" . htmlspecialchars($x) . "” does not match any defined paper topic.");
                 $type = "f";
             } else {
                 $value = $tids;
             }
         }
         $qt[] = new SearchTerm($type, self::F_XVIEW, $value);
     }
     if ($keyword === "option") {
         $this->_search_options($word, $qt, true);
     }
     if ($keyword === "status" || $keyword === "is") {
         $this->_search_status($word, $qt, $quoted, true);
     }
     if ($keyword === "decision") {
         $this->_search_status($word, $qt, $quoted, false);
     }
     if ($keyword === "conflict" && $this->amPC) {
         $this->_search_conflict($word, $qt, $quoted, false);
     }
     if ($keyword === "pcconflict" && $this->amPC) {
         $this->_search_conflict($word, $qt, $quoted, true);
     }
     if ($keyword === "reconflict" && $this->privChair) {
         $this->_searchReviewerConflict($word, $qt, $quoted);
     }
     if ($keyword === "round" && $this->amPC) {
         $this->reviewAdjust = true;
         if ($word === "none") {
             $qt[] = new SearchTerm("revadj", 0, array("round" => array(0)));
         } else {
             if ($word === "any") {
                 $qt[] = new SearchTerm("revadj", 0, array("round" => range(1, count($Conf->round_list()) - 1)));
             } else {
                 $x = simplify_whitespace($word);
                 $rounds = Text::simple_search($x, $Conf->round_list());
                 if (count($rounds) == 0) {
                     $this->warn("“" . htmlspecialchars($x) . "” doesn’t match a review round.");
                     $qt[] = new SearchTerm("f");
                 } else {
                     $qt[] = new SearchTerm("revadj", 0, array("round" => array_keys($rounds)));
                 }
             }
         }
     }
     if ($keyword === "rate") {
         $this->_searchReviewRatings($word, $qt);
     }
     if ($keyword === "has") {
         $this->_search_has($word, $qt, $quoted);
     }
     if ($keyword === "formula") {
         $this->_search_formula($word, $qt, $quoted);
     }
     if ($keyword === "ss" && $this->amPC) {
         if ($nextq = self::_expand_saved_search($word, $this->_ssRecursion)) {
             $this->_ssRecursion[$word] = true;
             $qe = $this->_searchQueryType($nextq);
             unset($this->_ssRecursion[$word]);
         } else {
             $qe = null;
         }
         if (!$qe && $nextq === false) {
             $this->warn("Saved search “" . htmlspecialchars($word) . "” is incorrectly defined in terms of itself.");
         } else {
             if (!$qe && !$Conf->setting_data("ss:{$word}")) {
                 $this->warn("There is no “" . htmlspecialchars($word) . "” saved search.");
             } else {
                 if (!$qe) {
                     $this->warn("The “" . htmlspecialchars($word) . "” saved search is defined incorrectly.");
                 }
             }
         }
         $qt[] = $qe ?: new SearchTerm("f");
     }
     if ($keyword === "HEADING") {
         $heading = simplify_whitespace($word);
         $qt[] = SearchTerm::make_float(["heading" => $heading]);
     }
     if ($keyword === "show" || $keyword === "hide" || $keyword === "edit" || $keyword === "sort" || $keyword === "showsort" || $keyword === "editsort") {
         $editing = strpos($keyword, "edit") !== false;
         $sorting = strpos($keyword, "sort") !== false;
         $views = array();
         $a = $keyword === "hide" ? false : ($editing ? "edit" : true);
         $word = simplify_whitespace($word);
         $ch1 = substr($word, 0, 1);
         if ($ch1 === "-" && !$sorting) {
             list($a, $word) = array(false, substr($word, 1));
         }
         $wtype = $word;
         if ($sorting) {
             $sort = self::parse_sorter($wtype);
             $wtype = $sort->type;
         }
         if ($wtype !== "" && $keyword !== "sort") {
             $views[$wtype] = $a;
         }
         $f = array("view" => $views);
         if ($sorting) {
             $f["sort"] = array($word);
         }
         $qt[] = SearchTerm::make_float($f);
     }
     // Finally, look for a review field.
     if ($keyword && !isset(self::$_keywords[$keyword]) && count($qt) == 0) {
         if ($field = ReviewForm::field_search($keyword)) {
             $this->_search_review_field($word, $field, $qt, $quoted);
         } else {
             if (!$this->_search_options("{$keyword}:{$word}", $qt, false) && $report_error) {
                 $this->warn("Unrecognized keyword “" . htmlspecialchars($keyword) . "”.");
             }
         }
     }
     $qe = SearchTerm::make_op("or", $qt);
     return $negated ? SearchTerm::make_not($qe) : $qe;
 }
Пример #24
0
 function run(Contact $user, $qreq, $ssel)
 {
     global $Conf;
     $result = Dbl::qe_raw($Conf->paperQuery($user, array("paperId" => $ssel->selection(), "allReviewScores" => 1, "reviewerName" => 1)));
     // compose scores; NB chair is always forceShow
     $errors = array();
     $texts = $any_scores = array();
     $any_decision = $any_reviewer_identity = false;
     $rf = ReviewForm::get();
     $bad_pid = -1;
     while ($row = PaperInfo::fetch($result, $user)) {
         if (!$row->reviewSubmitted || $row->paperId == $bad_pid) {
             /* skip */
         } else {
             if ($whyNot = $user->perm_view_review($row, null, true)) {
                 $errors[] = whyNotText($whyNot, "view reviews for") . "<br />";
                 $bad_pid = $row->paperId;
             } else {
                 $a = array("paper" => $row->paperId, "title" => $row->title);
                 if ($row->outcome && $user->can_view_decision($row, true)) {
                     $a["decision"] = $any_decision = $Conf->decision_name($row->outcome);
                 }
                 $view_bound = $user->view_score_bound($row, $row, true);
                 $this_scores = false;
                 foreach ($rf->forder as $field => $f) {
                     if ($f->view_score > $view_bound && $f->has_options && ($row->{$field} || $f->allow_empty)) {
                         $a[$f->abbreviation] = $f->unparse_value($row->{$field});
                         $any_scores[$f->abbreviation] = $this_scores = true;
                     }
                 }
                 if ($user->can_view_review_identity($row, $row, true)) {
                     $any_reviewer_identity = true;
                     $a["email"] = $row->reviewEmail;
                     $a["reviewername"] = trim($row->reviewFirstName . " " . $row->reviewLastName);
                 }
                 if ($this_scores) {
                     arrayappend($texts[$row->paperId], $a);
                 }
             }
         }
     }
     if (count($texts)) {
         $header = array("paper", "title");
         if ($any_decision) {
             $header[] = "decision";
         }
         if ($any_reviewer_identity) {
             array_push($header, "reviewername", "email");
         }
         $header = array_merge($header, array_keys($any_scores));
         downloadCSV($ssel->reorder($texts), $header, "scores", ["selection" => true]);
     } else {
         if (!count($errors)) {
             $errors[] = "No papers selected.";
         }
         Conf::msg_error(join("", $errors));
     }
 }
 function importReviewForms()
 {
     assert($this->xml->name == 'reviewForms');
     $journal = $this->journal;
     $reviewFormDao =& DAORegistry::getDAO('ReviewFormDAO');
     $reviewFormElementDao =& DAORegistry::getDAO('ReviewFormElementDAO');
     $this->nextElement();
     while ($this->xml->name == 'reviewForm') {
         $reviewFormXML = $this->getCurrentElementAsDom();
         $reviewForm = new ReviewForm();
         $reviewForm->setSequence((int) $reviewFormXML->sequence);
         $reviewForm->setActive((int) $reviewFormXML->active);
         $reviewForm->setAssocType(ASSOC_TYPE_JOURNAL);
         $reviewForm->setAssocId($this->journal->getId());
         $reviewFormDao->insertObject($reviewForm);
         $this->idTranslationTable->register(INTERNAL_TRANSFER_OBJECT_REVIEW_FORM, (int) $reviewFormXML->oldId, $reviewForm->getId());
         foreach ($reviewFormXML->reviewElement as $reviewElementXML) {
             $reviewFormElement = new ReviewFormElement();
             $reviewFormElement->setReviewFormId($reviewForm->getId());
             $reviewFormElement->setSequence((int) $reviewElementXML->sequence);
             $reviewFormElement->setElementType((int) $reviewElementXML->elementType);
             $reviewFormElement->setRequired((int) $reviewElementXML->required);
             $reviewFormElement->setIncluded((int) $reviewElementXML->included);
             $reviewFormElementDao->insertObject($reviewFormElement);
             $this->idTranslationTable->register(INTERNAL_TRANSFER_OBJECT_REVIEW_FORM_ELEMENT, (int) $reviewElementXML->oldId, $reviewFormElement->getId());
             $this->restoreDataObjectSettings($reviewFormElementDao, $reviewElementXML->settings, 'review_form_element_settings', 'review_form_element_id', $reviewFormElement->getId());
         }
         $this->restoreDataObjectSettings($reviewFormDao, $reviewFormXML->settings, 'review_form_settings', 'review_form_id', $reviewForm->getId());
         $this->nextElement();
     }
 }
 private function get_reviews()
 {
     global $Conf;
     if ($this->rrow) {
         $rrows = array($this->rrow);
     } else {
         $result = Dbl::qe("select PaperReview.*,\n                ContactInfo.firstName, ContactInfo.lastName, ContactInfo.email\n                from PaperReview\n                join ContactInfo on (ContactInfo.contactId=PaperReview.contactId)\n                where PaperReview.paperId=" . $this->row->paperId . " order by reviewOrdinal");
         $rrows = edb_orows($result);
     }
     // save old au_seerev setting, and reset it so authors can see them.
     if (!($au_seerev = $Conf->au_seerev)) {
         $Conf->au_seerev = Conf::AUSEEREV_YES;
     }
     $text = "";
     $rf = ReviewForm::get();
     foreach ($rrows as $row) {
         if ($row->reviewSubmitted && $this->permissionContact->can_view_review($this->row, $row, false)) {
             $text .= $rf->pretty_text($this->row, $row, $this->permissionContact, $this->no_send) . "\n";
         }
     }
     $Conf->au_seerev = $au_seerev;
     if ($text === "" && $au_seerev == Conf::AUSEEREV_UNLESSINCOMPLETE && count($rrows)) {
         $text = "[Reviews are hidden since you have incomplete reviews of your own.]\n";
     }
     return $text;
 }