7 * @link http://www.open-emr.org
8 * @author Rod Roark <rod@sunsetsystems.com>
9 * @author Brady Miller <brady.g.miller@gmail.com>
10 * @author Kevin Yeh <kevin.y@integralemr.com>
11 * @author Scott Wakefield <scott.wakefield@gmail.com>
12 * @author ViCarePlus <visolve_emr@visolve.com>
13 * @author Julia Longtin <julialongtin@diasp.org>
16 * @author Tyler Wrenn <tyler@tylerwrenn.com>
17 * @author Ken Chapple <ken@mi-squared.com>
18 * @author Daniel Pflieger <daniel@mi-squared.com> <daniel@growlingflea.com>
19 * @author Robert Down <robertdown@live.com>
20 * @copyright Copyright (c) 2019 Brady Miller <brady.g.miller@gmail.com>
21 * @copyright Copyright (c) 2020 Tyler Wrenn <tyler@tylerwrenn.com>
22 * @copyright Copyright (c) 2021 Ken Chapple <ken@mi-squared.com>
23 * @copyright Copyright (c) 2021 Daniel Pflieger <daniel@mi-squared.com> <daniel@growlingflea.com>
24 * @copyright Copyright (c) 2021-2023 Robert Down <robertdown@live.com>
25 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
28 // prevent UI redressing
29 Header("X-Frame-Options: DENY");
30 Header("Content-Security-Policy: frame-ancestors 'none'");
32 use OpenEMR\Common\Twig\TwigContainer
;
33 use OpenEMR\Events\Core\TemplatePageEvent
;
34 use OpenEMR\Services\FacilityService
;
35 use OpenEMR\Services\LogoService
;
36 use Symfony\Component\EventDispatcher\EventDispatcher
;
37 use Twig\Error\LoaderError
;
38 use Twig\Error\RuntimeError
;
39 use Twig\Error\SyntaxError
;
42 // Set $sessionAllowWrite to true to prevent session concurrency issues during authorization related code
43 $sessionAllowWrite = true;
44 require_once("../globals.php");
46 $twig = new TwigContainer(null, $GLOBALS["kernel"]);
47 $t = $twig->getTwig();
49 $logoService = new LogoService();
50 $primaryLogo = $logoService->getLogo("core/login/primary");
51 $secondaryLogo = $logoService->getLogo("core/login/secondary");
52 $smallLogoOne = $logoService->getLogo("core/login/small_logo_1");
53 $smallLogoTwo = $logoService->getLogo("core/login/small_logo_2");
55 $layout = $GLOBALS['login_page_layout'];
57 // mdsupport - Add 'App' functionality for user interfaces without standard menu and frames
58 // If this script is called with app parameter, validate it without showing other apps.
60 // Build a list of valid entries
61 // Original merge v5.0.1
63 $sql = "SELECT option_id, title,is_default FROM list_options WHERE list_id=? and activity=1 ORDER BY seq, option_id";
64 $rs = sqlStatement($sql, ['apps']);
65 if (sqlNumRows($rs)) {
66 while ($app = sqlFetchArray($rs)) {
67 $app_req = explode('?', trim($app['title']));
68 if (! file_exists('../' . $app_req[0])) {
72 $emr_app [trim($app ['option_id'])] = trim($app ['title']);
73 if ($app ['is_default']) {
74 $emr_app_def = $app ['option_id'];
80 if (count($emr_app)) {
81 // Standard app must exist
82 $std_app = 'main/main_screen.php';
83 if (!in_array($std_app, $emr_app)) {
84 $emr_app['*OpenEMR'] = $std_app;
87 if (isset($_REQUEST['app']) && $emr_app[$_REQUEST['app']]) {
88 $div_app = sprintf('<input type="hidden" name="appChoice" value="%s">', attr($_REQUEST['app']));
91 foreach ($emr_app as $opt_disp => $opt_value) {
93 '<option value="%s" %s>%s</option>\n',
95 ($opt_disp == ($emr_app_def ??
'') ?
'selected="selected"' : ''),
96 text(xl_list_label($opt_disp))
102 <div id="divApp" class="form-group row">
103 <label for="appChoice" class="col-form-label col-sm-4">%s:</label>
105 <select class="form-control" id="selApp" name="appChoice" size="1">%s</select>
115 function getDefaultLanguage(): array
117 $sql = "SELECT * FROM lang_languages where lang_description = ?";
118 $res = sqlStatement($sql, [$GLOBALS['language_default']]);
121 while ($row = sqlFetchArray($res)) {
128 if (count($langs) == 1) {
129 $id = $langs[0]["lang_id"];
130 $desc = $langs[0]["lang_description"];
133 return ["id" => $id, "language" => $desc];
136 function getLanguagesList(): array
138 $mainLangID = empty($_SESSION['language_choice']) ?
'1' : $_SESSION['language_choice'];
139 $sql = "SELECT ll.lang_id, IF(LENGTH(ld.definition), ld.definition, ll.lang_description) AS trans_lang_description, ll.lang_description
140 FROM lang_languages AS ll
141 LEFT JOIN lang_constants AS lc ON lc.constant_name = ll.lang_description
142 LEFT JOIN lang_definitions AS ld ON ld.cons_id = lc.cons_id AND ld.lang_id = ?
143 ORDER BY IF(LENGTH(ld.definition),ld.definition,ll.lang_description), ll.lang_id";
144 $res = sqlStatement($sql, [$mainLangID]);
147 while ($row = sqlFetchArray($res)) {
148 if (!$GLOBALS['allow_debug_language'] && $row['lang_description'] == 'dummy') {
149 continue; // skip the dummy language
152 if ($GLOBALS['language_menu_showall']) {
155 if (in_array($row['lang_description'], $GLOBALS['language_menu_show'])) {
165 $facilitySelected = false;
166 if ($GLOBALS['login_into_facility']) {
167 $facilityService = new FacilityService();
168 $facilities = $facilityService->getAllFacility();
169 $facilitySelected = ($GLOBALS['set_facility_cookie'] && isset($_COOKIE['pc_facility'])) ?
$_COOKIE['pc_facility'] : null;
172 $defaultLanguage = getDefaultLanguage();
173 $languageList = getLanguagesList();
174 $_SESSION['language_choice'] = $defaultLanguage['id'];
176 $relogin = (isset($_SESSION['relogin']) && ($_SESSION['relogin'] == 1)) ?
true : false;
178 unset($_SESSION["relogin"]);
181 $t1 = $GLOBALS['tiny_logo_1'];
182 $t2 = $GLOBALS['tiny_logo_2'];
183 $displaySmallLogo = false;
185 $displaySmallLogo = 1;
187 $displaySmallLogo = 2;
189 $displaySmallLogo = 3;
192 $regTranslations = json_encode(array(
193 'title' => xla('OpenEMR Product Registration'),
194 'pleaseProvideValidEmail' => xla('Please provide a valid email address'),
195 'success' => xla('Success'),
196 'registeredSuccess' => xla('Your installation of OpenEMR has been registered'),
197 'submit' => xla('Submit'),
198 'noThanks' => xla('No Thanks'),
199 'registeredEmail' => xla('Registered email'),
200 'registeredId' => xla('Registered id'),
201 'genericError' => xla('Error. Try again later'),
206 if (session_name()) {
207 $sid = urlencode(session_id());
208 $sname = urlencode(session_name());
209 $scparams = session_get_cookie_params();
210 $domain = $scparams['domain'];
211 $path = $scparams['path'];
212 $oldDate = gmdate('Y', strtotime("-1 years"));
213 $expires = gmdate(DATE_RFC1123
, $oldDate);
214 $sameSite = empty($scparams['samesite']) ?
'' : $scparams['samesite'];
215 $cookie = "{$sname}={$sid}; path={$path}; domain={$domain}; expires={$expires}";
218 $cookie .= "; SameSite={$sameSite}";
221 $cookie = json_encode($cookie);
225 'title' => $openemr_name,
226 'displayLanguage' => $GLOBALS["language_menu_login"] && (count($languageList) != 1),
227 'defaultLangID' => $defaultLanguage['id'],
228 'defaultLangName' => $defaultLanguage['language'],
229 'languageList' => $languageList,
230 'relogin' => $relogin,
231 'loginFail' => isset($_SESSION["loginfailure"]) && $_SESSION["loginfailure"] == 1,
232 'displayFacilities' => (bool)$GLOBALS["login_into_facility"],
233 'facilityList' => $facilities,
234 'facilitySelected' => $facilitySelected,
235 'displayGoogleSignin' => !empty($GLOBALS['google_signin_enabled']) && !empty($GLOBALS['google_signin_client_id']),
236 'googleSigninClientID' => $GLOBALS['google_signin_client_id'],
237 'displaySmallLogo' => $displaySmallLogo,
238 'smallLogoOne' => $smallLogoOne,
239 'smallLogoTwo' => $smallLogoTwo,
240 'showTitleOnLogin' => $GLOBALS['show_label_login'],
241 'displayTagline' => $GLOBALS['show_tagline_on_login'],
242 'tagline' => $GLOBALS['login_tagline_text'],
243 'displayAck' => $GLOBALS['display_acknowledgements_on_login'],
244 'hasSession' => (bool)session_name(),
245 'cookieText' => $cookie,
246 'regTranslations' => $regTranslations,
247 'regConstants' => json_encode(['webroot' => $GLOBALS['webroot']]),
248 'siteID' => $_SESSION['site_id'],
249 'showLabels' => $GLOBALS['show_labels_on_login_form'],
250 'displayPrimaryLogo' => $GLOBALS['show_primary_logo'],
251 'primaryLogo' => $primaryLogo,
252 'primaryLogoWidth' => $GLOBALS['primary_logo_width'],
253 'logoPosition' => $GLOBALS['logo_position'],
254 'secondaryLogoWidth' => $GLOBALS['secondary_logo_width'],
255 'displaySecondaryLogo' => $GLOBALS['extra_logo_login'],
256 'secondaryLogo' => $secondaryLogo,
257 'secondaryLogoPosition' => $GLOBALS['secondary_logo_position'],
261 * @var EventDispatcher;
263 $ed = $GLOBALS['kernel']->getEventDispatcher();
265 $templatePageEvent = new TemplatePageEvent('login/login.php', [], $layout, $viewArgs);
266 $event = $ed->dispatch($templatePageEvent, TemplatePageEvent
::RENDER_EVENT
);
269 echo $t->render($event->getTwigTemplate(), $event->getTwigVariables());
270 } catch (LoaderError | RuntimeError | SyntaxError
$e) {
271 echo "<p style='font-size:24px; color: red;'>" . text($e->getMessage()) . '</p>';