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 _clauseTermCheck($t, $row) { $tt = $t->type; // collect columns if ($tt === "ti" || $tt === "ab" || $tt === "au" || $tt === "co") { return $this->_clauseTermCheckField($t, $row); } else { if ($tt === "au_cid") { assert(is_array($t->value)); return $this->_clauseTermCheckFlags($t, $row) && $row->{$t->link} != 0; } else { if ($tt === "re" || $tt === "conflict" || $tt === "revpref" || $tt === "cmt" || $tt === "cmttag") { if (!$this->_clauseTermCheckFlags($t, $row)) { return false; } else { $fieldname = $t->link; return $t->value->test((int) $row->{$fieldname}); } } else { if ($tt === "pn") { if (count($t->value[0]) && array_search($row->paperId, $t->value[0]) === false) { return false; } else { if (count($t->value[1]) && array_search($row->paperId, $t->value[1]) !== false) { return false; } else { return true; } } } else { if ($tt === "pf") { if (!$this->_clauseTermCheckFlags($t, $row)) { return false; } else { $ans = true; for ($i = 0; $ans && $i < count($t->value); $i += 2) { $fieldname = $t->value[$i]; $expr = $t->value[$i + 1]; if (is_array($expr)) { $ans = in_array($row->{$fieldname}, $expr); } else { $ans = CountMatcher::compare_string($row->{$fieldname}, $expr); } } return $ans; } } else { if ($tt === "tag" || $tt === "topic") { if (!$this->_clauseTermCheckFlags($t, $row)) { return false; } $fieldname = $t->link; if ($t->value[0] === "none") { return $row->{$fieldname} == 0; } else { return $row->{$fieldname} != 0; } } else { if ($tt === "option") { if (!$this->_clauseTermCheckFlags($t, $row)) { return false; } $fieldname = $t->link; if ($row->{$fieldname} == 0) { return false; } $om = $t->value; if ($om->kind) { $ov = $row->option($om->option->id); if ($om->kind === "attachment-count" && $ov) { return CountMatcher::compare(count($ov->values), $om->compar, $om->value); } else { if ($om->kind === "attachment-name" && $ov) { $reg = self::analyze_field_preg($om->value); foreach ($ov->documents($row) as $doc) { if (self::match_field_preg($reg, $doc->filename, false)) { return true; } } } } return false; } return true; } else { if ($tt === "formula") { $formulaf = $t->link; return !!$formulaf($row, null, $this->contact); } else { if ($tt === "not") { return !$this->_clauseTermCheck($t->value[0], $row); } else { if ($tt === "and" || $tt === "and2") { foreach ($t->value as $subt) { if (!$this->_clauseTermCheck($subt, $row)) { return false; } } return true; } else { if ($tt === "or") { foreach ($t->value as $subt) { if ($this->_clauseTermCheck($subt, $row)) { return true; } } return false; } else { if ($tt === "then") { for ($i = 0; $i < $t->nthen; ++$i) { if ($this->_clauseTermCheck($t->value[$i], $row)) { return true; } } return false; } else { if ($tt === "f") { return false; } else { if ($tt === "t" || $tt === "revadj") { return true; } else { error_log("PaperSearch::_clauseTermCheck: {$tt} defaults, correctness unlikely"); return true; } } } } } } } } } } } } } } }