public function make_column($name, $errors)
 {
     global $Me;
     $p = strpos($name, ":");
     $cids = ContactSearch::make_pc(substr($name, $p + 1), $Me)->ids;
     if (count($cids) == 0) {
         self::make_column_error($errors, "No PC member matches “" . htmlspecialchars(substr($name, $p + 1)) . "”.", 2);
     } else {
         if (count($cids) == 1) {
             $pcm = pcMembers();
             return parent::register(new PreferencePaperColumn($name, $this->editable, $pcm[$cids[0]]));
         } else {
             self::make_column_error($errors, "“" . htmlspecialchars(substr($name, $p + 1)) . "” matches more than one PC member.", 2);
         }
     }
     return null;
 }
 private function _expand_tag($tagword, $allow_star)
 {
     // see also TagAssigner
     $ret = array("");
     $twiddle = strpos($tagword, "~");
     if ($this->privChair && $twiddle > 0 && !ctype_digit(substr($tagword, 0, $twiddle))) {
         $c = substr($tagword, 0, $twiddle);
         $ret = ContactSearch::make_pc($c, $this->cid)->ids;
         if (count($ret) == 0) {
             $this->warn("“" . htmlspecialchars($c) . "” doesn’t match a PC email.");
         }
         $tagword = substr($tagword, $twiddle);
     } else {
         if ($twiddle === 0 && ($tagword === "" || $tagword[1] !== "~")) {
             $ret[0] = $this->cid;
         }
     }
     $tagger = new Tagger($this->contact);
     if (!$tagger->check("#" . $tagword, Tagger::ALLOWRESERVED | Tagger::NOVALUE | ($allow_star ? Tagger::ALLOWSTAR : 0))) {
         $this->warn($tagger->error_html);
         $ret = array();
     }
     foreach ($ret as &$x) {
         $x .= $tagword;
     }
     return $ret;
 }
예제 #3
0
 private function apply_remove($pid, $contact, AssignmentState $state, $m)
 {
     $prow = $state->prow($pid);
     // resolve twiddle portion
     if ($m[1] && $m[1] != "~~" && !ctype_digit(substr($m[1], 0, strlen($m[1]) - 1))) {
         $c = substr($m[1], 0, strlen($m[1]) - 1);
         $twiddlecids = ContactSearch::make_pc($c, $state->contact->contactId)->ids;
         if (count($twiddlecids) == 0) {
             return "“" . htmlspecialchars($c) . "” doesn’t match a PC member.";
         } else {
             if (count($twiddlecids) == 1) {
                 $m[1] = $twiddlecids[0] . "~";
             } else {
                 $m[1] = "(?:" . join("|", $twiddlecids) . ")~";
             }
         }
     }
     // resolve tag portion
     $search_ltag = null;
     if (strcasecmp($m[2], "none") == 0) {
         return;
     } else {
         if (strcasecmp($m[2], "any") == 0 || strcasecmp($m[2], "all") == 0) {
             if ($m[1]) {
                 $m[2] = "[^~]*";
             } else {
                 if ($state->contact->privChair) {
                     $m[2] = "(?:~~|" . $state->contact->contactId . "~|)[^~]*";
                 } else {
                     $m[2] = "(?:" . $state->contact->contactId . "~|)[^~]*";
                 }
             }
         } else {
             if (!preg_match(',[*(],', $m[1] . $m[2])) {
                 $search_ltag = $m[1] . $m[2];
             }
             $m[2] = str_replace("\\*", "[^~]*", preg_quote($m[2]));
         }
     }
     // resolve index comparator
     if (preg_match(',\\A(?:any|all|none|clear)\\z,i', $m[4])) {
         $m[3] = $m[4] = "";
     } else {
         if ($m[3] == "#") {
             $m[3] = "=";
         }
         $m[4] = cvtint($m[4], 0);
     }
     // if you can't view the tag, you can't clear the tag
     // (information exposure)
     if ($search_ltag && !$state->contact->can_view_tag($prow, $search_ltag, $state->override)) {
         return $this->cannot_view_error($state, $pid, $search_ltag);
     }
     // query
     $res = $state->query(array("type" => "tag", "pid" => $pid, "ltag" => $search_ltag));
     $tag_re = '{\\A' . $m[1] . $m[2] . '\\z}i';
     $vote_adjustments = array();
     foreach ($res as $x) {
         if (preg_match($tag_re, $x["ltag"]) && (!$m[3] || CountMatcher::compare($x["_index"], $m[3], $m[4])) && ($search_ltag || $state->contact->can_change_tag($prow, $x["ltag"], $x["_index"], null, $state->override))) {
             $state->remove($x);
             if ($v = TagInfo::votish_base($x["ltag"])) {
                 $vote_adjustments[$v] = true;
             }
         }
     }
     foreach ($vote_adjustments as $vtag => $v) {
         $this->account_votes($pid, $vtag, $state);
     }
 }
예제 #4
0
function setTagIndexes()
{
    global $Conf, $Me, $Error;
    $filename = null;
    if (isset($_REQUEST["upload"]) && fileUploaded($_FILES["file"])) {
        if (($text = file_get_contents($_FILES["file"]["tmp_name"])) === false) {
            Conf::msg_error("Internal error: cannot read file.");
            return;
        }
        $filename = @$_FILES["file"]["name"];
    } else {
        if (!($text = defval($_REQUEST, "data"))) {
            Conf::msg_error("Choose a file first.");
            return;
        }
    }
    $RealMe = $Me;
    $tagger = new Tagger();
    if ($tag = defval($_REQUEST, "tag")) {
        $tag = $tagger->check($tag, Tagger::NOVALUE);
    }
    $curIndex = 0;
    $lineno = 1;
    $settings = $titles = $linenos = $errors = array();
    foreach (explode("\n", rtrim(cleannl($text))) as $l) {
        if (substr($l, 0, 4) == "Tag:" || substr($l, 0, 6) == "# Tag:") {
            if (!$tag) {
                $tag = $tagger->check(trim(substr($l, $l[0] == "#" ? 6 : 4)), Tagger::NOVALUE);
            }
            ++$lineno;
            continue;
        } else {
            if ($l == "" || $l[0] == "#") {
                ++$lineno;
                continue;
            }
        }
        if (preg_match('/\\A\\s*?([Xx=]|>*|\\([-\\d]+\\))\\s+(\\d+)\\s*(.*?)\\s*\\z/', $l, $m)) {
            if (isset($settings[$m[2]])) {
                $errors[$lineno] = "Paper #{$m['2']} already given on line " . $linenos[$m[2]];
            }
            if ($m[1] == "X" || $m[1] == "x") {
                $settings[$m[2]] = null;
            } else {
                if ($m[1] == "" || $m[1] == ">") {
                    $settings[$m[2]] = $curIndex = $curIndex + 1;
                } else {
                    if ($m[1][0] == "(") {
                        $settings[$m[2]] = $curIndex = substr($m[1], 1, -1);
                    } else {
                        if ($m[1] == "=") {
                            $settings[$m[2]] = $curIndex;
                        } else {
                            $settings[$m[2]] = $curIndex = $curIndex + strlen($m[1]);
                        }
                    }
                }
            }
            $titles[$m[2]] = $m[3];
            $linenos[$m[2]] = $lineno;
        } else {
            if ($RealMe->privChair && preg_match('/\\A\\s*<\\s*([^<>]*?(|<[^<>]*>))\\s*>\\s*\\z/', $l, $m)) {
                if (count($settings) && $Me) {
                    saveTagIndexes($tag, $filename, $settings, $titles, $linenos, $errors);
                }
                $ret = ContactSearch::make_pc($m[1], $RealMe);
                $Me = null;
                if (count($ret->ids) == 1) {
                    $Me = $ret->contact(0);
                } else {
                    if (count($ret->ids) == 0) {
                        $errors[$lineno] = htmlspecialchars($m[1]) . " matches no PC member";
                    } else {
                        $errors[$lineno] = htmlspecialchars($m[1]) . " matches more than one PC member, give a full email address to disambiguate";
                    }
                }
            } else {
                if (trim($l) !== "") {
                    $errors[$lineno] = "Syntax error";
                }
            }
        }
        ++$lineno;
    }
    if (count($settings) && $Me) {
        saveTagIndexes($tag, $filename, $settings, $titles, $linenos, $errors);
    }
    $Me = $RealMe;
    if (count($errors)) {
        ksort($errors);
        if ($filename) {
            foreach ($errors as $lineno => &$error) {
                $error = '<span class="lineno">' . htmlspecialchars($filename) . ':' . $lineno . ':</span> ' . $error;
            }
        }
        $Error["tags"] = '<div class="parseerr"><p>' . join("</p>\n<p>", $errors) . '</p></div>';
    }
    if (isset($Error["tags"])) {
        Conf::msg_error($Error["tags"]);
    } else {
        if (isset($_REQUEST["setvote"])) {
            $Conf->confirmMsg("Votes saved.");
        } else {
            $Conf->confirmMsg("Ranking saved.  To view it, <a href='" . hoturl("search", "q=order:" . urlencode($tag)) . "'>search for &ldquo;order:{$tag}&rdquo;</a>.");
        }
    }
}