1<?php
2// listaction.php -- HotCRP helper class for paper search actions
3// Copyright (c) 2006-2018 Eddie Kohler; see LICENSE.
4
5class ListAction {
6    public $subname;
7    const ENOENT = "No such action.";
8    const EPERM = "Permission error.";
9    function allow(Contact $user) {
10        return true;
11    }
12    function run(Contact $user, $qreq, $selection) {
13        return "Unsupported.";
14    }
15
16    static private function do_call($name, Contact $user, Qrequest $qreq, $selection) {
17        if ($qreq->method() !== "GET" && $qreq->method() !== "HEAD" && !$qreq->post_ok())
18            return new JsonResult(403, ["ok" => false, "error" => "Missing credentials."]);
19        $uf = $user->conf->list_action($name, $user, $qreq->method());
20        if (!$uf) {
21            if ($user->conf->has_list_action($name, $user, null))
22                return new JsonResult(405, ["ok" => false, "error" => "Method not supported."]);
23            else if ($user->conf->has_list_action($name, null, $qreq->method()))
24                return new JsonResult(403, ["ok" => false, "error" => "Permission error."]);
25            else
26                return new JsonResult(404, ["ok" => false, "error" => "Function not found."]);
27        }
28        if (is_array($selection))
29            $selection = new SearchSelection($selection);
30        if (get($uf, "paper") && $selection->is_empty())
31            return new JsonResult(400, ["ok" => false, "error" => "No papers selected."]);
32        if ($uf->callback[0] === "+") {
33            $class = substr($uf->callback, 1);
34            $action = new $class($user->conf, $uf);
35        } else
36            $action = call_user_func($uf->callback, $user->conf, $uf);
37        if (!$action || !$action->allow($user))
38            return new JsonResult(403, ["ok" => false, "error" => "Permission error."]);
39        else
40            return $action->run($user, $qreq, $selection);
41    }
42
43    static function call($name, Contact $user, Qrequest $qreq, $selection) {
44        $res = self::do_call($name, $user, $qreq, $selection);
45        if (is_string($res))
46            $res = new JsonResult(400, ["ok" => false, "error" => $res]);
47        if ($res instanceof JsonResult) {
48            if ($res->status >= 300 && !$qreq->ajax)
49                Conf::msg_error($res->content["error"]);
50            else
51                json_exit($res);
52        } else if ($res instanceof CsvGenerator) {
53            csv_exit($res);
54        }
55    }
56
57
58    static function pcassignments_csv_data(Contact $user, $selection) {
59        require_once("assignmentset.php");
60        $pcm = $user->conf->pc_members();
61        $token_users = [];
62
63        $round_list = $user->conf->round_list();
64        $any_round = $any_token = false;
65
66        $texts = array();
67        foreach ($user->paper_set($selection, ["reviewSignatures" => true]) as $prow) {
68            if (!$user->allow_administer($prow)) {
69                $texts[] = array();
70                $texts[] = array("paper" => $prow->paperId,
71                                 "action" => "none",
72                                 "title" => "You cannot override your conflict with this paper");
73            } else if (($rrows = $prow->reviews_by_display())) {
74                $texts[] = array();
75                $texts[] = array("paper" => $prow->paperId,
76                                 "action" => "clearreview",
77                                 "email" => "#pc",
78                                 "round" => "any",
79                                 "title" => $prow->title);
80                foreach ($rrows as $rrow) {
81                    if ($rrow->reviewToken) {
82                        if (!array_key_exists($rrow->contactId, $token_users))
83                            $token_users[$rrow->contactId] = $user->conf->user_by_id($rrow->contactId);
84                        $u = $token_users[$rrow->contactId];
85                    } else if ($rrow->reviewType >= REVIEW_PC)
86                        $u = get($pcm, $rrow->contactId);
87                    else
88                        $u = null;
89                    if (!$u)
90                        continue;
91
92                    $round = $rrow->reviewRound;
93                    $d = ["paper" => $prow->paperId,
94                          "action" => ReviewInfo::unparse_assigner_action($rrow->reviewType),
95                          "email" => $u->email,
96                          "round" => $round ? $round_list[$round] : "none"];
97                    if ($rrow->reviewToken)
98                        $d["review_token"] = $any_token = encode_token((int) $rrow->reviewToken);
99                    $texts[] = $d;
100                    $any_round = $any_round || $round != 0;
101                }
102            }
103        }
104        $header = array("paper", "action", "email");
105        if ($any_round)
106            $header[] = "round";
107        if ($any_token)
108            $header[] = "review_token";
109        $header[] = "title";
110        return [$header, $texts];
111    }
112}
113