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; }
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); } }
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 “order:{$tag}”</a>."); } } }