1<?php
2// help.php -- HotCRP help page
3// Copyright (c) 2006-2018 Eddie Kohler; see LICENSE.
4
5require_once("src/initweb.php");
6
7$help_topics = new GroupedExtensions($Me, [
8    '{"name":"topics","title":"Help topics","position":-1000000,"priority":1000000,"callback":"show_help_topics"}',
9    "etc/helptopics.json"
10], $Conf->opt("helpTopics"));
11
12if (!$Qreq->t && preg_match(',\A/(\w+)\z,i', Navigation::path()))
13    $Qreq->t = substr(Navigation::path(), 1);
14$topic = $Qreq->t ? : "topics";
15$want_topic = $help_topics->canonical_group($topic);
16if (!$want_topic)
17    $want_topic = "topics";
18if ($want_topic !== $topic)
19    SelfHref::redirect($Qreq, ["t" => $want_topic]);
20$topicj = $help_topics->get($topic);
21
22$Conf->header_head($topic === "topics" ? "Help" : "Help - {$topicj->title}");
23$Conf->header_body("Help", "help");
24
25class HtHead extends Ht {
26    public $conf;
27    public $user;
28    private $_tabletype;
29    private $_rowidx;
30    private $_help_topics;
31    private $_renderers = [];
32    function __construct($help_topics, Contact $user) {
33        $this->conf = $user->conf;
34        $this->user = $user;
35        $this->_help_topics = $help_topics;
36    }
37    static function subhead($title, $id = null) {
38        if ($id || $title)
39            return '<h3 class="helppage"' . ($id ? " id=\"{$id}\"" : "") . '>' . $title . "</h3>\n";
40        else
41            return "";
42    }
43    function table($tabletype = false) {
44        $this->_rowidx = 0;
45        $this->_tabletype = $tabletype;
46        return $this->_tabletype ? "" : '<table class="demargin"><tbody>';
47    }
48    function tgroup($title, $id = null) {
49        $this->_rowidx = 0;
50        if ($this->_tabletype)
51            return $this->subhead($title, $id);
52        else
53            return '<tr><td class="sentry nw remargin-left remargin-right" colspan="2"><h4 class="helppage"'
54                . ($id ? " id=\"{$id}\"" : "") . '>'
55                . $title . "</h4></td></tr>\n";
56    }
57    function trow($caption, $entry = null) {
58        if ($this->_tabletype) {
59            $t = "<div class=\"helplist-item demargin k{$this->_rowidx}\">"
60                . "<table><tbody><tr>"
61                . "<td class=\"helplist-dt remargin-left\">"
62                . $caption
63                . "</td><td class=\"helplist-dd remargin-right\">"
64                . $entry . "</td></tr></tbody></table></div>\n";
65        } else {
66            $t = "<tr class=\"k{$this->_rowidx}\">"
67                . "<td class=\"sentry remargin-left";
68            if ((string) $entry === "")
69                $t .= ' remargin-right" colspan="2">' . $caption;
70            else
71                $t .= '">' . $caption . '</td><td class="sentry remargin-right">' . $entry;
72            $t .= "</td></tr>\n";
73        }
74        $this->_rowidx = 1 - $this->_rowidx;
75        return $t;
76    }
77    function end_table() {
78        return $this->_tabletype ? "" : "</tbody></table>\n";
79    }
80    function search_link($html, $q = null) {
81        if ($q === null)
82            $q = $html;
83        if (is_string($q))
84            $q = ["q" => $q];
85        return '<a href="' . hoturl("search", $q) . '">'
86            . ($html ? : htmlspecialchars($q["q"])) . '</a>';
87    }
88    function help_link($html, $topic = null) {
89        if ($topic === null) {
90            $topic = $html;
91            $html = "Learn more";
92        }
93        if (is_string($topic) && ($hash = strpos($topic, "#")) !== false)
94            $topic = ["t" => substr($topic, 0, $hash), "anchor" => substr($topic, $hash + 1)];
95        else if (is_string($topic))
96            $topic = ["t" => $topic];
97        if (isset($topic["t"]) && ($group = $this->_help_topics->canonical_group($topic["t"])))
98            $topic["t"] = $group;
99        return '<a href="' . hoturl("help", $topic) . '">' . $html . '</a>';
100    }
101    function settings_link($html, $group = null) {
102        if ($this->user->privChair) {
103            $pre = $post = "";
104            if ($group === null) {
105                $group = $html;
106                $html = "Change this setting";
107                $pre = " (";
108                $post = ")";
109            }
110            if (is_string($group) && ($hash = strpos($group, "#")) !== false)
111                $group = ["group" => substr($group, 0, $hash), "anchor" => substr($group, $hash + 1)];
112            else if (is_string($group))
113                $group = ["group" => $group];
114            return $pre . '<a href="' . hoturl("settings", $group) . '">' . $html . '</a>' . $post;
115        } else {
116            if ($group === null)
117                return '';
118            else
119                return $html;
120        }
121    }
122    function search_form($q, $size = 20) {
123        if (is_string($q))
124            $q = ["q" => $q];
125        $t = Ht::form(hoturl("search"), ["method" => "get", "class" => "nw"])
126            . Ht::entry("q", $q["q"], ["size" => $size])
127            . " &nbsp;"
128            . Ht::submit("go", "Search");
129        foreach ($q as $k => $v) {
130            if ($k !== "q")
131                $t .= Ht::hidden($k, $v);
132        }
133        return $t . "</form>";
134    }
135    function search_trow($q, $entry) {
136        return $this->trow($this->search_form($q, 36), $entry);
137    }
138    function example_tag($property) {
139        $vt = [];
140        if ($this->user->isPC)
141            $vt = $this->conf->tags()->filter($property);
142        return empty($vt) ? $property : current($vt)->tag;
143    }
144    function current_tag_list($property) {
145        $vt = [];
146        if ($this->user->isPC)
147            $vt = $this->conf->tags()->filter($property);
148        if (empty($vt))
149            return "";
150        else
151            return " (currently " . join(", ", array_map(function ($t) {
152                return $this->search_link($t->tag, "#{$t->tag}");
153            }, $vt)) . ")";
154    }
155    function render_group($topic) {
156        foreach ($this->_help_topics->members($topic) as $gj) {
157            Conf::xt_resolve_require($gj);
158            if (isset($gj->callback)) {
159                $cb = $gj->callback;
160                if ($cb[0] === "*") {
161                    $colons = strpos($cb, ":");
162                    $klass = substr($cb, 1, $colons - 1);
163                    if (!isset($this->_renderers[$klass]))
164                        $this->_renderers[$klass] = new $klass($this, $gj);
165                    $cb = [$this->_renderers[$klass], substr($cb, $colons + 2)];
166                }
167                call_user_func($cb, $this, $gj);
168            }
169        }
170    }
171    function groups() {
172        return $this->_help_topics->groups();
173    }
174}
175
176$hth = new HtHead($help_topics, $Me);
177
178
179function show_help_topics($hth) {
180    echo "<dl>\n";
181    foreach ($hth->groups() as $ht) {
182        if ($ht->name !== "topics" && isset($ht->title)) {
183            echo '<dt><strong><a href="', hoturl("help", "t=$ht->name"), '">', $ht->title, '</a></strong></dt>';
184            if (isset($ht->description))
185                echo '<dd>', get($ht, "description", ""), '</dd>';
186            echo "\n";
187        }
188    }
189    echo "</dl>\n";
190}
191
192
193function meaningful_pc_tag(Contact $user) {
194    if ($user->isPC)
195        foreach ($user->conf->pc_tags() as $tag)
196            if ($tag !== "pc")
197                return $tag;
198    return false;
199}
200
201function meaningful_round_name(Contact $user) {
202    if ($user->isPC) {
203        $rounds = $user->conf->round_list();
204        for ($i = 1; $i < count($rounds); ++$i)
205            if ($rounds[$i] !== ";")
206                return $rounds[$i];
207    }
208    return false;
209}
210
211
212echo '<div class="leftmenu-menu-container"><div class="leftmenu-list">';
213foreach ($help_topics->groups() as $gj) {
214    if ($gj->name === $topic)
215        echo '<div class="leftmenu-item-on">', $gj->title, '</div>';
216    else if (isset($gj->title))
217        echo '<div class="leftmenu-item ui js-click-child">',
218            '<a href="', hoturl("help", "t=$gj->name"), '">', $gj->title, '</a></div>';
219    if ($gj->name === "topics")
220        echo '<div class="c g"></div>';
221}
222echo "</div></div>\n",
223    '<div class="leftmenu-content-container"><div id="helpcontent" class="leftmenu-content">';
224
225echo '<h2 class="helppage">', $topicj->title, '</h2>';
226$hth->render_group($topic);
227echo "</div></div>\n";
228
229
230$Conf->footer();
231