1<?php 2// multiconference.php -- HotCRP multiconference installations 3// Copyright (c) 2006-2018 Eddie Kohler; see LICENSE. 4 5class Multiconference { 6 static private $original_opt = null; 7 8 static function init() { 9 global $Opt, $argv; 10 assert(self::$original_opt === null); 11 self::$original_opt = $Opt; 12 13 $confid = get($Opt, "confid"); 14 if (!$confid && PHP_SAPI == "cli") { 15 for ($i = 1; $i != count($argv); ++$i) { 16 if ($argv[$i] === "-n" || $argv[$i] === "--name") { 17 if (isset($argv[$i + 1])) 18 $confid = $argv[$i + 1]; 19 break; 20 } else if (substr($argv[$i], 0, 2) === "-n") { 21 $confid = substr($argv[$i], 2); 22 break; 23 } else if (substr($argv[$i], 0, 7) === "--name=") { 24 $confid = substr($argv[$i], 7); 25 break; 26 } else if ($argv[$i] === "--") { 27 break; 28 } 29 } 30 } else if (!$confid) { 31 $base = Navigation::site_absolute(true); 32 if (($multis = get($Opt, "multiconferenceAnalyzer"))) { 33 foreach (is_array($multis) ? $multis : array($multis) as $multi) { 34 list($match, $replace) = explode(" ", $multi); 35 if (preg_match("`\\A$match`", $base, $m)) { 36 $confid = $replace; 37 for ($i = 1; $i < count($m); ++$i) 38 $confid = str_replace("\$$i", $m[$i], $confid); 39 break; 40 } 41 } 42 } else if (preg_match(',/([^/]+)/\z,', $base, $m)) 43 $confid = $m[1]; 44 } 45 46 if (!$confid) 47 $confid = "__nonexistent__"; 48 else if (!preg_match(',\A[-a-zA-Z0-9_][-a-zA-Z0-9_.]*\z,', $confid)) 49 $confid = "__invalid__"; 50 51 self::assign_confid($Opt, $confid); 52 } 53 54 static function assign_confid(&$opt, $confid) { 55 foreach (array("dbName", "dbUser", "dbPassword", "dsn") as $k) 56 if (isset($opt[$k]) && is_string($opt[$k])) 57 $opt[$k] = preg_replace(',\*|\$\{conf(?:id|name)\}|\$conf(?:id|name)\b,', $confid, $opt[$k]); 58 if (!get($opt, "dbName") && !get($opt, "dsn")) 59 $opt["dbName"] = $confid; 60 $opt["confid"] = $confid; 61 } 62 63 static function load_confid($confid) { 64 global $Opt; 65 $save_opt = $Opt; 66 $Opt = self::$original_opt; 67 self::assign_confid($Opt, $confid); 68 if (get($Opt, "include")) 69 read_included_options($Opt["include"]); 70 $newconf = get($Opt, "missing") ? null : new Conf($Opt, true); 71 $Opt = $save_opt; 72 return $newconf; 73 } 74 75 static function fail_message($errors) { 76 global $Conf, $Me, $Opt; 77 78 if (is_string($errors)) 79 $errors = array($errors); 80 if (get($Opt, "maintenance")) 81 $errors = array("The site is down for maintenance. " . (is_string($Opt["maintenance"]) ? $Opt["maintenance"] : "Please check back later.")); 82 83 if (PHP_SAPI == "cli") { 84 fwrite(STDERR, join("\n", $errors) . "\n"); 85 exit(1); 86 } else if (get($_GET, "ajax")) { 87 $ctype = get($_GET, "text") ? "text/plain" : "application/json"; 88 header("Content-Type: $ctype; charset=utf-8"); 89 if (get($Opt, "maintenance")) 90 echo "{\"error\":\"maintenance\"}\n"; 91 else 92 echo "{\"error\":\"unconfigured installation\"}\n"; 93 } else { 94 if (!$Conf) 95 $Conf = Conf::$g = new Conf($Opt, false); 96 $Me = null; 97 header("HTTP/1.1 404 Not Found"); 98 $Conf->header("HotCRP Error", "", ["action_bar" => false]); 99 foreach ($errors as $i => &$e) 100 $e = ($i ? "<div class=\"hint\">" : "<p>") . htmlspecialchars($e) . ($i ? "</div>" : "</p>"); 101 echo join("", $errors); 102 $Conf->footer(); 103 } 104 exit; 105 } 106 107 static function fail_bad_options() { 108 global $Opt; 109 $errors = array(); 110 if (get($Opt, "multiconference") && $Opt["confid"] === "__nonexistent__") 111 $errors[] = "You haven’t specified a conference and this is a multiconference installation."; 112 else if (get($Opt, "multiconference")) 113 $errors[] = "The “" . $Opt["confid"] . "” conference does not exist. Check your URL to make sure you spelled it correctly."; 114 else if (!get($Opt, "loaded")) 115 $errors[] = "HotCRP has been installed, but not yet configured. You must run `lib/createdb.sh` to create a database for your conference. See `README.md` for further guidance."; 116 else 117 $errors[] = "HotCRP was unable to load. A system administrator must fix this problem."; 118 if (!get($Opt, "loaded") && defined("HOTCRP_OPTIONS")) 119 $errors[] = "Error: Unable to load options file `" . HOTCRP_OPTIONS . "`"; 120 else if (!get($Opt, "loaded")) 121 $errors[] = "Error: Unable to load options file"; 122 if (get($Opt, "missing")) 123 $errors[] = "Error: Unable to load options from " . commajoin($Opt["missing"]); 124 self::fail_message($errors); 125 } 126 127 static function fail_bad_database() { 128 global $Conf, $Opt; 129 $errors = array(); 130 if (get($Opt, "multiconference") && $Opt["confid"] === "__nonexistent__") 131 $errors[] = "You haven’t specified a conference and this is a multiconference installation."; 132 else if (get($Opt, "multiconference")) 133 $errors[] = "The “" . $Opt["confid"] . "” conference does not exist. Check your URL to make sure you spelled it correctly."; 134 else { 135 $errors[] = "HotCRP was unable to load. A system administrator must fix this problem."; 136 $errors[] = "Error: Unable to connect to database " . Dbl::sanitize_dsn($Conf->dsn); 137 if (defined("HOTCRP_TESTHARNESS")) 138 $errors[] = "You may need to run `lib/createdb.sh -c test/options.php` to create the database."; 139 } 140 self::fail_message($errors); 141 } 142} 143