',
Ht::select("rev_round", $rev_rounds, $Qreq->rev_round ? : $expected_round, ["id" => "assrevround", "class" => "ignore-diff"]), '
· ';
diff --git a/reviewprefs.php b/reviewprefs.php
index 4285f4bed..9b2d09eda 100644
--- a/reviewprefs.php
+++ b/reviewprefs.php
@@ -248,8 +248,9 @@ function parseUploadedPreferences($text, $filename, $apply) {
"pageurl" => $Conf->hoturl_site_relative_raw("reviewprefs")
]);
$pl = new PaperList("pf", $search, ["sort" => true], $Qreq);
-$pl->add_report_default_view();
-$pl->add_session_view();
+$pl->apply_view_report_default();
+$pl->apply_view_session();
+$pl->apply_view_qreq();
$pl->set_table_id_class("foldpl", "pltable-fullw", "p#");
$pl_text = $pl->table_html(["fold_session_prefix" => "pfdisplay.",
"footer_extra" => "
" . Ht::submit("fn", "Save changes", ["data-default-submit-all" => 1, "value" => "saveprefs"]) . "
",
@@ -259,7 +260,7 @@ function parseUploadedPreferences($text, $filename, $apply) {
// DISPLAY OPTIONS
echo Ht::form($Conf->hoturl("reviewprefs"), [
"method" => "get", "id" => "searchform",
- "class" => "has-fold fold10" . ($pl->showing("authors") ? "o" : "c")
+ "class" => "has-fold fold10" . ($pl->viewing("authors") ? "o" : "c")
]);
if ($Me->privChair) {
@@ -290,7 +291,7 @@ function parseUploadedPreferences($text, $filename, $apply) {
function show_pref_element($pl, $name, $text, $extra = []) {
return '
'
- . Ht::checkbox("show$name", 1, $pl->showing($name), [
+ . Ht::checkbox("show$name", 1, $pl->viewing($name), [
"class" => "uich js-plinfo ignore-diff" . (isset($extra["fold_target"]) ? " js-foldup" : ""),
"data-fold-target" => $extra["fold_target"] ?? null
]) . "" . Ht::label($text) . '';
diff --git a/scripts/script.js b/scripts/script.js
index 7b716db81..89f3af25a 100644
--- a/scripts/script.js
+++ b/scripts/script.js
@@ -3143,11 +3143,11 @@ $(document).on("keypress", "input.js-autosubmit", function (event) {
if (event_modkey(event) || event_key(event) !== "Enter") {
return;
}
- var $f = $(event.target).closest("form"),
- type = $f.data("autosubmitType"),
- defaulte = $f[0] ? $f[0]["default"] : null;
+ var f = event.target.closest("form"),
+ type = $(f).data("autosubmitType"),
+ defaulte = f ? f.elements["default"] : null;
if (defaulte && type) {
- $f[0].defaultact.value = type;
+ f.elements.defaultact.value = type;
event.target.blur();
defaulte.click();
}
@@ -3161,6 +3161,15 @@ handle_ui.on("js-submit-mark", function (event) {
$(this).closest("form").data("submitMark", event.target.value);
});
+handle_ui.on("js-keydown-enter-submit", function (event) {
+ if (event.type === "keydown"
+ && !(event_modkey(event) & (event_modkey.SHIFT | event_modkey.ALT))
+ && event_key(event) === "Enter") {
+ $(event.target.closest("form")).trigger("submit");
+ event.preventDefault();
+ }
+});
+
// assignment selection
(function ($) {
@@ -8513,8 +8522,22 @@ handle_ui.on("js-edit-view-options", function () {
$.ajax(hoturl_post("api/viewoptions"), {
method: "POST", data: $(this).serialize(),
success: function (data) {
- if (data.ok)
+ if (data.ok) {
$d.close();
+ location.reload();
+ } else {
+ var ta = $d.find("[name=display]")[0];
+ while (ta.previousSibling
+ && hasClass(ta.previousSibling, "feedback")) {
+ ta.parentElement.removeChild(ta.previousSibling);
+ }
+ data.errors = data.errors || ["Error saving view options."];
+ for (var i in data.errors) {
+ $('' + data.errors[i] + '
').insertBefore(ta);
+ }
+ addClass(ta, "has-error");
+ ta.focus();
+ }
}
});
event.preventDefault();
@@ -8527,7 +8550,7 @@ handle_ui.on("js-edit-view-options", function () {
hc.push('' + escape_entities(display_default || "(none)") + '
');
hc.pop();
hc.push('');
- hc.push('');
+ hc.push('');
hc.pop();
hc.push_actions(['', '']);
$d = hc.show();
diff --git a/search.php b/search.php
index f845dbb8a..16c05bb9f 100644
--- a/search.php
+++ b/search.php
@@ -157,11 +157,9 @@ function savesearch() {
}
assert(!isset($Qreq->display));
$pl = new PaperList("pl", $Search, ["sort" => true], $Qreq);
-$pl->add_report_default_view();
-$pl->add_session_view();
-if (isset($Qreq->forceShow)) {
- $pl->set_view("force", !!$Qreq->forceShow);
-}
+$pl->apply_view_report_default();
+$pl->apply_view_session();
+$pl->apply_view_qreq();
if (isset($Qreq->q)) {
$pl->set_table_id_class("foldpl", "pltable-fullw", "p#");
if ($SSel->count()) {
@@ -200,7 +198,7 @@ function checkbox_item($column, $type, $title, $options = []) {
global $pl;
$options["class"] = "uich js-plinfo";
$x = '';
$this->item($column, $x);
}
@@ -457,7 +455,7 @@ function echo_request_as_hidden_inputs($specialscore = false) {
// Conflict display
if ($Me->privChair) {
echo '',
- Ht::checkbox("showforce", 1, $pl->showing("force"),
+ Ht::checkbox("showforce", 1, $pl->viewing("force"),
["id" => "showforce", "class" => "uich js-plinfo"]),
" ", Ht::label("Override conflicts", "showforce"), " | ";
}
diff --git a/src/api/api_search.php b/src/api/api_search.php
index fbb6cb4ab..406454fb4 100644
--- a/src/api/api_search.php
+++ b/src/api/api_search.php
@@ -23,8 +23,8 @@ static function search(Contact $user, Qrequest $qreq) {
$search = new PaperSearch($user, ["t" => $t, "q" => $q, "qt" => $qreq->qt, "urlbase" => $qreq->urlbase, "reviewer" => $qreq->reviewer]);
$pl = new PaperList($qreq->report ? : "pl", $search, ["sort" => true], $qreq);
- $pl->add_report_default_view();
- $pl->add_session_view();
+ $pl->apply_view_report_default();
+ $pl->apply_view_session();
$ih = $pl->ids_and_groups();
return ["ok" => true, "ids" => $ih[0], "groups" => $ih[1],
"hotlist" => $pl->session_list_object()->info_string()];
diff --git a/src/api/api_searchconfig.php b/src/api/api_searchconfig.php
index fc060abd4..2149a9778 100644
--- a/src/api/api_searchconfig.php
+++ b/src/api/api_searchconfig.php
@@ -8,36 +8,44 @@ static function viewoptions(Contact $user, Qrequest $qreq) {
if ($report !== "pl" && $report !== "pf") {
return new JsonResult(400, "Bad request.");
}
- if ($qreq->method() !== "GET" && $user->privChair) {
+ $search = new PaperSearch($user, "NONE");
+
+ if ($qreq->method() === "POST" && $user->privChair) {
if (!isset($qreq->display)) {
return new JsonResult(400, "Bad request.");
}
- $base_display = "";
- if ($report === "pl") {
- $base_display = $user->conf->review_form()->default_display();
+ $pl = new PaperList($report, $search, ["sort" => true]);
+ $pl->apply_view_report_default();
+ $default_view = $pl->unparse_view(true);
+ $pl->parse_view($qreq->display, PaperList::VIEWORIGIN_EXPLICIT);
+ $parsed_view = $pl->unparse_view(true);
+
+ // check for errors
+ $pl->table_html();
+ if ($pl->message_set()->has_error()) {
+ return new JsonResult([
+ "ok" => false,
+ "errors" => $pl->message_set()->error_texts()
+ ]);
}
- $display = simplify_whitespace($qreq->display);
- if ($display === $base_display) {
+
+ if ($parsed_view === $default_view) {
$user->conf->save_setting("{$report}display_default", null);
} else {
- $user->conf->save_setting("{$report}display_default", 1, $display);
+ $user->conf->save_setting("{$report}display_default", 1, join(" ", $parsed_view));
}
$user->save_session("{$report}display", null);
}
- $search = new PaperSearch($user, "NONE");
- $pl = new PaperList($report, $search, ["sort" => true]);
- $vb = $pl->viewer_list();
-
$pl = new PaperList($report, $search, ["sort" => true]);
- $pl->add_report_default_view();
- $vd = PaperList::viewer_diff($pl->viewer_list(), $vb);
+ $pl->apply_view_report_default();
+ $vd = $pl->unparse_view(true);
$search = new PaperSearch($user, $qreq->q ?? "NONE");
$pl = new PaperList($report, $search, ["sort" => $qreq->sort ?? true]);
- $pl->add_report_default_view();
- $pl->add_session_view();
- $vr = PaperList::viewer_diff($pl->viewer_list(), $vb);
+ $pl->apply_view_report_default();
+ $pl->apply_view_session();
+ $vr = $pl->unparse_view(true);
return new JsonResult([
"ok" => true, "report" => $report,
diff --git a/src/api/api_session.php b/src/api/api_session.php
index a84db0032..b0c44aeca 100644
--- a/src/api/api_session.php
+++ b/src/api/api_session.php
@@ -81,18 +81,12 @@ static function setsession(Contact $user, $qreq) {
static function change_display(Contact $user, $report, $settings) {
$search = new PaperSearch($user, "NONE");
$pl = new PaperList($report, $search, ["sort" => true]);
- $pl->add_report_default_view();
- $vd = $pl->viewer_list();
-
- $pl = new PaperList($report, $search, ["sort" => true]);
- $pl->add_report_default_view();
- $pl->add_session_view();
+ $pl->apply_view_report_default();
+ $pl->apply_view_session();
foreach ($settings as $k => $v) {
$pl->set_view($k, $v);
}
- $vd = PaperList::viewer_diff($pl->viewer_list(), $vd);
- $vd = array_filter($vd, function ($x) { return !str_starts_with($x, "sort:"); });
-
+ $vd = array_filter($pl->unparse_view(true), function ($x) { return !str_starts_with($x, "sort:"); });
$user->save_session("{$report}display", join(" ", $vd));
}
}
diff --git a/src/conference.php b/src/conference.php
index 40ace62a3..abf3c7f2a 100644
--- a/src/conference.php
+++ b/src/conference.php
@@ -199,6 +199,8 @@ class Conf {
public $xt_context;
private $_xt_allow_checkers;
public $_xt_allow_callback;
+ /** @var int */
+ private $_xt_checks = 0;
/** @var ?array> */
private $_formula_functions;
@@ -1185,11 +1187,14 @@ function xt_search_name($map, $name, $user, $found = null, $noalias = false) {
if (isset($xt->deprecated) && $xt->deprecated) {
error_log("{$this->dbname}: deprecated extension for `{$iname}`\n" . debug_string_backtrace());
}
- if (isset($xt->alias) && is_string($xt->alias) && !$noalias) {
+ if (!isset($xt->alias) || !is_string($xt->alias) || $noalias) {
+ ++$this->_xt_checks;
+ if ($this->xt_checkf($xt, $user)) {
+ return $xt;
+ }
+ } else {
$name = $xt->alias;
break;
- } else if ($this->xt_checkf($xt, $user)) {
- return $xt;
}
}
}
@@ -5002,8 +5007,12 @@ function paper_columns($name, Contact $user) {
if ($name === "" || $name[0] === "?") {
return [];
}
+ $nchecks = $this->_xt_checks;
$uf = $this->xt_search_name($this->paper_column_map(), $name, $user);
$ufs = $this->xt_search_factories($this->_paper_column_factories, $name, $user, $uf, "i");
+ if (empty($ufs) || $ufs === [null]) {
+ PaperColumn::column_error($user, $nchecks === $this->_xt_checks ? "No matching field." : "You can’t view that field.", true);
+ }
return array_values(array_filter($ufs, "Conf::xt_resolve_require"));
}
diff --git a/src/listactions/la_get_sub.php b/src/listactions/la_get_sub.php
index eed5fa016..26d506997 100644
--- a/src/listactions/la_get_sub.php
+++ b/src/listactions/la_get_sub.php
@@ -118,8 +118,8 @@ function run(Contact $user, Qrequest $qreq, SearchSelection $ssel) {
$search->restrict_match([$ssel, "is_selected"]);
assert(!isset($qreq->display));
$pl = new PaperList("pl", $search, ["sort" => true], $qreq);
- $pl->add_report_default_view();
- $pl->add_session_view();
+ $pl->apply_view_report_default();
+ $pl->apply_view_session();
$pl->set_view("sel", false);
list($header, $data) = $pl->text_csv();
return $user->conf->make_csvg("data", CsvGenerator::FLAG_ITEM_COMMENTS)
diff --git a/src/papercolumn.php b/src/papercolumn.php
index fb8df4251..45a63a48f 100644
--- a/src/papercolumn.php
+++ b/src/papercolumn.php
@@ -37,9 +37,13 @@ static function make(Conf $conf, $cj, $decorations = []) {
}
return $pc;
}
- static function column_error(Contact $user, $msg) {
- assert($user->conf->xt_context instanceof PaperList);
- $user->conf->xt_context->column_error($msg);
+ /** @param string $msg
+ * @param bool $is_default */
+ static function column_error(Contact $user, $msg, $is_default = false) {
+ $c = $user->conf->xt_context;
+ if ($c instanceof PaperList) {
+ $c->column_error($msg, $is_default);
+ }
}
@@ -408,13 +412,16 @@ function add_decoration($decor) {
if ($decor === "full" || $decor === "short") {
$this->aufull = $decor === "full";
return $this->__add_decoration($this->aufull ? "full" : null, ["full"]);
+ } else if ($decor === "anon" || $decor === "noanon") {
+ $this->anonau = $decor === "anon";
+ return $this->__add_decoration($this->anonau ? "anon" : "noanon", ["anon", "noanon"]);
} else {
return parent::add_user_sort_decoration($decor) || parent::add_decoration($decor);
}
}
function prepare(PaperList $pl, $visible) {
- $this->aufull = $this->aufull ?? $pl->showing("aufull");
- $this->anonau = $pl->showing("anonau");
+ $this->aufull = $this->aufull ?? $pl->viewing("aufull");
+ $this->anonau = $this->anonau ?? $pl->viewing("anonau");
$this->highlight = $pl->search->field_highlighter("authorInformation");
return $pl->user->can_view_some_authors();
}
diff --git a/src/paperlist.php b/src/paperlist.php
index 207ae4f4a..208996e51 100644
--- a/src/paperlist.php
+++ b/src/paperlist.php
@@ -149,11 +149,22 @@ class PaperList {
private $_paper_linkto;
private $_view_kanban = false;
private $_view_force = false;
- private $_viewing = [];
- private $_view_origin = [];
+ /** @var array */
+ private $_viewf = [];
+ /** @var array> */
private $_view_decorations = [];
private $_atab;
+ const VIEWORIGIN_MASK = 15;
+ const VIEWORIGIN_NONE = -1;
+ const VIEWORIGIN_REPORT = 0;
+ const VIEWORIGIN_DEFAULT_DISPLAY = 1;
+ const VIEWORIGIN_SESSION = 2;
+ const VIEWORIGIN_EXPLICIT = 3;
+ const VIEW_REPORTSHOW = 16;
+ const VIEW_SHOW = 32;
+ const VIEW_EDIT = 64;
+
private $_table_id;
private $_table_class;
private $_report_id;
@@ -239,6 +250,9 @@ function __construct(string $report, PaperSearch $search, $args = [], $qreq = nu
$this->_report_id = $report;
$this->parse_view($this->_list_columns(), self::VIEWORIGIN_REPORT);
+ if ($this->viewable_author_types() === 1) {
+ $this->set_view("anonau", true, self::VIEWORIGIN_REPORT);
+ }
if ($this->sortable) {
if (is_string($args["sort"])) {
@@ -251,10 +265,10 @@ function __construct(string $report, PaperSearch $search, $args = [], $qreq = nu
$qe = $this->search->term();
if ($qe instanceof Then_SearchTerm) {
for ($i = 0; $i < $qe->nthen; ++$i) {
- $this->set_view_search($qe->child[$i], $i);
+ $this->apply_view_search($qe->child[$i], $i);
}
}
- $this->set_view_search($qe, -1);
+ $this->apply_view_search($qe, -1);
if ($qreq->forceShow !== null) {
$this->set_view("force", !!$qreq->forceShow);
@@ -341,11 +355,28 @@ function add_column($name, PaperColumn $col) {
"kanban" => -2, "rownum" => -1, "statistics" => -1, "all" => -4, "linkto" => -4
];
- const VIEWORIGIN_NONE = -1;
- const VIEWORIGIN_REPORT = 0;
- const VIEWORIGIN_DEFAULT_DISPLAY = 1;
- const VIEWORIGIN_SESSION = 2;
- const VIEWORIGIN_EXPLICIT = 3;
+
+ /** @param string $fname
+ * @return bool */
+ function viewing($fname) {
+ $fname = self::$view_synonym[$fname] ?? $fname;
+ return ($this->_viewf[$fname] ?? 0) >= self::VIEW_SHOW;
+ }
+
+ /** @param string $fname
+ * @return bool
+ * @deprecated */
+ function showing($fname) {
+ return $this->viewing($fname);
+ }
+
+ /** @param string $k
+ * @return int */
+ function view_origin($k) {
+ $k = self::$view_synonym[$k] ?? $k;
+ return ($this->_viewf[$k] ?? 0) & self::VIEWORIGIN_MASK;
+ }
+
/** @param string $k
* @param 'show'|'hide'|'edit'|bool $v
@@ -353,47 +384,56 @@ function add_column($name, PaperColumn $col) {
* @param ?list $decorations */
function set_view($k, $v, $origin = null, $decorations = null) {
$origin = $origin ?? self::VIEWORIGIN_EXPLICIT;
+ assert($origin >= self::VIEWORIGIN_REPORT && $origin <= self::VIEWORIGIN_EXPLICIT);
if ($v === "show" || $v === "hide") {
$v = $v === "show";
}
+ assert(is_bool($v) || $v === "edit");
+
if ($k !== "" && $k[0] === "\"" && $k[strlen($k) - 1] === "\"") {
$k = substr($k, 1, -1);
}
- $k = self::$view_synonym[$k] ?? $k;
-
- if (($this->_view_origin[$k] ?? -1) > $origin) {
- return;
- } else if ($k === "all") {
- if ($v === false) {
- foreach ($this->_viewing as $k => &$v) {
- if (!isset(self::$view_fake[$k])) {
- $v = false;
- }
- }
+ if ($k === "all") {
+ assert($v === false && $decorations === null);
+ $views = array_keys($this->_viewf);
+ foreach ($views as $k) {
+ $this->set_view($k, $v, $origin, null);
}
return;
}
+ $k = self::$view_synonym[$k] ?? $k;
- $this->_viewing[$k] = $v;
- $this->_view_origin[$k] = $origin;
- $this->_view_decorations[$k] = empty($decorations) ? null : $decorations;
+ $flags = &$this->_viewf[$k];
+ $flags = $flags ?? 0;
+ if ($origin === self::VIEWORIGIN_REPORT) {
+ $flags = ($flags & ~self::VIEW_REPORTSHOW) | ($v ? self::VIEW_REPORTSHOW : 0);
+ }
+ if (($flags & self::VIEWORIGIN_MASK) <= $origin) {
+ $flags = ($flags & self::VIEW_REPORTSHOW)
+ | $origin
+ | ($v ? self::VIEW_SHOW : 0)
+ | ($v === "edit" ? self::VIEW_EDIT : 0);
+ if (!empty($decorations)) {
+ $this->_view_decorations[$k] = $decorations;
+ } else {
+ unset($this->_view_decorations[$k]);
+ }
- if ($k === "force") {
- $this->_view_force = $v;
- } else if ($k === "kanban") {
- $this->_view_kanban = $v;
- } else if ($k === "linkto") {
- if (!empty($decorations)
- && in_array($decorations[0], ["paper", "paperedit", "assign", "finishreview"])) {
- $this->_paper_linkto = $decorations[0];
+ if ($k === "force") {
+ $this->_view_force = $v;
+ } else if ($k === "kanban") {
+ $this->_view_kanban = $v;
+ } else if ($k === "linkto") {
+ if (!empty($decorations)
+ && in_array($decorations[0], ["paper", "paperedit", "assign", "finishreview"])) {
+ $this->_paper_linkto = $decorations[0];
+ }
+ } else if (($k === "aufull" || $k === "anonau")
+ && $origin === self::VIEWORIGIN_EXPLICIT
+ && $v
+ && $this->view_origin("authors") < $origin) {
+ $this->set_view("authors", true, $origin, null);
}
- } else if (($k === "aufull" || $k === "anonau")
- && $origin === self::VIEWORIGIN_EXPLICIT
- && $v === true
- && ($this->_view_origin["authors"] ?? -1) < self::VIEWORIGIN_EXPLICIT) {
- $this->_viewing["authors"] = true;
- $this->_view_origin["authors"] = $origin;
- $this->_view_decorations["authors"] = null;
}
}
@@ -428,12 +468,12 @@ private function _add_sorter($name, $decorations, $sort_subset) {
}
}
- /** @param list $words
+ /** @param list $groups
* @param ?int $origin
* @param int $sort_subset */
- private function set_view_list($words, $origin, $sort_subset) {
+ private function set_view_list($groups, $origin, $sort_subset) {
$has_sort = false;
- foreach (PaperSearch::view_generator($words) as $akd) {
+ foreach (PaperSearch::view_generator($groups) as $akd) {
if ($akd[0] !== "sort" && $sort_subset === -1) {
$this->set_view($akd[1], substr($akd[0], 0, 4), $origin, $akd[2]);
}
@@ -452,7 +492,20 @@ function parse_view($str, $origin = null) {
}
}
- function add_report_default_view() {
+ /** @param int $sort_subset */
+ private function apply_view_search(SearchTerm $qe, $sort_subset) {
+ $nsort = count($this->_sortcol);
+ $this->set_view_list($qe->get_float("view") ?? [], null, $sort_subset);
+ if ($nsort === count($this->_sortcol)
+ && ($sortcol = $qe->default_sort_column(true, $this->search))
+ && $sortcol->prepare($this, PaperColumn::PREP_SORT)) {
+ assert(!!$sortcol->sort);
+ $sortcol->sort_subset = $sort_subset;
+ $this->_sortcol[] = $sortcol;
+ }
+ }
+
+ function apply_view_report_default() {
if ($this->_report_id === "pl") {
$s = $this->conf->setting_data("pldisplay_default")
?? $this->conf->review_form()->default_display();
@@ -464,31 +517,75 @@ function add_report_default_view() {
$this->parse_view($s, self::VIEWORIGIN_DEFAULT_DISPLAY);
}
- function add_session_view() {
+ function apply_view_session() {
if ($this->_report_id === "pl" || $this->_report_id === "pf") {
$s = $this->user->session("{$this->_report_id}display");
$this->parse_view($s, self::VIEWORIGIN_SESSION);
}
}
- /** @param int $sort_subset */
- private function set_view_search(SearchTerm $qe, $sort_subset) {
- $nsort = count($this->_sortcol);
- $this->set_view_list($qe->get_float("view") ?? [], null, $sort_subset);
- if ($nsort === count($this->_sortcol)
- && ($sortcol = $qe->default_sort_column(true, $this->search))
- && $sortcol->prepare($this, PaperColumn::PREP_SORT)) {
- assert(!!$sortcol->sort);
- $sortcol->sort_subset = $sort_subset;
- $this->_sortcol[] = $sortcol;
+ function apply_view_qreq() {
+ foreach ($this->qreq as $k => $v) {
+ if (str_starts_with($k, "show") && $v) {
+ $name = substr($k, 4);
+ $this->set_view($name, true, self::VIEWORIGIN_SESSION, $this->_view_decorations[$name] ?? null);
+ } else if ($k === "forceShow") {
+ $this->set_view("force", !!$v, self::VIEWORIGIN_SESSION);
+ }
}
}
- /** @param string $k
- * @return int */
- function view_origin($k) {
- $k = self::$view_synonym[$k] ?? $k;
- return $this->_view_origin[$k] ?? self::VIEWORIGIN_NONE;
+ /** @param bool $report_diff
+ * @return list */
+ function unparse_view($report_diff = false) {
+ $this->_prepare();
+ $res = [];
+ $nextpos = 1000000;
+ foreach ($this->_viewf as $k => $v) {
+ if ($report_diff
+ ? ($v >= self::VIEW_SHOW) !== (($v & self::VIEW_REPORTSHOW) !== 0)
+ : $v >= self::VIEW_SHOW) {
+ $name = $k;
+ $pos = self::$view_fake[$k] ?? null;
+ if ($pos === null) {
+ list($name, $decorations) = self::parse_column($k);
+ $fs = $this->conf->paper_columns($name, $this->user);
+ if (count($fs) && isset($fs[0]->position)) {
+ $pos = $fs[0]->position;
+ $name = $fs[0]->name;
+ } else {
+ $pos = $nextpos++;
+ }
+ }
+ $key = "$pos $name";
+ if ($v >= self::VIEW_EDIT) {
+ $kw = "edit";
+ } else if ($v >= self::VIEW_SHOW) {
+ $kw = "show";
+ } else {
+ $kw = "hide";
+ }
+ $res[$key] = PaperSearch::unparse_view($kw, $name, $this->_view_decorations[$k] ?? null);
+ }
+ }
+ if (((($this->_viewf["anonau"] ?? 0) >= self::VIEW_SHOW && $this->conf->submission_blindness() == Conf::BLIND_OPTIONAL)
+ || ($this->_viewf["aufull"] ?? 0) >= self::VIEW_SHOW)
+ && ($this->_viewf["authors"] ?? 0) < self::VIEW_SHOW) {
+ $res["150 authors"] = "hide:authors";
+ }
+ ksort($res, SORT_NATURAL);
+ $res = array_values($res);
+
+ foreach ($this->sorters() as $s) {
+ $res[] = PaperSearch::unparse_view("sort", $s->name, $s->decorations());
+ if ($s->name === "id") {
+ break;
+ }
+ }
+ while (!empty($res) && $res[count($res) - 1] === "sort:id") {
+ array_pop($res);
+ }
+ return $res;
}
@@ -616,10 +713,10 @@ private function _set_sort_etag_anno_groups() {
}
$dt = $this->conf->tags()->add(Tagger::base($etag));
if (!$dt->has_order_anno()
- && ($this->_viewing["#$etag"] ?? false) !== "edit"
- && ($this->_viewing["#$alt_etag"] ?? false) !== "edit"
- && ($this->_viewing["tagval:$etag"] ?? false) !== "edit"
- && ($this->_viewing["tagval:$alt_etag"] ?? false) !== "edit") {
+ && !(($this->_viewf["#$etag"] ?? 0) & self::VIEW_EDIT)
+ && !(($this->_viewf["#$alt_etag"] ?? 0) & self::VIEW_EDIT)
+ && !(($this->_viewf["tagval:$etag"] ?? 0) & self::VIEW_EDIT)
+ && !(($this->_viewf["tagval:$alt_etag"] ?? 0) & self::VIEW_EDIT)) {
return;
}
$srch = $this->search;
@@ -800,33 +897,32 @@ private function _compute_has($key) {
}
- function column_error($text) {
- if ($this->_current_find_column) {
- $this->_column_errors_by_name[$this->_current_find_column][] = $text;
+ function column_error($text, $is_default = false) {
+ if (($name = $this->_current_find_column)
+ && (!$is_default || empty($this->_column_errors_by_name[$name]))) {
+ $this->_column_errors_by_name[$name][] = $text;
}
}
- /** @param string $name
- * @return list */
- private function find_columns($name) {
- $viewdecorations = null;
- if (str_starts_with($name, "[")) {
- $words = SearchSplitter::split_balanced_parens(substr($name, 1, strlen($name) - (str_ends_with($name, "]") ? 2 : 1)));
- $name = $words[0] ?? "NONE";
- $viewdecorations = array_slice($words, 1);
+ /** @param string $str
+ * @return array{string,?list} */
+ static private function parse_column($str) {
+ if (str_starts_with($str, "[")) {
+ $ws = SearchSplitter::split_balanced_parens(substr($str, 1, strlen($str) - (str_ends_with($str, "]") ? 2 : 1)));
+ return [$ws[0] ?? "?", count($ws) > 1 ? array_slice($ws, 1) : null];
+ } else {
+ return [$str, null];
}
+ }
+
+ /** @param string $str
+ * @return list */
+ private function find_columns($str) {
+ list($name, $viewdecorations) = self::parse_column($str);
if (!array_key_exists($name, $this->_columns_by_name)) {
$this->_current_find_column = $name;
- $fs = $this->conf->paper_columns($name, $this->user);
- if (!$fs && !isset($this->_column_errors_by_name[$name])) {
- if ($this->conf->paper_columns($name, $this->conf->root_user())) {
- $this->_column_errors_by_name[$name][] = "Permission error.";
- } else {
- $this->_column_errors_by_name[$name][] = "No such column.";
- }
- }
$nfs = [];
- foreach ($fs as $fdef) {
+ foreach ($this->conf->paper_columns($name, $this->user) as $fdef) {
$decorations = $viewdecorations
?? $this->_view_decorations[$fdef->name]
?? $this->_view_decorations[$name]
@@ -851,12 +947,13 @@ private function find_column($name) {
return ($this->find_columns($name))[0] ?? null;
}
- private function _expand_view_column($k, $report) {
- if (!isset(self::$view_fake[$k]) && ($this->_viewing[$k] ?? false)) {
+ private function _expand_view_column($k) {
+ if (!isset(self::$view_fake[$k])
+ && ($this->_viewf[$k] ?? 0) >= self::VIEW_SHOW) {
$fs = $this->find_columns($k);
- if (!$fs && $report && isset($this->_column_errors_by_name[$k])) {
- foreach ($this->_column_errors_by_name[$k] as $i => $err) {
- $this->message_set()->error_at($k, htmlspecialchars($k) . ": " . $err);
+ if (!$fs && $this->view_origin($k) >= self::VIEWORIGIN_EXPLICIT) {
+ foreach ($this->_column_errors_by_name[$k] ?? [] as $err) {
+ $this->message_set()->error_at($k, "Can’t show " . htmlspecialchars($k) . ": " . $err);
}
}
return $fs;
@@ -871,23 +968,23 @@ private function _columns() {
$this->table_attr = [];
assert(empty($this->row_attr));
- // extract columns from _viewing
+ // extract columns from _viewf
$old_context = $this->conf->xt_swap_context($this);
- $fields = $editable = [];
- foreach ($this->_viewing as $k => $v) {
- foreach ($this->_expand_view_column($k, true) as $f) {
- assert($v === true || $v === "edit");
+ $fields = $viewf = [];
+ foreach ($this->_viewf as $k => $v) {
+ foreach ($this->_expand_view_column($k) as $f) {
+ assert($v >= self::VIEW_SHOW);
$fields[$f->name] = $fields[$f->name] ?? $f;
- $editable[$f->name] = ($editable[$f->name] ?? false) || $v === "edit";
+ $viewf[$f->name] = $this->_viewf[$f->name] ?? $v;
}
}
$this->conf->xt_swap_context($old_context);
- // update _viewing, prepare, mark fields editable
+ // update _viewf, prepare, mark fields editable
$fields2 = [];
foreach ($fields as $k => $f) {
- $this->_viewing[$k] = $editable[$f->name] ? "edit" : true;
- if ($editable[$k]) {
+ $this->_viewf[$k] = $viewf[$k];
+ if ($viewf[$k] >= self::VIEW_EDIT) {
$f->mark_editable();
}
$f->is_visible = true;
@@ -1003,15 +1100,6 @@ function viewable_author_types() {
}
}
- function showing($fname) {
- $fname = self::$view_synonym[$fname] ?? $fname;
- if (isset($this->qreq["show$fname"])) {
- return true;
- } else {
- return $this->_viewing[$fname] ?? false;
- }
- }
-
private function _wrap_conflict($main_content, $override_content, PaperColumn $fdef) {
if ($main_content === $override_content) {
return $main_content;
@@ -1313,15 +1401,15 @@ private function _analyze_folds($rstate, $fieldDef) {
}
}
// authorship requires special handling
- $classes[] = "fold2" . ($this->showing("anonau") ? "o" : "c");
- $classes[] = "fold4" . ($this->showing("aufull") ? "o" : "c");
+ $classes[] = "fold2" . ($this->viewing("anonau") ? "o" : "c");
+ $classes[] = "fold4" . ($this->viewing("aufull") ? "o" : "c");
if ($this->user->is_track_manager()) {
- $classes[] = "fold5" . ($this->showing("force") ? "o" : "c");
+ $classes[] = "fold5" . ($this->viewing("force") ? "o" : "c");
}
if ($has_sel) {
- $classes[] = "fold6" . ($this->showing("rownum") ? "o" : "c");
+ $classes[] = "fold6" . ($this->viewing("rownum") ? "o" : "c");
}
- $classes[] = "fold7" . ($this->showing("statistics") ? "o" : "c");
+ $classes[] = "fold7" . ($this->viewing("statistics") ? "o" : "c");
$classes[] = "fold8" . ($has_statistics ? "o" : "c");
$this->table_attr["data-columns"] = $jscol;
}
@@ -1990,54 +2078,4 @@ function text_csv($options = []) {
return [$header, $body];
}
-
-
- function viewer_list() {
- $this->_prepare();
- $res = [];
- foreach ($this->_viewing as $k => $v) {
- if (!$v) {
- // skip
- } else if (isset(self::$view_fake[$k])) {
- $key = self::$view_fake[$k] . " " . $k;
- $res[$key] = "show:$k";
- } else {
- foreach ($this->_expand_view_column($k, false) as $col) {
- $key = ($col->position ? : 0) . " " . $col->name;
- $res[$key] = PaperSearch::unparse_view($v, $col->name, $col->decorations());
- }
- }
- }
- if (((($this->_viewing["anonau"] ?? false) && $this->conf->submission_blindness() == Conf::BLIND_OPTIONAL)
- || ($this->_viewing["aufull"] ?? false))
- && !($this->_viewing["authors"] ?? false)) {
- $res["150 authors"] = "hide:authors";
- }
- ksort($res, SORT_NATURAL);
- $res = array_values($res);
-
- foreach ($this->sorters() as $s) {
- $res[] = PaperSearch::unparse_view("sort", $s->name, $s->decorations());
- if ($s->name === "id") {
- break;
- }
- }
- while (!empty($res) && $res[count($res) - 1] === "sort:id") {
- array_pop($res);
- }
- return $res;
- }
-
- static function viewer_diff($v1, $v2) {
- $res = [];
- foreach ($v1 as $x) {
- if (!str_starts_with($x, "show:") || !in_array($x, $v2))
- $res[] = $x;
- }
- foreach ($v2 as $x) {
- if (str_starts_with($x, "show:") && !in_array($x, $v1))
- $res[] = "hide:" . substr($x, 5);
- }
- return $res;
- }
}