1<?php 2// listactions/la_get_sub.php -- HotCRP helper classes for list actions 3// Copyright (c) 2006-2018 Eddie Kohler; see LICENSE. 4 5class Get_ListAction extends ListAction { 6 static function render(PaperList $pl) { 7 $actions = array_values($pl->displayable_list_actions("get/")); 8 foreach ($pl->user->user_option_list() as $o) 9 if ($pl->user->can_view_some_paper_option($o) 10 && $o->is_document() 11 && $pl->has($o->field_key())) 12 $actions[] = GetDocument_ListAction::make_list_action($o); 13 usort($actions, "Conf::xt_position_compare"); 14 $last_group = null; 15 foreach ($actions as $fj) { 16 $as = strpos($fj->selector, "/"); 17 if ($as === false) { 18 if ($last_group) 19 $sel_opt[] = ["optgroup", false]; 20 $last_group = null; 21 $sel_opt[] = ["value" => substr($fj->name, 4), "label" => $fj->selector]; 22 } else { 23 $group = substr($fj->selector, 0, $as); 24 if ($group !== $last_group) { 25 $sel_opt[] = ["optgroup", $group]; 26 $last_group = $group; 27 } 28 $sel_opt[] = ["value" => substr($fj->name, 4), "label" => substr($fj->selector, $as + 1)]; 29 } 30 } 31 if (!empty($sel_opt)) { 32 return Ht::select("getfn", $sel_opt, $pl->qreq->getfn, 33 ["class" => "want-focus js-submit-action-info-get", "style" => "max-width:10em"]) 34 . " " . Ht::submit("fn", "Go", ["value" => "get", "data-default-submit-all" => 1, "class" => "btn uix js-submit-mark"]); 35 } else 36 return null; 37 } 38 function run(Contact $user, $qreq, $ssel) { 39 if (($opts = $user->conf->paper_opts->find_all($qreq->getfn)) 40 && count($opts) == 1 41 && ($o = current($opts)) 42 && $user->can_view_some_paper_option($o)) { 43 $ga = new GetDocument_ListAction($o->id); 44 return $ga->run($user, $qreq, $ssel); 45 } else 46 return self::ENOENT; 47 } 48} 49 50class GetCheckFormat_ListAction extends ListAction { 51 function run(Contact $user, $qreq, $ssel) { 52 $papers = []; 53 foreach ($user->paper_set($ssel) as $prow) 54 if ($user->can_view_pdf($prow)) 55 $papers[$prow->paperId] = $prow; 56 $csvg = $user->conf->make_csvg("formatcheck")->select(["paper", "title", "pages", "format"]); 57 $csvg->download_headers(); 58 echo $csvg->headerline; 59 $cf = new CheckFormat($user->conf); 60 foreach ($ssel->reorder($papers) as $prow) { 61 $pages = "?"; 62 if ($prow->mimetype == "application/pdf") { 63 $dtype = $prow->finalPaperStorageId ? DTYPE_FINAL : DTYPE_SUBMISSION; 64 if (($doc = $cf->fetch_document($prow, $dtype))) 65 $cf->check_document($prow, $doc); 66 if ($doc && !$cf->failed) { 67 $errf = $cf->problem_fields(); 68 $format = empty($errf) ? "ok" : join(",", $errf); 69 $pages = $cf->pages; 70 } else 71 $format = "error"; 72 } else 73 $format = "notpdf"; 74 echo $prow->paperId, ",", CsvGenerator::quote($prow->title), ",", $pages, ",", CsvGenerator::quote($format), "\n"; 75 ob_flush(); 76 flush(); 77 } 78 exit; 79 } 80} 81 82class GetAbstract_ListAction extends ListAction { 83 const WIDTH = 96; 84 static private function render_option(PaperOption $o, $otxt) { 85 $dtype = array_shift($otxt); 86 if ($dtype === PaperOption::PAGE_HTML_NAME) 87 $n = join(" ", $otxt); 88 else 89 $n = $o->title; 90 $text = prefix_word_wrap("", $n, 0, self::WIDTH); 91 $text .= str_repeat("-", min(self::WIDTH, strlen($text) - 1)) . "\n"; 92 if ($dtype === PaperOption::PAGE_HTML_DATA && !empty($otxt)) { 93 if (count($otxt) === 1) 94 $text .= rtrim($otxt[0]); 95 else 96 $text .= join("", array_map(function ($t) { return "* " . rtrim($t) . "\n"; }, $otxt)); 97 $text .= "\n"; 98 } 99 return $text . "\n"; 100 } 101 static function render_displayed_options(PaperInfo $prow, Contact $user, $display) { 102 $text = ""; 103 foreach ($prow->options() as $ov) { 104 if ($ov->option->display() === $display 105 && $user->can_view_paper_option($prow, $ov->option) 106 && ($otxt = $ov->option->unparse_page_text($prow, $ov))) 107 $text .= self::render_option($ov->option, $otxt); 108 } 109 return $text; 110 } 111 static function render(PaperInfo $prow, Contact $user) { 112 $n = prefix_word_wrap("", "Submission #{$prow->paperId}: {$prow->title}", 0, self::WIDTH); 113 $text = $n . str_repeat("=", min(self::WIDTH, strlen($n) - 1)) . "\n\n"; 114 115 $text .= self::render_displayed_options($prow, $user, PaperOption::DISP_SUBMISSION); 116 117 if ($user->can_view_authors($prow) && ($alist = $prow->author_list())) { 118 if (count($alist) == 1) 119 $text .= "Author\n------\n" 120 . prefix_word_wrap("", $alist[0]->name_email_aff_text(), 0, self::WIDTH); 121 else { 122 $text .= "Authors\n-------\n"; 123 foreach ($alist as $i => $au) { 124 $marker = ($i + 1) . ". "; 125 $text .= prefix_word_wrap($marker, $au->name_email_aff_text(), strlen($marker), self::WIDTH); 126 } 127 } 128 $text .= "\n"; 129 } 130 131 if ($prow->abstract) 132 $text .= "Abstract\n--------\n" . rtrim($prow->abstract) . "\n\n"; 133 134 $text .= self::render_displayed_options($prow, $user, PaperOption::DISP_PROMINENT); 135 136 if (($tlist = $prow->named_topic_map())) { 137 $text .= "Topics\n------\n"; 138 foreach ($tlist as $t) 139 $text .= prefix_word_wrap("* ", $t, 2, self::WIDTH); 140 $text .= "\n"; 141 } 142 143 $text .= self::render_displayed_options($prow, $user, PaperOption::DISP_TOPICS); 144 145 return $text . "\n"; 146 } 147 function run(Contact $user, $qreq, $ssel) { 148 $texts = array(); 149 foreach ($user->paper_set($ssel, ["topics" => 1]) as $prow) { 150 if (($whyNot = $user->perm_view_paper($prow))) 151 Conf::msg_error(whyNotText($whyNot)); 152 else { 153 defappend($texts[$prow->paperId], $this->render($prow, $user)); 154 $rfSuffix = (count($texts) == 1 ? $prow->paperId : "s"); 155 } 156 } 157 if (count($texts)) 158 downloadText(join("", $ssel->reorder($texts)), "abstract$rfSuffix"); 159 } 160} 161 162class GetAuthors_ListAction extends ListAction { 163 static function contact_map(Conf $conf, $ssel) { 164 $result = $conf->qe_raw("select ContactInfo.contactId, firstName, lastName, affiliation, email from ContactInfo join PaperConflict on (PaperConflict.contactId=ContactInfo.contactId) where conflictType>=" . CONFLICT_AUTHOR . " and paperId" . $ssel->sql_predicate() . " group by ContactInfo.contactId"); 165 $contact_map = []; 166 while (($row = edb_orow($result))) { 167 $row->contactId = (int) $row->contactId; 168 $contact_map[$row->contactId] = $row; 169 } 170 return $contact_map; 171 } 172 function allow(Contact $user) { 173 return $user->can_view_some_authors(); 174 } 175 function run(Contact $user, $qreq, $ssel) { 176 $contact_map = self::contact_map($user->conf, $ssel); 177 $texts = array(); 178 $want_contacttype = false; 179 foreach ($user->paper_set($ssel, ["allConflictType" => 1]) as $prow) { 180 if (!$user->allow_view_authors($prow)) 181 continue; 182 $admin = $user->allow_administer($prow); 183 $contact_emails = []; 184 if ($admin) { 185 $want_contacttype = true; 186 foreach ($prow->contacts() as $cid => $c) { 187 $c = $contact_map[$cid]; 188 $contact_emails[strtolower($c->email)] = $c; 189 } 190 } 191 foreach ($prow->author_list() as $au) { 192 $line = [$prow->paperId, $prow->title, $au->firstName, $au->lastName, $au->email, $au->affiliation]; 193 $lemail = strtolower($au->email); 194 if ($admin && $lemail && isset($contact_emails[$lemail])) { 195 $line[] = "yes"; 196 unset($contact_emails[$lemail]); 197 } else if ($admin) 198 $line[] = "no"; 199 arrayappend($texts[$prow->paperId], $line); 200 } 201 foreach ($contact_emails as $c) 202 arrayappend($texts[$prow->paperId], [$prow->paperId, $prow->title, $c->firstName, $c->lastName, $c->email, $c->affiliation, "contact_only"]); 203 } 204 $header = ["paper", "title", "first", "last", "email", "affiliation"]; 205 if ($want_contacttype) 206 $header[] = "iscontact"; 207 return $user->conf->make_csvg("authors")->select($header) 208 ->add($ssel->reorder($texts)); 209 } 210} 211 212/* NB this search action is actually unavailable via the UI */ 213class GetContacts_ListAction extends ListAction { 214 function allow(Contact $user) { 215 return $user->is_manager(); 216 } 217 function run(Contact $user, $qreq, $ssel) { 218 $contact_map = GetAuthors_ListAction::contact_map($user->conf, $ssel); 219 foreach ($user->paper_set($ssel, ["allConflictType" => 1]) as $prow) 220 if ($user->allow_administer($prow)) 221 foreach ($prow->contacts() as $cid => $c) { 222 $a = $contact_map[$cid]; 223 $aa = $prow->author_by_email($a->email) ? : $a; 224 arrayappend($texts[$prow->paperId], [$prow->paperId, $prow->title, $aa->firstName, $aa->lastName, $aa->email, $aa->affiliation]); 225 } 226 return $user->conf->make_csvg("contacts") 227 ->select(["paper", "title", "first", "last", "email", "affiliation"]) 228 ->add($ssel->reorder($texts)); 229 } 230} 231 232class GetPcconflicts_ListAction extends ListAction { 233 function allow(Contact $user) { 234 return $user->is_manager(); 235 } 236 function run(Contact $user, $qreq, $ssel) { 237 $allConflictTypes = Conflict::$type_descriptions; 238 $allConflictTypes[CONFLICT_CHAIRMARK] = "Chair-confirmed"; 239 $allConflictTypes[CONFLICT_AUTHOR] = "Author"; 240 $allConflictTypes[CONFLICT_CONTACTAUTHOR] = "Contact"; 241 $pcm = $user->conf->pc_members(); 242 $texts = array(); 243 $old_overrides = $user->add_overrides(Contact::OVERRIDE_CONFLICT); 244 foreach ($user->paper_set($ssel, ["allConflictType" => 1]) as $prow) { 245 if ($user->can_view_conflicts($prow)) { 246 $m = []; 247 foreach ($prow->conflicts() as $cid => $c) 248 if (isset($pcm[$cid])) { 249 $pc = $pcm[$cid]; 250 $m[$pc->sort_position] = [$prow->paperId, $prow->title, $pc->firstName, $pc->lastName, $pc->email, get($allConflictTypes, $c->conflictType, "Conflict")]; 251 } 252 if ($m) { 253 ksort($m); 254 $texts[$prow->paperId] = $m; 255 } 256 } 257 } 258 $user->set_overrides($old_overrides); 259 return $user->conf->make_csvg("pcconflicts") 260 ->select(["paper", "title", "first", "last", "email", "conflicttype"]) 261 ->add($ssel->reorder($texts)); 262 } 263} 264 265class GetTopics_ListAction extends ListAction { 266 function run(Contact $user, $qreq, $ssel) { 267 $texts = array(); 268 foreach ($user->paper_set($ssel, ["topics" => 1]) as $row) 269 if ($user->can_view_paper($row)) { 270 $out = array(); 271 foreach ($row->named_topic_map() as $t) 272 $out[] = [$row->paperId, $row->title, $t]; 273 if (empty($out)) 274 $out[] = [$row->paperId, $row->title, "<none>"]; 275 arrayappend($texts[$row->paperId], $out); 276 } 277 return $user->conf->make_csvg("topics") 278 ->select(["paper", "title", "topic"]) 279 ->add($ssel->reorder($texts)); 280 } 281} 282 283class GetCSV_ListAction extends ListAction { 284 function run(Contact $user, $qreq, $ssel) { 285 $search = new PaperSearch($user, $qreq); 286 $search->restrict_match([$ssel, "is_selected"]); 287 $pl = new PaperList($search, ["sort" => true, "report" => "pl", "display" => $qreq->display], $qreq); 288 $pl->set_view("sel", false); 289 list($header, $data) = $pl->text_csv($qreq->t); 290 return $user->conf->make_csvg("data", CsvGenerator::FLAG_ITEM_COMMENTS) 291 ->select($header)->add($data); 292 } 293} 294