예제 #1
0
 function perm_change_tag(PaperInfo $prow, $tag, $previndex, $index, $forceShow = null)
 {
     global $Conf;
     if ($this->can_change_tag($prow, $tag, $previndex, $index, $forceShow)) {
         return null;
     }
     $rights = $this->rights($prow, $forceShow);
     $whyNot = $prow->initial_whynot();
     $whyNot["tag"] = $tag;
     if (!$this->isPC) {
         $whyNot["permission"] = true;
     } else {
         if ($rights->conflict_type > 0) {
             $whyNot["conflict"] = true;
             if ($rights->allow_administer) {
                 $whyNot["forceShow"] = true;
             }
         } else {
             if (!$Conf->timePCViewPaper($prow, false)) {
                 if ($prow->timeWithdrawn > 0) {
                     $whyNot["withdrawn"] = true;
                 } else {
                     $whyNot["notSubmitted"] = true;
                 }
             } else {
                 $tag = TagInfo::base($tag);
                 $twiddle = strpos($tag, "~");
                 if ($twiddle === 0 && $tag[1] === "~" || $twiddle > 0 && substr($tag, 0, $twiddle) != $this->contactId) {
                     $whyNot["otherTwiddleTag"] = true;
                 } else {
                     if ($twiddle !== false) {
                         $whyNot["voteTagNegative"] = true;
                     } else {
                         $t = TagInfo::defined_tag($tag);
                         if ($t && $t->vote) {
                             $whyNot["voteTag"] = true;
                         } else {
                             $whyNot["chairTag"] = true;
                         }
                     }
                 }
             }
         }
     }
     return $whyNot;
 }
예제 #2
0
 public function editable_tags(Contact $user)
 {
     $tags = $this->viewable_tags($user);
     if ($tags !== "") {
         $privChair = $user->allow_administer($this);
         $dt = TagInfo::defined_tags();
         $etags = array();
         foreach (explode(" ", $tags) as $t) {
             if (!($t === "" || ($v = $dt->check(TagInfo::base($t))) && ($v->vote || $v->approval || !$privChair && (!$user->privChair || !$v->sitewide) && ($v->chair || $v->rank)))) {
                 $etags[] = $t;
             }
         }
         $tags = join(" ", $etags);
     }
     return $tags;
 }
예제 #3
0
function do_tags()
{
    global $Conf, $Me, $papersel;
    // check tags
    $tagger = new Tagger($Me);
    $t1 = array();
    $errors = array();
    foreach (preg_split('/[\\s,]+/', (string) @$_REQUEST["tag"]) as $t) {
        if ($t === "") {
            /* nada */
        } else {
            if (!($t = $tagger->check($t, Tagger::NOPRIVATE))) {
                $errors[] = $tagger->error_html;
            } else {
                if (TagInfo::base($t) === "pc") {
                    $errors[] = "The “pc” user tag is set automatically for all PC members.";
                } else {
                    $t1[] = $t;
                }
            }
        }
    }
    if (count($errors)) {
        return Conf::msg_error(join("<br>", $errors));
    } else {
        if (!count($t1)) {
            return $Conf->warnMsg("Nothing to do.");
        }
    }
    // modify database
    Dbl::qe("lock tables ContactInfo write");
    Conf::$no_invalidate_caches = true;
    $users = array();
    if ($_REQUEST["tagtype"] === "s") {
        // erase existing tags
        $likes = array();
        $removes = array();
        foreach ($t1 as $t) {
            list($tag, $index) = TagInfo::split_index($t);
            $removes[] = $t;
            $likes[] = "contactTags like " . Dbl::utf8ci("'% " . sqlq_for_like($tag) . "#%'");
        }
        foreach (Dbl::fetch_first_columns(Dbl::qe("select contactId from ContactInfo where " . join(" or ", $likes))) as $cid) {
            $users[(int) $cid] = (object) array("id" => (int) $cid, "add_tags" => [], "remove_tags" => $removes);
        }
    }
    // account for request
    $key = $_REQUEST["tagtype"] === "d" ? "remove_tags" : "add_tags";
    foreach ($papersel as $cid) {
        if (!isset($users[(int) $cid])) {
            $users[(int) $cid] = (object) array("id" => (int) $cid, "add_tags" => [], "remove_tags" => []);
        }
        $users[(int) $cid]->{$key} = array_merge($users[(int) $cid]->{$key}, $t1);
    }
    // apply modifications
    foreach ($users as $cid => $cj) {
        $us = new UserStatus(array("send_email" => false));
        if (!$us->save($cj)) {
            $errors = array_merge($errors, $us->error_messages());
        }
    }
    Dbl::qe("unlock tables");
    Conf::$no_invalidate_caches = false;
    $Conf->invalidateCaches(["pc" => true]);
    // report
    if (!count($errors)) {
        $Conf->confirmMsg("Tags saved.");
        redirectSelf(array("tagact" => null, "tag" => null));
    } else {
        Conf::msg_error(join("<br>", $errors));
    }
}
예제 #4
0
 function run(Contact $user, $qreq, $ssel)
 {
     global $Conf;
     $papers = $ssel->selection();
     $act = $qreq->tagfn;
     $tagreq = trim(str_replace(",", " ", (string) $qreq->tag));
     $tags = preg_split('/\\s+/', $tagreq);
     if ($act == "da") {
         $otags = $tags;
         foreach ($otags as $t) {
             $tags[] = "all~" . preg_replace(',\\A.*~([^~]+)\\z', '$1', $t);
         }
         $act = "d";
     } else {
         if ($act == "sor") {
             shuffle($papers);
         }
     }
     $x = array("action,paper,tag\n");
     if ($act == "s" || $act == "so" || $act == "sos" || $act == "sor") {
         foreach ($tags as $t) {
             $x[] = "cleartag,all," . TagInfo::base($t) . "\n";
         }
     }
     if ($act == "s" || $act == "a") {
         $action = "tag";
     } else {
         if ($act == "d") {
             $action = "cleartag";
         } else {
             if ($act == "so" || $act == "sor" || $act == "ao") {
                 $action = "nexttag";
             } else {
                 if ($act == "sos" || $act == "aos") {
                     $action = "seqnexttag";
                 } else {
                     $action = null;
                 }
             }
         }
     }
     $assignset = new AssignmentSet($user, $user->privChair);
     if (count($papers) && $action) {
         foreach ($papers as $p) {
             foreach ($tags as $t) {
                 $x[] = "{$action},{$p},{$t}\n";
             }
         }
         $assignset->parse(join("", $x));
     } else {
         if (count($papers) && $act == "cr" && $user->privChair) {
             $source_tag = trim((string) $qreq->tagcr_source);
             if ($source_tag == "") {
                 $source_tag = substr($tagreq, 0, 2) == "~~" ? substr($tagreq, 2) : $tagreq;
             }
             $tagger = new Tagger($user);
             if ($tagger->check($tagreq, Tagger::NOPRIVATE | Tagger::NOVALUE) && $tagger->check($source_tag, Tagger::NOPRIVATE | Tagger::NOCHAIR | Tagger::NOVALUE)) {
                 $r = new PaperRank($source_tag, $tagreq, $papers, $qreq->tagcr_gapless, "Search", "search");
                 $r->run($qreq->tagcr_method);
                 $r->apply($assignset);
                 $assignset->finish();
                 if ($qreq->q === "") {
                     $qreq->q = "order:{$tagreq}";
                 }
             } else {
                 $assignset->error($tagger->error_html);
             }
         }
     }
     if ($errors = join("<br />\n", $assignset->errors_html())) {
         if ($assignset->has_assigners()) {
             Conf::msg_warning("Some tag assignments were ignored:<br />\n{$errors}");
             $assignset->clear_errors();
         } else {
             Conf::msg_error($errors);
         }
     }
     $success = $assignset->execute();
     if (!$Conf->headerPrinted && $qreq->ajax) {
         $Conf->ajaxExit(array("ok" => $success));
     } else {
         if (!$Conf->headerPrinted && $success) {
             if (!$errors) {
                 $Conf->confirmMsg("Tags saved.");
             }
             $args = array("atab" => "tag");
             foreach (array("tag", "tagfn", "tagcr_method", "tagcr_source", "tagcr_gapless") as $arg) {
                 if (isset($qreq[$arg])) {
                     $args[$arg] = $qreq[$arg];
                 }
             }
             redirectSelf($args);
         }
     }
 }
 function content($fieldId, $row)
 {
     global $Conf;
     switch ($fieldId) {
         case self::FIELD_NAME:
             $t = Text::name_html($row);
             if (trim($t) == "") {
                 $t = "[No name]";
             }
             $t = '<span class="taghl">' . $t . '</span>';
             if ($this->contact->privChair) {
                 $t = "<a href=\"" . hoturl("profile", "u=" . urlencode($row->email) . $this->contactLinkArgs) . "\"" . ($row->disabled ? " class='uu'" : "") . ">{$t}</a>";
             }
             if ($row->roles & Contact::ROLE_CHAIR) {
                 $t .= ' <span class="pcrole">(chair)</span>';
             } else {
                 if (($row->roles & (Contact::ROLE_ADMIN | Contact::ROLE_PC)) == (Contact::ROLE_ADMIN | Contact::ROLE_PC)) {
                     $t .= ' <span class="pcrole">(PC, sysadmin)</span>';
                 } else {
                     if ($row->roles & Contact::ROLE_ADMIN) {
                         $t .= ' <span class="pcrole">(sysadmin)</span>';
                     } else {
                         if ($row->roles & Contact::ROLE_PC && $this->limit != "pc") {
                             $t .= ' <span class="pcrole">(PC)</span>';
                         }
                     }
                 }
             }
             if ($this->contact->privChair && $row->email != $this->contact->email) {
                 $t .= " <a href=\"" . hoturl("index", "actas=" . urlencode($row->email)) . "\">" . Ht::img("viewas.png", "[Act as]", array("title" => "Act as " . Text::name_text($row))) . "</a>";
             }
             if ($row->disabled && $this->contact->isPC) {
                 $t .= ' <span class="hint">(disabled)</span>';
             }
             return $t;
         case self::FIELD_EMAIL:
             if (!$this->contact->isPC) {
                 return "";
             }
             $e = htmlspecialchars($row->email);
             if (strpos($row->email, "@") === false) {
                 return $e;
             } else {
                 return "<a href=\"mailto:{$e}\">{$e}</a>";
             }
         case self::FIELD_AFFILIATION:
         case self::FIELD_AFFILIATION_ROW:
             return htmlspecialchars($row->affiliation);
         case self::FIELD_LASTVISIT:
             if (!$row->lastLogin) {
                 return "Never";
             }
             return $Conf->printableTimeShort($row->lastLogin);
         case self::FIELD_SELECTOR:
         case self::FIELD_SELECTOR_ON:
             $this->any->sel = true;
             $c = "";
             if ($fieldId == self::FIELD_SELECTOR_ON) {
                 $c = " checked='checked'";
             }
             return "<input type='checkbox' class='cb' name='pap[]' value='{$row->contactId}' tabindex='1' id='psel{$this->count}' onclick='rangeclick(event,this)' {$c}/>";
         case self::FIELD_HIGHTOPICS:
         case self::FIELD_LOWTOPICS:
             if (!defval($row, "topicIds")) {
                 return "";
             }
             $wanthigh = $fieldId == self::FIELD_HIGHTOPICS;
             $topics = array_combine(explode(",", $row->topicIds), explode(",", $row->topicInterest));
             $nt = $nti = array();
             foreach ($topics as $k => $v) {
                 if ($wanthigh ? $v > 0 : $v < 0) {
                     $nt[] = $k;
                     $nti[] = $v;
                 }
             }
             if (count($nt)) {
                 return PaperInfo::unparse_topic_list_html($nt, $nti, true);
             } else {
                 return "";
             }
         case self::FIELD_REVIEWS:
             if (!$row->numReviews && !$row->numReviewsSubmitted) {
                 return "";
             }
             $a1 = "<a href=\"" . hoturl("search", "t=s&amp;q=re:" . urlencode($row->email)) . "\">";
             if ($row->numReviews == $row->numReviewsSubmitted) {
                 return "{$a1}<b>{$row->numReviewsSubmitted}</b></a>";
             } else {
                 return "{$a1}<b>{$row->numReviewsSubmitted}</b>/{$row->numReviews}</a>";
             }
         case self::FIELD_LEADS:
             if (!$row->numLeads) {
                 return "";
             }
             return "<a href=\"" . hoturl("search", "t=s&amp;q=lead:" . urlencode($row->email)) . "\">{$row->numLeads}</a>";
         case self::FIELD_SHEPHERDS:
             if (!$row->numShepherds) {
                 return "";
             }
             return "<a href=\"" . hoturl("search", "t=s&amp;q=shepherd:" . urlencode($row->email)) . "\">{$row->numShepherds}</a>";
         case self::FIELD_REVIEW_RATINGS:
             if (!$row->numReviews && !$row->numReviewsSubmitted || !$row->numRatings) {
                 return "";
             }
             $a = array();
             $b = array();
             if ($row->sumRatings > 0) {
                 $a[] = $row->sumRatings . " positive";
                 $b[] = "<a href=\"" . hoturl("search", "q=re:" . urlencode($row->email) . "+rate:%2B") . "\">+" . $row->sumRatings . "</a>";
             }
             if ($row->sumRatings < $row->numRatings) {
                 $a[] = $row->numRatings - $row->sumRatings . " negative";
                 $b[] = "<a href=\"" . hoturl("search", "q=re:" . urlencode($row->email) . "+rate:-") . "\">&minus;" . ($row->numRatings - $row->sumRatings) . "</a>";
             }
             return "<span class='hastitle' title='" . join(", ", $a) . "'>" . join(" ", $b) . "</span>";
         case self::FIELD_PAPERS:
             if (!$row->paperIds) {
                 return "";
             }
             $x = explode(",", $row->paperIds);
             sort($x, SORT_NUMERIC);
             foreach ($x as &$v) {
                 $v = '<a href="' . hoturl("paper", "p={$v}") . '">' . $v . '</a>';
             }
             $ls = "p/s/";
             if ($this->limit == "auuns" || $this->limit == "all") {
                 $ls = "p/all/";
             }
             $ls = htmlspecialchars($ls . urlencode("au:" . $row->email));
             return '<div class="has_hotcrp_list" data-hotcrp-list="' . $ls . '">' . join(", ", $x) . '</div>';
         case self::FIELD_REVIEW_PAPERS:
             if (!$row->paperIds) {
                 return "";
             }
             $pids = explode(",", $row->paperIds);
             $rids = explode(",", $row->reviewIds);
             $ords = explode(",", $row->reviewOrdinals);
             $spids = $pids;
             sort($spids, SORT_NUMERIC);
             $m = array();
             for ($i = 0; $i != count($pids); ++$i) {
                 if ($ords[$i]) {
                     $url = hoturl("paper", "p=" . $pids[$i] . "#r" . $pids[$i] . unparseReviewOrdinal($ords[$i]));
                 } else {
                     $url = hoturl("review", "p=" . $pids[$i] . "&amp;r=" . $rids[$i]);
                 }
                 $m[$pids[$i]] = "<a href=\"{$url}\">" . $pids[$i] . "</a>";
             }
             ksort($m, SORT_NUMERIC);
             $ls = htmlspecialchars("p/s/" . urlencode("re:" . $row->email));
             return '<div class="has_hotcrp_list" data-hotcrp-list="' . $ls . '">' . join(", ", $m) . '</div>';
         case self::FIELD_TAGS:
             if ($this->contact->isPC && ($tags = $row->viewable_tags($this->contact))) {
                 $x = [];
                 foreach (TagInfo::split($tags) as $t) {
                     $x[] = '<a class="qq nw" href="' . hoturl("users", "t=%23" . TagInfo::base($t)) . '">' . $this->tagger->unparse_hashed($t) . '</a>';
                 }
                 return join(" ", $x);
             }
             return "";
         case self::FIELD_COLLABORATORS:
             if (!$this->contact->isPC || !($row->roles & Contact::ROLE_PC)) {
                 return "";
             }
             $t = array();
             foreach (explode("\n", $row->collaborators) as $collab) {
                 if (preg_match(',\\A(.*?)\\s*(\\(.*\\))\\s*\\z,', $collab, $m)) {
                     $t[] = '<span class="nw">' . htmlspecialchars($m[1]) . ' <span class="auaff">' . htmlspecialchars($m[2]) . '</span></span>';
                 } else {
                     if (($collab = trim($collab)) !== "" && strcasecmp($collab, "None")) {
                         $t[] = '<span class="nw">' . htmlspecialchars($collab) . '</span>';
                     }
                 }
             }
             return join("; ", $t);
         default:
             $f = ReviewForm::field($fieldId);
             if (!$f) {
                 return "";
             }
             if (!($row->roles & Contact::ROLE_PC) && !$this->contact->privChair && $this->limit != "req") {
                 return "";
             }
             $v = scoreCounts($row->{$fieldId}, $this->scoreMax[$fieldId]);
             $m = "";
             if ($v->n > 0) {
                 $m = $f->unparse_graph($v, 2, 0);
             }
             return $m;
     }
 }
예제 #6
0
 public function unparse_and_link($viewable, $alltags, $highlight = false)
 {
     $vtags = $this->unparse($viewable);
     if ($vtags === "") {
         return "";
     }
     // decorate with URL matches
     $tt = "";
     // clean $highlight
     $byhighlight = array();
     $anyhighlight = false;
     assert($highlight === false || is_array($highlight));
     if ($highlight) {
         foreach ($highlight as $h) {
             $tag = is_object($h) ? $h->tag : $h;
             if (($pos = strpos($tag, "~")) !== false) {
                 $tag = substr($tag, $pos);
             }
             $byhighlight[strtolower($tag)] = "";
         }
     }
     foreach (preg_split('/\\s+/', $vtags) as $tag) {
         if (!($base = TagInfo::base($tag))) {
             continue;
         }
         $lbase = strtolower($base);
         if ($link = $this->link($tag)) {
             $tx = '<a class="qq nw" href="' . $link . '">#' . $base . '</a>';
         } else {
             $tx = "#" . $base;
         }
         $tx .= substr($tag, strlen($base));
         if (isset($byhighlight[$lbase])) {
             $byhighlight[$lbase] .= "<strong>" . $tx . "</strong> ";
             $anyhighlight = true;
         } else {
             $tt .= $tx . " ";
         }
     }
     if ($anyhighlight) {
         return rtrim(join("", $byhighlight) . $tt);
     } else {
         return rtrim($tt);
     }
 }