1<?php
2// pc_option.php -- HotCRP helper classes for paper list content
3// Copyright (c) 2006-2018 Eddie Kohler; see LICENSE.
4
5class Option_PaperColumn extends PaperColumn {
6    private $opt;
7    function __construct(Conf $conf, $cj) {
8        parent::__construct($conf, $cj);
9        $this->override = PaperColumn::OVERRIDE_FOLD_IFEMPTY;
10        $this->opt = $conf->paper_opts->get($cj->option_id);
11    }
12    function prepare(PaperList $pl, $visible) {
13        if (!$pl->user->can_view_some_paper_option($this->opt))
14            return false;
15        $pl->qopts["options"] = true;
16        return true;
17    }
18    function compare(PaperInfo $a, PaperInfo $b, ListSorter $sorter) {
19        return $this->opt->value_compare($a->option($this->opt->id),
20                                         $b->option($this->opt->id));
21    }
22    function header(PaperList $pl, $is_text) {
23        return $is_text ? $this->opt->title : htmlspecialchars($this->opt->title);
24    }
25    function completion_name() {
26        return $this->opt->search_keyword();
27    }
28    function content_empty(PaperList $pl, PaperInfo $row) {
29        return !$pl->user->can_view_paper_option($row, $this->opt);
30    }
31    function content(PaperList $pl, PaperInfo $row) {
32        return $this->opt->unparse_list_html($pl, $row, $this->viewable_row());
33    }
34    function text(PaperList $pl, PaperInfo $row) {
35        return $this->opt->unparse_list_text($pl, $row);
36    }
37}
38
39class Option_PaperColumnFactory {
40    static private function option_json($xfj, PaperOption $opt, $isrow) {
41        $cj = (array) $xfj;
42        $cj["name"] = $opt->search_keyword() . ($isrow ? ":row" : "");
43        if ($isrow)
44            $cj["row"] = true;
45        $optcj = $opt->list_display($isrow);
46        if ($optcj === true && !$isrow)
47            $optcj = ["column" => true, "className" => "pl_option"];
48        if (is_array($optcj))
49            $cj += $optcj;
50        $cj["option_id"] = $opt->id;
51        return (object) $cj;
52    }
53    static function expand($name, Conf $conf, $xfj, $m) {
54        list($ocolon, $oname, $isrow) = [$m[1], $m[2], !!$m[3]];
55        if (!$ocolon && $oname === "options") {
56            $conf->xt_factory_mark_matched();
57            $x = [];
58            foreach ($conf->xt_user->user_option_list() as $opt)
59                if ($opt->display() >= 0 && $opt->list_display($isrow))
60                    $x[] = self::option_json($xfj, $opt, $isrow);
61            return $x;
62        }
63        $opts = $conf->paper_opts->find_all($oname);
64        if (!$opts && $isrow) {
65            $oname .= $m[3];
66            $opts = $conf->paper_opts->find_all($oname);
67        }
68        if (count($opts) == 1) {
69            reset($opts);
70            $opt = current($opts);
71            if ($opt->display() >= 0 && $opt->list_display($isrow))
72                return self::option_json($xfj, $opt, $isrow);
73            $conf->xt_factory_error("Option “" . htmlspecialchars($oname) . "” can’t be displayed.");
74        } else if ($ocolon)
75            $conf->xt_factory_error("No such option “" . htmlspecialchars($oname) . "”.");
76        return null;
77    }
78    static function completions(Contact $user, $fxt) {
79        $cs = array_map(function ($opt) {
80            return $opt->search_keyword();
81        }, array_filter($user->user_option_list(), function ($opt) {
82            return $opt->display() >= 0;
83        }));
84        if (!empty($cs))
85            array_unshift($cs, "options");
86        return $cs;
87    }
88}
89