public static function highlight($text, $match, &$n = null) { $n = 0; if ($match === null || $match === false || $match === "" || $text == "") { return htmlspecialchars($text); } $mtext = $text; $offsetmap = null; $flags = ""; if (is_object($match)) { if (!isset($match->preg_raw)) { $match = $match->preg_utf8; $flags = "u"; } else { if (preg_match('/[\\x80-\\xFF]/', $text)) { list($mtext, $offsetmap) = UnicodeHelper::deaccent_offsets($mtext); $match = $match->preg_utf8; $flags = "u"; } else { $match = $match->preg_raw; } } } $s = $clean_initial_nonletter = false; if ($match !== null && $match !== "") { if (str_starts_with($match, self::UTF8_INITIAL_NONLETTER)) { $clean_initial_nonletter = true; } if ($match[0] !== "{") { $match = "{(" . $match . ")}is" . $flags; } $s = preg_split($match, $mtext, -1, PREG_SPLIT_DELIM_CAPTURE); } if (!$s || count($s) == 1) { return htmlspecialchars($text); } $n = (int) (count($s) / 2); if ($offsetmap) { for ($i = $b = $o = 0; $i < count($s); ++$i) { if ($s[$i] !== "") { $o += strlen($s[$i]); $e = UnicodeHelper::deaccent_translate_offset($offsetmap, $o); $s[$i] = substr($text, $b, $e - $b); $b = $e; } } } if ($clean_initial_nonletter) { for ($i = 1; $i < count($s); $i += 2) { if ($s[$i] !== "" && preg_match('{\\A((?!\\pL|\\pN)\\X)(.*)\\z}us', $s[$i], $m)) { $s[$i - 1] .= $m[1]; $s[$i] = $m[2]; } } } for ($i = 0; $i < count($s); ++$i) { if ($i % 2 && $s[$i] !== "") { $s[$i] = '<span class="match">' . htmlspecialchars($s[$i]) . "</span>"; } else { $s[$i] = htmlspecialchars($s[$i]); } } return join("", $s); }
static function abbreviate($name, $id) { $abbr = strtolower(UnicodeHelper::deaccent($name)); $abbr = preg_replace('/[^a-z_0-9]+/', "-", $abbr); $abbr = preg_replace('/^-+|-+$/', "", $abbr); if (preg_match('/\\A(?:|p(?:aper)?\\d*|submission|final|opt\\d*|\\d.*)\\z/', $abbr)) { $abbr = "opt{$id}"; } return $abbr; }
public static function set_sorter($c, $sorttype = null) { $sort_by_last = $sorttype === "last"; if ($c->is_anonymous) { $c->sorter = $c->anon_username; return; } else { if (isset($c->unaccentedName) && $sort_by_last) { $c->sorter = trim("{$c->unaccentedName} {$c->email}"); return; } } list($first, $middle) = Text::split_first_middle($c->firstName); if ($sort_by_last) { if ($m = Text::analyze_von($c->lastName)) { $c->sorter = "{$m['1']} {$first} {$m['0']}"; } else { $c->sorter = "{$c->lastName} {$first}"; } } else { $c->sorter = "{$first} {$c->last}"; } $c->sorter = trim($c->sorter . " " . $c->username . " " . $c->email); if (preg_match('/[\\x80-\\xFF]/', $c->sorter)) { $c->sorter = UnicodeHelper::deaccent($c->sorter); } }
public static function set_sorter($c) { if (opt("sortByLastName")) { if ($m = Text::analyze_von($c->lastName)) { $c->sorter = trim("{$m['1']} {$c->firstName} {$m['0']} {$c->email}"); } else { $c->sorter = trim("{$c->lastName} {$c->firstName} {$c->email}"); } } else { if (isset($c->unaccentedName)) { $c->sorter = trim("{$c->unaccentedName} {$c->email}"); return; } else { $c->sorter = trim("{$c->firstName} {$c->lastName} {$c->email}"); } } if (preg_match('/[\\x80-\\xFF]/', $c->sorter)) { $c->sorter = UnicodeHelper::deaccent($c->sorter); } }
public function pretty_text_title_indent($width = 75) { $n = "Paper #{$this->paperId}: "; $vistitle = UnicodeHelper::deaccent($this->title); $l = (int) (($width + 0.5 - strlen($vistitle) - strlen($n)) / 2); return strlen($n) + max(0, $l); }
function echo_commit($Info) { global $Conf, $Me, $User, $Pset; global $TABWIDTH, $WDIFF; $Notes = $Info->commit_info(); $TABWIDTH = $Info->commit_info("tabwidth") ?: 4; $WDIFF = isset($Notes->wdiff) ? $Notes->wdiff : false; // current commit and commit selector $sel = array(); $curhead = $grouphead = null; foreach ($Info->recent_commits() as $k) { // visually separate older heads if ($curhead === null) { $curhead = $k->fromhead; } if ($curhead != $k->fromhead) { if (!$grouphead) { $sel["from.{$k->fromhead}"] = (object) array("type" => "optgroup", "label" => "Other snapshots"); } else { $sel["from.{$k->fromhead}"] = null; } $curhead = $grouphead = $k->fromhead; } // actual option $x = UnicodeHelper::utf8_prefix($k->subject, 72); if (strlen($x) != strlen($k->subject)) { $x .= "..."; } $sel[$k->hash] = substr($k->hash, 0, 7) . " " . htmlspecialchars($x); } $result = $Conf->qe("select hash from CommitNotes where (haslinenotes & ?)!=0 and pset=? and hash ?a", $Me == $User && !$Info->can_see_grades ? HASNOTES_COMMENT : HASNOTES_ANY, $Pset->psetid, array_keys($sel)); while ($row = edb_row($result)) { $sel[$row[0]] .= " ♪"; } if (($h = $Info->grading_hash()) && isset($sel[$h])) { $sel[$h] = preg_replace('_(.*?)(?: )?(♪?)\\z_', '$1 ✱$2', $sel[$h]); } if ($Info->is_grading_commit()) { $key = "grading commit"; } else { $key = "this commit"; } $value = Ht::select("newcommit", $sel, $Info->commit_hash(), array("onchange" => "jQuery(this).closest('form').submit()")); if ($Me != $User) { $x = $Info->is_grading_commit() ? "" : "font-weight:bold"; $value .= " " . Ht::submit("grade", "Grade", array("style" => $x)); } // view options $fold_viewoptions = !isset($_REQUEST["tab"]) && !isset($_REQUEST["wdiff"]); $value .= '<div class="viewoptions61">' . '<a class="q" href="#" onclick="return fold61(this.nextSibling,this.parentNode)">' . '<span class="foldarrow">' . ($fold_viewoptions ? '▶' : '▼') . '</span> options</a><span style="padding-left:1em' . ($fold_viewoptions ? ';display:none' : '') . '">tab width:'; foreach (array(2, 4, 8) as $i) { $value .= ' <a href="' . self_href(array("tab" => $i)) . '"' . ($TABWIDTH == $i ? " class=\"q\"><strong>{$i}</strong>" : '>' . $i) . '</a>'; } $value .= '<span style="padding-left:1em">wdiff:'; foreach (array("no", "yes") as $i => $t) { $value .= ' <a href="' . self_href(array("wdiff" => $i)) . '"' . (!$WDIFF == !$i ? " class=\"q\"><strong>{$t}</strong>" : '>' . $t) . '</a>'; } $value .= '</span></span></div>'; // warnings $remarks = array(); if (!$Info->grading_hash() && $Me != $User && !$Pset->gitless_grades) { $remarks[] = array(true, "No commit has been marked for grading."); } else { if (!$Info->is_grading_commit() && $Info->grading_hash()) { $remarks[] = array(true, "This is not " . "<a class=\"uu\" href=\"" . $Info->hoturl("pset", array("commit" => $Info->grading_hash())) . "\">the commit currently marked for grading</a>" . " <span style=\"font-weight:normal\">(<a href=\"" . $Info->hoturl("diff", array("commit1" => $Info->grading_hash())) . "\">see diff</a>)</span>."); } } if (!$Info->is_latest_commit()) { $remarks[] = array(true, "This is not " . "<a class=\"uu\" href=\"" . $Info->hoturl("pset", array("commit" => $Info->latest_hash())) . "\">the latest commit</a>" . " <span style=\"font-weight:normal\">(<a href=\"" . $Info->hoturl("diff", array("commit1" => $Info->latest_hash())) . "\">see diff</a>)</span>."); } if (($lh = $Info->late_hours()) && $lh->hours > 0) { $extra = array(); if (get($lh, "commitat")) { $extra[] = "commit at " . $Conf->printableTimestamp($lh->commitat); } if (get($lh, "deadline")) { $extra[] = "deadline " . $Conf->printableTimestamp($lh->deadline); } $extra = count($extra) ? ' <span style="font-weight:normal">(' . join(", ", $extra) . ')</span>' : ""; $remarks[] = array(true, "This commit uses " . plural($lh->hours, "late hour") . $extra . "."); } if (($Info->is_latest_commit() || $Me->isPC) && $Pset->handout_repo_url) { $Pset->latest_handout_commit(); $last_handout = $Pset->latest_handout_commit(); $last_myhandout = $last_handout ? $Info->derived_handout_hash() : false; if ($last_handout && $last_myhandout && $last_handout->hash == $last_myhandout) { /* this is ideal: they have the latest handout commit */ } else { if ($last_handout && $last_myhandout) { // they don't have the latest updates $remarks[] = array(true, "Updates are available for this problem set <span style=\"font-weight:normal\">(<a href=\"" . $Info->hoturl("diff", array("commit" => $last_myhandout, "commit1" => $last_handout->hash)) . "\">see diff</a>)</span>. Run <code>git pull handout master</code> to merge these updates."); } else { if ($last_handout) { $remarks[] = array(true, "Please create your repository by cloning our repository. Creating your repository from scratch makes it harder for you to get pset updates."); } else { if (!$last_handout && $Me->isPC) { $handout_files = $Pset->handout_repo()->ls_files("master"); if (!count($handout_files)) { $remarks[] = array(true, "The handout repository, " . htmlspecialchars($Pset->handout_repo_url) . ", contains no files; perhaps handout_repo_url is misconfigured."); } else { $remarks[] = array(true, "The handout repository, " . htmlspecialchars($Pset->handout_repo_url) . ", does not contain problem set code yet."); } } } } } } // actually print echo Ht::form($Info->hoturl_post("pset", array("commit" => null, "setcommit" => 1)), array("class" => "commitcontainer61", "data-pa-pset" => $Info->pset->urlkey, "data-pa-commit" => $Info->latest_hash())), "<div class=\"f-contain\">"; ContactView::echo_group($key, $value, $remarks); echo "</div></form>\n"; }
public function save($req, $contact) { global $Conf, $Now; if (is_array($req)) { $req = (object) $req; } $Table = $this->prow->comment_table_name(); $LinkTable = $this->prow->table_name(); $LinkColumn = $this->prow->id_column(); $req_visibility = get($req, "visibility"); $is_response = !!($this->commentType & COMMENTTYPE_RESPONSE); if ($is_response && get($req, "submit")) { $ctype = COMMENTTYPE_RESPONSE | COMMENTTYPE_AUTHOR; } else { if ($is_response) { $ctype = COMMENTTYPE_RESPONSE | COMMENTTYPE_AUTHOR | COMMENTTYPE_DRAFT; } else { if ($req_visibility == "a" || $req_visibility == "au") { $ctype = COMMENTTYPE_AUTHOR; } else { if ($req_visibility == "p" || $req_visibility == "pc") { $ctype = COMMENTTYPE_PCONLY; } else { if ($req_visibility == "admin") { $ctype = COMMENTTYPE_ADMINONLY; } else { if ($this->commentId && $req_visibility === null) { $ctype = $this->commentType; } else { // $req->visibility == "r" || $req->visibility == "rev" $ctype = COMMENTTYPE_REVIEWER; } } } } } } if ($is_response ? $this->prow->blind : $Conf->is_review_blind(!!get($req, "blind"))) { $ctype |= COMMENTTYPE_BLIND; } // tags if ($is_response) { $ctags = " response "; if (($rname = $Conf->resp_round_name($this->commentRound)) != "1") { $ctags .= "{$rname}response "; } } else { if (get($req, "tags") && preg_match_all(',\\S+,', $req->tags, $m)) { $tagger = new Tagger($contact); $ctags = array(); foreach ($m[0] as $text) { if (($text = $tagger->check($text, Tagger::NOVALUE)) && !stri_ends_with($text, "response")) { $ctags[strtolower($text)] = $text; } } $tagger->sort($ctags); $ctags = count($ctags) ? " " . join(" ", $ctags) . " " : null; } else { $ctags = null; } } // notifications $displayed = !($ctype & COMMENTTYPE_DRAFT); // query $text = get_s($req, "text"); $q = ""; $qv = array(); if ($text === "" && $this->commentId) { $change = true; $q = "delete from {$Table} where commentId={$this->commentId}"; } else { if ($text === "") { /* do nothing */ } else { if (!$this->commentId) { $change = true; $qa = ["contactId, {$LinkColumn}, commentType, comment, commentOverflow, timeModified, replyTo"]; $qb = [$contact->contactId, $this->prow->{$LinkColumn}, $ctype, "?", "?", $Now, 0]; if (strlen($text) <= 32000) { array_push($qv, $text, null); } else { array_push($qv, UnicodeHelper::utf8_prefix($text, 200), $text); } if ($ctags !== null) { $qa[] = "commentTags"; $qb[] = "?"; $qv[] = $ctags; } if ($is_response) { $qa[] = "commentRound"; $qb[] = $this->commentRound; } if ($displayed) { $qa[] = "timeDisplayed, timeNotified"; $qb[] = "{$Now}, {$Now}"; } $q = "insert into {$Table} (" . join(", ", $qa) . ") select " . join(", ", $qb) . "\n"; if ($is_response) { // make sure there is exactly one response $q .= " from (select {$LinkTable}.{$LinkColumn}, coalesce(commentId, 0) commentId\n from {$LinkTable}\n left join {$Table} on ({$Table}.{$LinkColumn}={$LinkTable}.{$LinkColumn} and (commentType&" . COMMENTTYPE_RESPONSE . ")!=0 and commentRound={$this->commentRound})\n where {$LinkTable}.{$LinkColumn}={$this->prow->{$LinkColumn}} limit 1) t\n where t.commentId=0"; } } else { $change = $this->commentType >= COMMENTTYPE_AUTHOR != $ctype >= COMMENTTYPE_AUTHOR; if ($this->timeModified >= $Now) { $Now = $this->timeModified + 1; } // do not notify on updates within 3 hours $qa = ""; if ($this->timeNotified + 10800 < $Now || $ctype & COMMENTTYPE_RESPONSE && !($ctype & COMMENTTYPE_DRAFT) && $this->commentType & COMMENTTYPE_DRAFT) { $qa .= ", timeNotified={$Now}"; } // reset timeDisplayed if you change the comment type if ((!$this->timeDisplayed || $this->ordinal_missing($ctype)) && $text !== "" && $displayed) { $qa .= ", timeDisplayed={$Now}"; } $q = "update {$Table} set timeModified={$Now}{$qa}, commentType={$ctype}, comment=?, commentOverflow=?, commentTags=? where commentId={$this->commentId}"; if (strlen($text) <= 32000) { array_push($qv, $text, null); } else { array_push($qv, UnicodeHelper::utf8_prefix($text, 200), $text); } $qv[] = $ctags; } } } $result = Dbl::qe_apply($q, $qv); if (!$result) { return false; } $cmtid = $this->commentId ?: $result->insert_id; if (!$cmtid) { return false; } // log $contact->log_activity("Comment {$cmtid} " . ($text !== "" ? "saved" : "deleted"), $this->prow->{$LinkColumn}); // ordinal if ($text !== "" && $this->ordinal_missing($ctype)) { $this->save_ordinal($cmtid, $ctype, $Table, $LinkTable, $LinkColumn); } // reload if ($text !== "") { $comments = $this->prow->fetch_comments("commentId={$cmtid}"); $this->merge($comments[$cmtid], $this->prow); if ($this->timeNotified == $this->timeModified) { self::$watching = $this; $this->prow->notify(WATCHTYPE_COMMENT, "CommentInfo::watch_callback", $contact); self::$watching = null; } } else { $this->commentId = 0; $this->comment = ""; $this->commentTags = null; } return true; }
function center_word_wrap($text, $totWidth = 75, $multi_center = false) { if (strlen($text) <= $totWidth && !preg_match('/[\\200-\\377]/', $text)) { return str_pad($text, (int) (($totWidth + strlen($text)) / 2), " ", STR_PAD_LEFT) . "\n"; } $out = ""; while (($line = UnicodeHelper::utf8_line_break($text, $totWidth)) !== false) { $linelen = UnicodeHelper::utf8_glyphlen($line); $out .= str_pad($line, (int) (($totWidth + $linelen) / 2), " ", STR_PAD_LEFT) . "\n"; } return $out; }
function _clauseTermCheckField($t, $row) { $field = $t->link; if (!$this->_clauseTermCheckFlags($t, $row) || $row->{$field} === "") { return false; } $field_deaccent = $field . "_deaccent"; if (!isset($row->{$field_deaccent})) { if (preg_match('/[\\x80-\\xFF]/', $row->{$field})) { $row->{$field_deaccent} = UnicodeHelper::deaccent($row->{$field}); } else { $row->{$field_deaccent} = false; } } if (!isset($t->preg_utf8)) { self::analyze_field_preg($t); } return self::match_field_preg($t, $row->{$field}, $row->{$field_deaccent}); }
static function runner_json($info, $checkt, $offset = -1) { if (ctype_digit($checkt)) { $logfn = self::runner_logfile($info, $checkt); } else { if (preg_match(',\\.(\\d+)\\.log(?:\\.lock|\\.pid)?\\z,', $checkt, $m)) { $logfn = $checkt; $checkt = $m[1]; } else { return false; } } $data = @file_get_contents($logfn, false, null, $offset); if ($data === false) { return (object) array("error" => true, "message" => "No such log"); } // Fix up $data if it is not valid UTF-8. if (!is_valid_utf8($data)) { $data = UnicodeHelper::utf8_truncate_invalid($data); if (!is_valid_utf8($data)) { $data = UnicodeHelper::utf8_replace_invalid($data); } } $json = self::runner_generic_json($info, $checkt); $json->data = $data; $json->offset = max($offset, 0); $json->lastoffset = $json->offset + strlen($data); self::runner_status_json($info, $checkt, $json); return $json; }
function expandvar_recipient($what, $isbool) { global $Conf; // rest is only there if we have a pset if (!$this->pset) { return self::EXPANDVAR_CONTINUE; } if ($what == "%PSET%" || $what == "%TITLE%") { return $this->pset->title; } if ($what == "%REPO%") { if ($this->pset->gitless) { return $isbool ? false : self::EXPANDVAR_CONTINUE; } $info = $this->get_pset_info(); if (!$info || !$info->repo) { return $isbool ? false : "(no repo)"; } return $info->repo->web_url(); } if ($what == "%PARTNER%") { if (!$this->pset->partner) { return $isbool ? false : self::EXPANDVAR_CONTINUE; } $info = $this->get_pset_info(); if (!$info || !$info->partner) { return $isbool ? false : "N/A"; } return Text::name_text($info->partner); } if (preg_match(',\\A%(?:COMMIT(?:|HASH|ABBREV|TITLE|DATE)|LATEHOURS)%\\z,', $what)) { if ($this->pset->gitless) { return $isbool ? false : self::EXPANDVAR_CONTINUE; } $info = $this->get_pset_info(); $recent = null; if ($info && $info->has_commit_set()) { $recent = $info->commit(); } if (!$recent) { if ($isbool) { return false; } else { if ($what == "%COMMITABBREV%" || $what == "%COMMITDATE%") { return "N/A"; } else { return "(no commit)"; } } } if ($what == "%COMMITHASH%") { return $recent->hash; } if ($what == "%COMMITABBREV%") { return substr($recent->hash, 0, 7); } if ($what == "%COMMIT%" && !$recent) { return substr($recent->hash, 0, 7); } else { if (!$recent) { return $isbool ? false : "(unknown)"; } else { if ($what == "%COMMITTITLE%") { return $recent->subject ?: "(empty)"; } else { if ($what == "%COMMIT%") { $subject = UnicodeHelper::utf8_prefix($recent->subject, 72); if (strlen($subject) != strlen($recent->subject)) { $subject .= "..."; } return substr($recent->hash, 0, 7) . ($subject === "" ? "" : " {$subject}"); } else { if ($what == "%COMMITDATE%") { return date("Y/m/d H:i:s", $recent->commitat); } else { if ($what == "%LATEHOURS%") { // XXX should use PsetView::late_hours if ($this->pset->deadline_extension && ($this->recipient->extension || $info->partner && $info->partner->extension)) { $deadline = $this->pset->deadline_extension; } else { if ($this->pset->deadline_college) { $deadline = $this->pset->deadline_college; } else { $deadline = $this->pset->deadline; } } if (!$deadline || $recent->commitat <= $deadline) { return $isbool ? false : "0"; } else { return (string) (int) (($recent->commitat - $deadline + 3599) / 3600); } } } } } } } } if ($what == "%GRADEENTRIES%") { $info = $this->get_pset_info(); if (!$info->can_see_grades) { return $isbool ? false : ""; } $t = ""; $total = $maxtotal = 0; // XXX better computation foreach ($this->pset->grades as $ge) { $g = $info->current_grade_entry($ge->name); if ($ge->is_extra ? $g : $g !== null) { $t .= (isset($ge->title) ? $ge->title : $ge->name) . ": " . ($g ?: 0); if ($ge->max && !$ge->hide_max) { $t .= " / " . $ge->max; } $t .= "\n"; } if ($g && !$ge->no_total) { $total += $g; } if (!$ge->is_extra && !$ge->no_total && !$ge->hide_max) { $maxtotal += $ge->max; } } if ($total || $maxtotal) { $t .= "TOTAL: " . $total; if ($maxtotal) { $t .= " / " . $maxtotal; } $t .= "\n"; } return $t; } return self::EXPANDVAR_CONTINUE; }
xassert_eqq(UnicodeHelper::utf8_prefix("a̓a̓a̓a̓a̓a̓a̓a̓", 8), "a̓a̓a̓a̓a̓a̓a̓a̓"); xassert_eqq(UnicodeHelper::utf8_prefix("a̓a̓a̓a̓a̓a̓a̓a̓", 9), "a̓a̓a̓a̓a̓a̓a̓a̓"); xassert_eqq(UnicodeHelper::utf8_word_prefix("aaaaaaaa bbb", 7), "aaaaaaaa"); xassert_eqq(UnicodeHelper::utf8_word_prefix("aaaaaaaa bbb", 8), "aaaaaaaa"); xassert_eqq(UnicodeHelper::utf8_word_prefix("aaaaaaaa bbb", 9), "aaaaaaaa"); xassert_eqq(UnicodeHelper::utf8_word_prefix("aaaaaaaa bbb", 10), "aaaaaaaa"); xassert_eqq(UnicodeHelper::utf8_glyphlen("aaaaaaaa"), 8); xassert_eqq(UnicodeHelper::utf8_glyphlen("áááááááá"), 8); xassert_eqq(UnicodeHelper::utf8_glyphlen("a̓a̓a̓a̓a̓a̓a̓a̓"), 8); xassert_eqq(prefix_word_wrap("+ ", "This is a thing to be wrapped.", "- ", 10), "+ This is\n- a thing\n- to be\n- wrapped.\n"); xassert_eqq(prefix_word_wrap("+ ", "This is a thing to be wrapped.", "- ", 9), "+ This is\n- a thing\n- to be\n- wrapped.\n"); xassert_eqq(prefix_word_wrap("+ ", "This\nis\na thing\nto\nbe wrapped.", "- ", 9), "+ This\n- is\n- a thing\n- to\n- be\n- wrapped.\n"); xassert_eqq(!!preg_match('/\\A\\pZ\\z/u', ' '), true); // deaccent tests xassert_eqq(UnicodeHelper::deaccent("Á é î ç ø U"), "A e i c o U"); $do = UnicodeHelper::deaccent_offsets("Á é î ç ø U .K"); xassert_eqq($do[0], "A e i c o U .K"); xassert_eqq(json_encode($do[1]), "[[0,0],[1,2],[3,5],[5,8],[7,11],[9,14],[14,21]]"); $regex = (object) ["preg_raw" => Text::word_regex("foo"), "preg_utf8" => Text::utf8_word_regex("foo")]; xassert_eqq(Text::highlight("Is foo bar føo bar fóó bar highlit right? foö", $regex), "Is <span class=\"match\">foo</span> bar <span class=\"match\">føo</span> bar <span class=\"match\">fóó</span> bar highlit right? <span class=\"match\">foö</span>"); // Qobject tests $q = new Qobject(["a" => 1, "b" => 2]); xassert_eqq($q->a, 1); xassert_eqq($q->b, 2); xassert_eqq(count($q), 2); xassert_eqq($q->c, null); xassert_eqq(count($q), 2); $q->c = array(); xassert_eqq(count($q), 3); $q->c[] = 1; xassert_eqq(json_encode($q->c), "[1]");
function expandvar_recipient($what, $isbool) { global $Conf; if ($what == "%NEWASSIGNMENTS%") { return $this->get_new_assignments($this->recipient); } // rest is only there if we have a real paper if (!$this->row || get($this->row, "paperId") <= 0) { return self::EXPANDVAR_CONTINUE; } if ($this->preparation) { ++$this->preparation->paper_expansions; } if ($what == "%TITLE%") { return $this->row->title; } if ($what == "%TITLEHINT%") { if ($tw = UnicodeHelper::utf8_abbreviate($this->row->title, 40)) { return "\"{$tw}\""; } else { return ""; } } if ($what == "%NUMBER%" || $what == "%PAPER%") { return $this->row->paperId; } if ($what == "%REVIEWNUMBER%") { return $this->reviewNumber; } if ($what == "%AUTHOR%" || $what == "%AUTHORS%") { if (!$this->permissionContact->is_site_contact && !$this->row->has_author($this->permissionContact) && !$this->permissionContact->can_view_authors($this->row, false)) { return $isbool ? false : "Hidden for blind review"; } return rtrim($this->row->pretty_text_author_list()); } if ($what == "%AUTHORVIEWCAPABILITY%" && isset($this->row->capVersion) && $this->permissionContact->act_author_view($this->row)) { return "cap=" . $Conf->capability_text($this->row, "a"); } if ($what == "%SHEPHERD%" || $what == "%SHEPHERDNAME%" || $what == "%SHEPHERDEMAIL%") { $pc = pcMembers(); if (defval($this->row, "shepherdContactId") <= 0 || !defval($pc, $this->row->shepherdContactId, null)) { if ($isbool) { return false; } else { if ($this->expansionType == self::EXPAND_EMAIL) { return "<none>"; } else { return "(no shepherd assigned)"; } } } $shep = $pc[$this->row->shepherdContactId]; if ($what == "%SHEPHERD%") { return $this->expand_user($shep, "CONTACT"); } else { if ($what == "%SHEPHERDNAME%") { return $this->expand_user($shep, "NAME"); } else { return $this->expand_user($shep, "EMAIL"); } } } if ($what == "%REVIEWAUTHOR%" && $this->contacts["reviewer"]) { return $this->_expand_reviewer("CONTACT", $isbool); } if ($what == "%REVIEWS%") { return $this->get_reviews(); } if ($what == "%COMMENTS%") { return $this->get_comments(null); } $len = strlen($what); if ($len > 12 && substr($what, 0, 10) == "%COMMENTS(" && substr($what, $len - 2) == ")%") { if ($t = $this->tagger()->check(substr($what, 10, $len - 12), Tagger::NOVALUE)) { return $this->get_comments($t); } } if ($len > 12 && substr($what, 0, 10) == "%TAGVALUE(" && substr($what, $len - 2) == ")%") { if ($t = $this->tagger()->check(substr($what, 10, $len - 12), Tagger::NOVALUE | Tagger::NOPRIVATE)) { if (!isset($this->_tags[$t])) { $this->_tags[$t] = array(); $result = Dbl::qe("select paperId, tagIndex from PaperTag where tag=?", $t); while ($row = edb_row($result)) { $this->_tags[$t][$row[0]] = $row[1]; } } $tv = defval($this->_tags[$t], $this->row->paperId); if ($isbool) { return $tv !== null; } else { if ($tv !== null) { return $tv; } else { $this->_tagless[$this->row->paperId] = true; return "(none)"; } } } } if ($this->preparation) { --$this->preparation->paper_expansions; } return self::EXPANDVAR_CONTINUE; }