function __construct($source_tag, $dest_tag, $papersel, $strict, $header_title = null, $header_id = null) { global $Conf; $this->dest_tag = $dest_tag; $this->ordertype = $strict ? "aos" : "ao"; $this->papersel = $papersel; $this->userrank = array(); $this->info_printed = false; $this->header_title = $header_title; $this->header_id = $header_id; $this->starttime = time(); // generate random order for paper comparisons if (count($papersel)) { $range = range(0, count($papersel) - 1); shuffle($range); $this->papershuffle = array_combine($papersel, $range); } else { $this->papershuffle = array(); } // load current ranks: $userrank maps user => [rank, paper] $result = $Conf->qe("select paperId, tag, tagIndex from PaperTag where tag like '%~" . sqlq_for_like($source_tag) . "' and paperId in (" . join(",", $papersel) . ")"); $len = strlen($source_tag) + 1; while ($row = edb_row($result)) { $l = (int) substr($row[1], 0, strlen($row[1]) - $len); $this->userrank[$l][] = array((int) $row[2], (int) $row[0]); } // sort $userrank[$user] by descending rank order foreach ($this->userrank as $user => &$ranks) { usort($ranks, array($this, "_comparUserrank")); } $this->rank = array(); $this->currank = 0; }
static function email_authored_papers($email, $reg) { $aupapers = array(); $result = Dbl::q("select paperId, authorInformation from Paper where authorInformation like " . Dbl::utf8ci("'%\t" . sqlq_for_like($email) . "\t%'")); while ($row = PaperInfo::fetch($result, null)) { foreach ($row->author_list() as $au) { if (strcasecmp($au->email, $email) == 0) { $aupapers[] = $row->paperId; if ($reg && $au->firstName && !get($reg, "firstName")) { $reg->firstName = $au->firstName; } if ($reg && $au->lastName && !get($reg, "lastName")) { $reg->lastName = $au->lastName; } if ($reg && $au->affiliation && !get($reg, "affiliation")) { $reg->affiliation = $au->affiliation; } } } } return $aupapers; }
public function save($sv, $si) { global $Conf; if ($si->name == "tag_vote" && $sv->has_savedv("tag_vote")) { // check allotments $pcm = pcMembers(); foreach (preg_split('/\\s+/', $sv->savedv("tag_vote")) as $t) { if ($t === "") { continue; } $base = substr($t, 0, strpos($t, "#")); $allotment = substr($t, strlen($base) + 1); $result = Dbl::q("select paperId, tag, tagIndex from PaperTag where tag like '%~" . sqlq_for_like($base) . "'"); $pvals = array(); $cvals = array(); $negative = false; while ($row = edb_row($result)) { $who = substr($row[1], 0, strpos($row[1], "~")); if ($row[2] < 0) { $sv->set_error(null, "Removed " . Text::user_html($pcm[$who]) . "’s negative “{$base}” vote for paper #{$row['0']}."); $negative = true; } else { $pvals[$row[0]] = defval($pvals, $row[0], 0) + $row[2]; $cvals[$who] = defval($cvals, $who, 0) + $row[2]; } } foreach ($cvals as $who => $what) { if ($what > $allotment) { $sv->set_error("tag_vote", Text::user_html($pcm[$who]) . " already has more than {$allotment} votes for tag “{$base}”."); } } $q = $negative ? " or (tag like '%~" . sqlq_for_like($base) . "' and tagIndex<0)" : ""; $Conf->qe("delete from PaperTag where tag='" . sqlq($base) . "'{$q}"); $q = array(); foreach ($pvals as $pid => $what) { $q[] = "({$pid}, '" . sqlq($base) . "', {$what})"; } if (count($q) > 0) { $Conf->qe("insert into PaperTag values " . join(", ", $q)); } } } if ($si->name == "tag_approval" && $sv->has_savedv("tag_approval")) { $pcm = pcMembers(); foreach (preg_split('/\\s+/', $sv->savedv("tag_approval")) as $t) { if ($t === "") { continue; } $result = $Conf->q("select paperId, tag, tagIndex from PaperTag where tag like '%~" . sqlq_for_like($t) . "'"); $pvals = array(); $negative = false; while ($row = edb_row($result)) { $who = substr($row[1], 0, strpos($row[1], "~")); if ($row[2] < 0) { $sv->set_error(null, "Removed " . Text::user_html($pcm[$who]) . "’s negative “{$t}” approval vote for paper #{$row['0']}."); $negative = true; } else { $pvals[$row[0]] = defval($pvals, $row[0], 0) + 1; } } $q = $negative ? " or (tag like '%~" . sqlq_for_like($t) . "' and tagIndex<0)" : ""; $Conf->qe("delete from PaperTag where tag='" . sqlq($t) . "'{$q}"); $q = array(); foreach ($pvals as $pid => $what) { $q[] = "({$pid}, '" . sqlq($t) . "', {$what})"; } if (count($q) > 0) { $Conf->qe("insert into PaperTag values " . join(", ", $q)); } } } TagInfo::invalidate_defined_tags(); }
$numreviews = Dbl::fetch_ivalue("select count(*) from PaperReview where paperId={$prow->paperId} and reviewNeedsSubmit!=0"); $Conf->update_papersub_setting(false); loadRows(); // email contact authors themselves if (!$Me->privChair || defval($_REQUEST, "doemail") > 0) { HotCRPMailer::send_contacts($prow->conflictType >= CONFLICT_AUTHOR ? "@authorwithdraw" : "@adminwithdraw", $prow, array("reason" => $reason, "infoNames" => 1)); } // email reviewers if ($numreviews > 0 && $Conf->time_review_open() || $prow->num_reviews_assigned() > 0) { HotCRPMailer::send_reviewers("@withdrawreviewer", $prow, array("reason" => $reason)); } // remove voting tags so people don't have phantom votes if (TagInfo::has_vote()) { $q = array(); foreach (TagInfo::vote_tags() as $t => $v) { $q[] = "tag='" . sqlq($t) . "' or tag like '%~" . sqlq_for_like($t) . "'"; } Dbl::qe_raw("delete from PaperTag where paperId={$prow->paperId} and (" . join(" or ", $q) . ")"); } $Me->log_activity("Withdrew", $prow->paperId); redirectSelf(); } else { Conf::msg_error(whyNotText($whyNot, "withdraw")); } } if (isset($_REQUEST["revive"]) && !$newPaper && check_post()) { if (!($whyNot = $Me->perm_revive_paper($prow))) { Dbl::qe("update Paper set timeWithdrawn=0, timeSubmitted=if(timeSubmitted=-100,{$Now},0), withdrawReason=null where paperId={$prow->paperId}"); $Conf->update_papersub_setting(true); loadRows(); $Me->log_activity("Revived", $prow->paperId);
$where[] = "action like " . Dbl::utf8ci("'% " . sqlq_for_like($row[1]) . "%'"); } } if (count($where)) { $wheres[] = "(" . join(" or ", $where) . ")"; } else { $Conf->infoMsg("No accounts match “" . htmlspecialchars($_REQUEST["acct"]) . "”."); $wheres[] = "false"; } } if ($str = $_REQUEST["q"]) { $where = array(); while (($str = ltrim($str)) != "") { preg_match('/^("[^"]+"?|[^"\\s]+)/s', $str, $m); $str = substr($str, strlen($m[0])); $where[] = "action like " . Dbl::utf8ci("'%" . sqlq_for_like($m[0]) . "%'"); } $wheres[] = "(" . join(" or ", $where) . ")"; } if (($count = cvtint(@$_REQUEST["n"])) <= 0) { Conf::msg_error("\"Show <i>n</i> records\" requires a number greater than 0."); $Eclass["n"] = " error"; $count = $DEFAULT_COUNT; } $firstDate = false; if ($_REQUEST["date"] == "") { $_REQUEST["date"] = "now"; } if ($_REQUEST["date"] != "now" && isset($_REQUEST["search"])) { if (($firstDate = $Conf->parse_time($_REQUEST["date"])) === false) { Conf::msg_error("“" . htmlspecialchars($_REQUEST["date"]) . "” is not a valid date.");
function crpmerge_database($old_user, $new_user) { global $Conf, $MergeError; // Now, scan through all the tables that possibly // specify a contactID and change it from their 2nd // contactID to their first contactId $oldid = $old_user->contactId; $newid = $new_user->contactId; $Conf->q("lock tables Paper write, ContactInfo write, PaperConflict write, ActionLog write, TopicInterest write, PaperComment write, PaperReview write, PaperReview as B write, PaperReviewPreference write, PaperReviewRefused write, ReviewRequest write, PaperWatch write, ReviewRating write"); crpmergeone("Paper", "leadContactId", $oldid, $newid); crpmergeone("Paper", "shepherdContactId", $oldid, $newid); crpmergeone("Paper", "managerContactId", $oldid, $newid); // paper authorship $result = $Conf->qe("select paperId, authorInformation from Paper where authorInformation like " . Dbl::utf8ci("'%\t" . sqlq_for_like($old_user->email) . "\t%'")); $qs = array(); while ($row = PaperInfo::fetch($result, null)) { foreach ($row->author_list() as $au) { if (strcasecmp($au->email, $old_user->email) == 0) { $au->email = $new_user->email; } } $qs[] = "update Paper set authorInformation='" . sqlq($row->parse_author_list()) . "' where paperId={$row->paperId}"; } foreach ($qs as $q) { $Conf->qe($q); } // ensure uniqueness in PaperConflict $result = $Conf->qe("select paperId, conflictType from PaperConflict where contactId={$oldid}"); $values = ""; while ($row = edb_row($result)) { $values .= ", ({$row['0']}, {$newid}, {$row['1']})"; } if ($values) { $Conf->qe("insert into PaperConflict (paperId, contactId, conflictType) values " . substr($values, 2) . " on duplicate key update conflictType=greatest(conflictType, values(conflictType))"); } $Conf->qe("delete from PaperConflict where contactId={$oldid}"); if (($old_user->roles | $new_user->roles) != $new_user->roles) { $new_user->roles |= $old_user->roles; $Conf->qe("update ContactInfo set roles={$new_user->roles} where contactId={$newid}"); } crpmergeone("ActionLog", "contactId", $oldid, $newid); crpmergeoneignore("TopicInterest", "contactId", $oldid, $newid); crpmergeone("PaperComment", "contactId", $oldid, $newid); // archive duplicate reviews crpmergeoneignore("PaperReview", "contactId", $oldid, $newid); crpmergeone("PaperReview", "requestedBy", $oldid, $newid); crpmergeoneignore("PaperReviewPreference", "contactId", $oldid, $newid); crpmergeone("PaperReviewRefused", "contactId", $oldid, $newid); crpmergeone("PaperReviewRefused", "requestedBy", $oldid, $newid); crpmergeone("ReviewRequest", "requestedBy", $oldid, $newid); crpmergeoneignore("PaperWatch", "contactId", $oldid, $newid); crpmergeoneignore("ReviewRating", "contactId", $oldid, $newid); // Remove the old contact record if ($MergeError == "") { if (!$Conf->q("delete from ContactInfo where contactId={$oldid}")) { $MergeError .= $Conf->db_error_html(true); } } $Conf->qe("unlock tables"); // Update PC settings if we need to if ($old_user->isPC) { $Conf->invalidateCaches(array("pc" => 1)); } }
function query($paper_sensitive) { global $Conf; $cols = array(); $where = array("email not regexp '^anonymous[0-9]*\$'"); $joins = array("ContactInfo"); // paper limit if ($this->need_papers() && isset($this->papersel)) { $where[] = "Paper.paperId in (" . join(",", $this->papersel) . ")"; } // paper type limit if ($this->type == "s") { $where[] = "Paper.timeSubmitted>0"; } else { if ($this->type == "unsub") { $where[] = "Paper.timeSubmitted<=0 and Paper.timeWithdrawn<=0"; } else { if ($this->type == "dec:any") { $where[] = "Paper.timeSubmitted>0 and Paper.outcome!=0"; } else { if ($this->type == "dec:none") { $where[] = "Paper.timeSubmitted>0 and Paper.outcome=0"; } else { if ($this->type == "dec:yes") { $where[] = "Paper.timeSubmitted>0 and Paper.outcome>0"; } else { if ($this->type == "dec:no") { $where[] = "Paper.timeSubmitted>0 and Paper.outcome<0"; } else { if (substr($this->type, 0, 4) == "dec:") { $nw = count($where); foreach ($Conf->decision_map() as $dnum => $dname) { if (strcasecmp($dname, substr($this->type, 4)) == 0) { $where[] = "Paper.timeSubmitted>0 and Paper.outcome={$dnum}"; break; } } if (count($where) == $nw) { return false; } } } } } } } } // additional manager limit if (!isset($this->sel_nonmanager[$this->type]) && !$this->contact->privChair) { $where[] = "Paper.managerContactId=" . $this->contact->contactId; } // reviewer limit if (!preg_match('_\\A(new|unc|c|allc|)(pc|ext|myext|)rev\\z_', $this->type, $revmatch)) { $revmatch = false; } // build query if ($this->type == "all") { $needpaper = $needconflict = $needreview = false; } else { if ($this->type == "pc" || substr($this->type, 0, 3) == "pc:") { $needpaper = $needconflict = $needreview = false; $where[] = "(ContactInfo.roles&" . Contact::ROLE_PC . ")!=0"; if ($this->type != "pc") { $where[] = "ContactInfo.contactTags like " . Dbl::utf8ci("'% " . sqlq_for_like(substr($this->type, 3)) . "#%'"); } } else { if ($revmatch) { $needpaper = $needreview = true; $needconflict = false; $joins[] = "join Paper"; $joins[] = "join PaperReview on (PaperReview.paperId=Paper.paperId and PaperReview.contactId=ContactInfo.contactId)"; $where[] = "Paper.paperId=PaperReview.paperId"; } else { if ($this->type == "lead" || $this->type == "shepherd") { $needpaper = $needconflict = $needreview = true; $joins[] = "join Paper on (Paper.{$this->type}ContactId=ContactInfo.contactId)"; $joins[] = "left join PaperReview on (PaperReview.paperId=Paper.paperId and PaperReview.contactId=ContactInfo.contactId)"; } else { $needpaper = $needconflict = true; $needreview = false; if ($Conf->au_seerev == Conf::AUSEEREV_UNLESSINCOMPLETE) { $cols[] = "(coalesce(allr.contactId,0)!=0) has_review"; $cols[] = "coalesce(allr.has_outstanding_review,0) has_outstanding_review"; $joins[] = "left join (select contactId, max(if(reviewNeedsSubmit!=0 and timeSubmitted>0,1,0)) has_outstanding_review from PaperReview join Paper on (Paper.paperId=PaperReview.paperId) group by PaperReview.contactId) as allr using (contactId)"; } $joins[] = "join Paper"; $where[] = "PaperConflict.conflictType>=" . CONFLICT_AUTHOR; if ($Conf->au_seerev == Conf::AUSEEREV_TAGS) { $joins[] = "left join (select paperId, group_concat(' ', tag, '#', tagIndex order by tag separator '') as paperTags from PaperTag group by paperId) as PaperTags on (PaperTags.paperId=Paper.paperId)"; $cols[] = "PaperTags.paperTags"; } } } } } // reviewer match if ($revmatch) { // Submission status if ($revmatch[1] == "c") { $where[] = "PaperReview.reviewSubmitted>0"; } else { if ($revmatch[1] == "unc" || $revmatch[1] == "new") { $where[] = "PaperReview.reviewSubmitted is null and PaperReview.reviewNeedsSubmit!=0 and Paper.timeSubmitted>0"; } } if ($revmatch[1] == "new") { $where[] = "PaperReview.timeRequested>PaperReview.timeRequestNotified"; } if ($revmatch[1] == "allc") { $joins[] = "left join (select contactId, max(if(reviewNeedsSubmit!=0 and timeSubmitted>0,1,0)) anyReviewNeedsSubmit from PaperReview join Paper on (Paper.paperId=PaperReview.paperId) group by contactId) AllReviews on (AllReviews.contactId=ContactInfo.contactId)"; $where[] = "AllReviews.anyReviewNeedsSubmit=0"; } if ($this->newrev_since) { $where[] = "PaperReview.timeRequested>={$this->newrev_since}"; } // Withdrawn papers may not count if ($revmatch[1] == "") { $where[] = "(Paper.timeSubmitted>0 or PaperReview.reviewSubmitted>0)"; } // Review type if ($revmatch[2] == "ext" || $revmatch[2] == "myext") { $where[] = "PaperReview.reviewType=" . REVIEW_EXTERNAL; } else { if ($revmatch[2] == "pc") { $where[] = "PaperReview.reviewType>" . REVIEW_EXTERNAL; } } if ($revmatch[2] == "myext") { $where[] = "PaperReview.requestedBy=" . $this->contact->contactId; } } // query construction $q = "select ContactInfo.contactId, firstName, lastName, email,\n password, roles, contactTags, preferredEmail, " . ($needconflict ? "PaperConflict.conflictType" : "0 as conflictType"); if ($needpaper) { $q .= ", Paper.paperId, Paper.title, Paper.abstract,\n Paper.authorInformation, Paper.outcome, Paper.blind,\n Paper.timeSubmitted, Paper.timeWithdrawn,\n Paper.shepherdContactId, Paper.capVersion,\n Paper.managerContactId"; } else { $q .= ", -1 as paperId"; } if ($needreview) { $q .= ", PaperReview.reviewType, PaperReview.reviewType as myReviewType"; } if ($needconflict) { $joins[] = "left join PaperConflict on (PaperConflict.paperId=Paper.paperId and PaperConflict.contactId=ContactInfo.contactId)"; } $q .= "\nfrom " . join("\n", $joins) . "\nwhere " . join("\n and ", $where) . "\norder by "; if (!$needpaper) { $q .= "email"; } else { if ($paper_sensitive) { $q .= "Paper.paperId, email"; } else { $q .= "email, Paper.paperId"; } } return $q; }
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)); } }
private function _search_one_tag($value, $old_arg) { if (($starpos = strpos($value, "*")) !== false) { $arg = "( like '" . str_replace("*", "%", sqlq_for_like($value)) . "'"; if ($starpos == 0) { $arg .= " and not like '%~%'"; } $arg .= ")"; } else { if ($value === "any" || $value === "none") { $arg = "( is not null and ( not like '%~%' or like '{$this->cid}~%'" . ($this->privChair ? " or like '~~%'" : "") . "))"; } else { $arg = "='" . sqlq($value) . "'"; } } return $old_arg ? "{$old_arg} or {$arg}" : $arg; }
private static function format_query_args($dblink, $qstr, $argv) { $original_qstr = $qstr; $strpos = $argpos = 0; $usedargs = array(); while (($strpos = strpos($qstr, "?", $strpos)) !== false) { // argument name $nextpos = $strpos + 1; $nextch = substr($qstr, $nextpos, 1); if ($nextch === "?") { $qstr = substr($qstr, 0, $strpos + 1) . substr($qstr, $strpos + 2); $strpos = $strpos + 1; continue; } else { if ($nextch === "{" && ($rbracepos = strpos($qstr, "}", $nextpos + 1)) !== false) { $thisarg = substr($qstr, $nextpos + 1, $rbracepos - $nextpos - 1); if ($thisarg === (string) (int) $thisarg) { --$thisarg; } $nextpos = $rbracepos + 1; $nextch = substr($qstr, $nextpos, 1); } else { while (get($usedargs, $argpos)) { ++$argpos; } $thisarg = $argpos; } } if (!array_key_exists($thisarg, $argv)) { trigger_error(self::landmark() . ": query '{$original_qstr}' argument " . (is_int($thisarg) ? $thisarg + 1 : $thisarg) . " not set"); } $usedargs[$thisarg] = true; // argument format $arg = get($argv, $thisarg); if ($nextch === "e" || $nextch === "E") { if ($arg === null) { $arg = $nextch === "e" ? " IS NULL" : " IS NOT NULL"; } else { if (is_int($arg) || is_float($arg)) { $arg = ($nextch === "e" ? "=" : "!=") . $arg; } else { $arg = ($nextch === "e" ? "='" : "!='") . $dblink->real_escape_string($arg) . "'"; } } ++$nextpos; } else { if ($nextch === "a" || $nextch === "A") { if ($arg === null) { $arg = array(); } else { if (is_int($arg) || is_float($arg) || is_string($arg)) { $arg = array($arg); } } foreach ($arg as $x) { if (!is_int($x) && !is_float($x)) { reset($arg); foreach ($arg as &$y) { $y = "'" . $dblink->real_escape_string($y) . "'"; } unset($y); break; } } if (empty($arg)) { // We want `foo IN ()` and `foo NOT IN ()`. // That is, we want `false` and `true`. We compromise. The // statement `foo=NULL` is always NULL -- which is falsy // -- even if `foo IS NULL`. The statement `foo IS NOT // NULL` is true unless `foo IS NULL`. $arg = $nextch === "a" ? "=NULL" : " IS NOT NULL"; } else { if (count($arg) === 1) { reset($arg); $arg = ($nextch === "a" ? "=" : "!=") . current($arg); } else { $arg = ($nextch === "a" ? " IN (" : " NOT IN (") . join(", ", $arg) . ")"; } } ++$nextpos; } else { if ($nextch === "s") { $arg = $dblink->real_escape_string($arg); ++$nextpos; } else { if ($nextch === "l") { $arg = sqlq_for_like($arg); ++$nextpos; if (substr($qstr, $nextpos + 1, 1) === "s") { ++$nextpos; } else { $arg = "'" . $arg . "'"; } } else { if ($nextch === "v") { ++$nextpos; if (!is_array($arg) || empty($arg)) { trigger_error(self::landmark() . ": query '{$original_qstr}' argument " . (is_int($thisarg) ? $thisarg + 1 : $thisarg) . " should be nonempty array"); $arg = "NULL"; } else { $alln = -1; $vs = []; foreach ($arg as $x) { if (!is_array($x)) { $x = [$x]; } $n = count($x); if ($alln === -1) { $alln = $n; } if ($alln !== $n && $alln !== -2) { trigger_error(self::landmark() . ": query '{$original_qstr}' argument " . (is_int($thisarg) ? $thisarg + 1 : $thisarg) . " has components of different lengths"); $alln = -2; } foreach ($x as &$y) { if ($y === null) { $y = "NULL"; } else { if (!is_int($y) && !is_float($y)) { $y = "'" . $dblink->real_escape_string($y) . "'"; } } } unset($y); $vs[] = "(" . join(",", $x) . ")"; } $arg = join(", ", $vs); } } else { if ($arg === null) { $arg = "NULL"; } else { if (!is_int($arg) && !is_float($arg)) { $arg = "'" . $dblink->real_escape_string($arg) . "'"; } } } } } } } // combine $suffix = substr($qstr, $nextpos); $qstr = substr($qstr, 0, $strpos) . $arg . $suffix; $strpos = strlen($qstr) - strlen($suffix); } return $qstr; }
function rows($listname) { // PC tags $queryOptions = array(); if (str_starts_with($listname, "#")) { $queryOptions["where"] = "(u.contactTags like " . Dbl::utf8ci("'% " . sqlq_for_like(substr($listname, 1)) . "#%'") . ")"; $listname = "pc"; } // get paper list if (!($baseFieldId = $this->listFields($listname))) { Conf::msg_error("There is no people list query named “" . htmlspecialchars($listname) . "”."); return null; } $this->limit = array_shift($baseFieldId); // run query return $this->_rows($queryOptions); }