Mercurial > hg > rc2
comparison program/include/rcmail_output_html.php @ 18:b631c1c7a3ce
More cleaning up more php8 Warnings/deprecations,
including _many_ ediff-based fixes on rcmail_output_html.php
| author | Charlie Root |
|---|---|
| date | Tue, 07 Oct 2025 11:20:40 -0400 |
| parents | 3a5f959af5ae |
| children | 303b85d5b561 |
comparison
equal
deleted
inserted
replaced
| 17:dd5ed6ef69c9 | 18:b631c1c7a3ce |
|---|---|
| 68 $this->devel_mode = $this->config->get('devel_mode'); | 68 $this->devel_mode = $this->config->get('devel_mode'); |
| 69 | 69 |
| 70 $this->set_env('task', $task); | 70 $this->set_env('task', $task); |
| 71 $this->set_env('x_frame_options', $this->config->get('x_frame_options', 'sameorigin')); | 71 $this->set_env('x_frame_options', $this->config->get('x_frame_options', 'sameorigin')); |
| 72 $this->set_env('standard_windows', (bool) $this->config->get('standard_windows')); | 72 $this->set_env('standard_windows', (bool) $this->config->get('standard_windows')); |
| 73 $this->set_env('locale', $_SESSION['language']); | 73 $this->set_env('locale', !empty($_SESSION['language']) ? $_SESSION['language'] : 'en_US'); |
| 74 $this->set_env('devel_mode', $this->devel_mode); | 74 $this->set_env('devel_mode', $this->devel_mode); |
| 75 | 75 |
| 76 // add cookie info | 76 // add cookie info |
| 77 $this->set_env('cookie_domain', ini_get('session.cookie_domain')); | 77 $this->set_env('cookie_domain', ini_get('session.cookie_domain')); |
| 78 $this->set_env('cookie_path', ini_get('session.cookie_path')); | 78 $this->set_env('cookie_path', ini_get('session.cookie_path')); |
| 83 $this->set_skin($skin); | 83 $this->set_skin($skin); |
| 84 $this->set_env('skin', $skin); | 84 $this->set_env('skin', $skin); |
| 85 | 85 |
| 86 $this->set_assets_path($this->config->get('assets_path'), $this->config->get('assets_dir')); | 86 $this->set_assets_path($this->config->get('assets_path'), $this->config->get('assets_dir')); |
| 87 | 87 |
| 88 if (!empty($_REQUEST['_extwin'])) | 88 if (!empty($_REQUEST['_extwin'])) { |
| 89 $this->set_env('extwin', 1); | 89 $this->set_env('extwin', 1); |
| 90 if ($this->framed || $framed) | 90 } |
| 91 | |
| 92 if ($this->framed || $framed) { | |
| 91 $this->set_env('framed', 1); | 93 $this->set_env('framed', 1); |
| 94 } | |
| 92 | 95 |
| 93 $lic = <<<EOF | 96 $lic = <<<EOF |
| 94 /* | 97 /* |
| 95 @licstart The following is the entire license notice for the | 98 @licstart The following is the entire license notice for the |
| 96 JavaScript code in this page. | 99 JavaScript code in this page. |
| 208 protected function get_pagetitle() | 211 protected function get_pagetitle() |
| 209 { | 212 { |
| 210 if (!empty($this->pagetitle)) { | 213 if (!empty($this->pagetitle)) { |
| 211 $title = $this->pagetitle; | 214 $title = $this->pagetitle; |
| 212 } | 215 } |
| 213 else if ($this->env['task'] == 'login') { | 216 else if (isset($this->env['task'])) { |
| 214 $title = $this->app->gettext(array( | 217 if ($this->env['task'] == 'login') { |
| 215 'name' => 'welcome', | 218 $title = $this->app->gettext([ |
| 216 'vars' => array('product' => $this->config->get('product_name') | 219 'name' => 'welcome', |
| 217 ))); | 220 'vars' => ['product' => $this->config->get('product_name')] |
| 221 ]); | |
| 222 } | |
| 223 else { | |
| 224 $title = ucfirst($this->env['task']); | |
| 225 } | |
| 218 } | 226 } |
| 219 else { | 227 else { |
| 220 $title = ucfirst($this->env['task']); | 228 $title = ''; |
| 221 } | 229 } |
| 222 | 230 |
| 223 return $title; | 231 return $title; |
| 224 } | 232 } |
| 225 | 233 |
| 283 | 291 |
| 284 $meta['path'] = $skin_path; | 292 $meta['path'] = $skin_path; |
| 285 $path_elements = explode('/', $skin_path); | 293 $path_elements = explode('/', $skin_path); |
| 286 $skin_id = end($path_elements); | 294 $skin_id = end($path_elements); |
| 287 | 295 |
| 288 if (!$meta['name']) { | 296 if (empty($meta['name'])) { |
| 289 $meta['name'] = $skin_id; | 297 $meta['name'] = $skin_id; |
| 290 } | 298 } |
| 291 | 299 |
| 292 $this->skins[$skin_id] = $meta; | 300 $this->skins[$skin_id] = $meta; |
| 293 | 301 |
| 294 if ($meta['extends']) { | 302 if (!empty($meta['extends'])) { |
| 295 $path = RCUBE_INSTALL_PATH . 'skins/'; | 303 $path = RCUBE_INSTALL_PATH . 'skins/'; |
| 296 if (is_dir($path . $meta['extends']) && is_readable($path . $meta['extends'])) { | 304 if (is_dir($path . $meta['extends']) && is_readable($path . $meta['extends'])) { |
| 297 $this->load_skin('skins/' . $meta['extends']); | 305 $this->load_skin('skins/' . $meta['extends']); |
| 298 } | 306 } |
| 299 } | 307 } |
| 308 */ | 316 */ |
| 309 public function template_exists($name) | 317 public function template_exists($name) |
| 310 { | 318 { |
| 311 foreach ($this->skin_paths as $skin_path) { | 319 foreach ($this->skin_paths as $skin_path) { |
| 312 $filename = RCUBE_INSTALL_PATH . $skin_path . '/templates/' . $name . '.html'; | 320 $filename = RCUBE_INSTALL_PATH . $skin_path . '/templates/' . $name . '.html'; |
| 313 if ((is_file($filename) && is_readable($filename)) | 321 if ( |
| 314 || ($this->deprecated_templates[$name] && $this->template_exists($this->deprecated_templates[$name])) | 322 (is_file($filename) && is_readable($filename)) |
| 323 || (!empty($this->deprecated_templates[$name]) && $this->template_exists($this->deprecated_templates[$name])) | |
| 315 ) { | 324 ) { |
| 316 return true; | 325 return true; |
| 317 } | 326 } |
| 318 } | 327 } |
| 319 | 328 |
| 414 if ($this->app->text_exists($message)) { | 423 if ($this->app->text_exists($message)) { |
| 415 if (!empty($vars)) | 424 if (!empty($vars)) |
| 416 $vars = array_map(array('rcube','Q'), $vars); | 425 $vars = array_map(array('rcube','Q'), $vars); |
| 417 $msgtext = $this->app->gettext(array('name' => $message, 'vars' => $vars)); | 426 $msgtext = $this->app->gettext(array('name' => $message, 'vars' => $vars)); |
| 418 } | 427 } |
| 419 else | 428 else { |
| 420 $msgtext = $message; | 429 $msgtext = $message; |
| 430 } | |
| 421 | 431 |
| 422 $this->message = $message; | 432 $this->message = $message; |
| 423 $this->command('display_message', $msgtext, $type, $timeout * 1000); | 433 $this->command('display_message', $msgtext, $type, $timeout * 1000); |
| 424 } | 434 } |
| 425 } | 435 } |
| 460 * @param int $delay Delay in seconds | 470 * @param int $delay Delay in seconds |
| 461 * @param bool $secure Redirect to secure location (see rcmail::url()) | 471 * @param bool $secure Redirect to secure location (see rcmail::url()) |
| 462 */ | 472 */ |
| 463 public function redirect($p = array(), $delay = 1, $secure = false) | 473 public function redirect($p = array(), $delay = 1, $secure = false) |
| 464 { | 474 { |
| 465 if ($this->env['extwin']) | 475 if (!empty($this->env['extwin'])) |
| 466 $p['extwin'] = 1; | 476 $p['extwin'] = 1; |
| 467 $location = $this->app->url($p, false, false, $secure); | 477 $location = $this->app->url($p, false, false, $secure); |
| 468 header('Location: ' . $location); | 478 header('Location: ' . $location); |
| 469 exit; | 479 exit; |
| 470 } | 480 } |
| 523 $this->header = ''; | 533 $this->header = ''; |
| 524 $this->footer = ''; | 534 $this->footer = ''; |
| 525 } | 535 } |
| 526 | 536 |
| 527 // write all javascript commands | 537 // write all javascript commands |
| 528 $this->add_script($commands, 'head_top'); | 538 if (!empty($commands)) { |
| 539 $this->add_script($commands, 'head_top'); | |
| 540 } | |
| 529 | 541 |
| 530 // allow (legal) iframe content to be loaded | 542 // allow (legal) iframe content to be loaded |
| 531 $iframe = $this->framed || $this->env['framed']; | 543 $iframe = $this->framed || !empty($this->env['framed']); |
| 532 if (!headers_sent() && $iframe && ($xopt = $this->app->config->get('x_frame_options', 'sameorigin'))) { | 544 if (!headers_sent() && $iframe && ($xopt = $this->app->config->get('x_frame_options', 'sameorigin'))) { |
| 533 if (strtolower($xopt) != 'sameorigin') { | 545 if (strtolower($xopt) != 'sameorigin') { |
| 534 header('X-Frame-Options: sameorigin', true); | 546 header('X-Frame-Options: sameorigin', true); |
| 535 } | 547 } |
| 536 } | 548 } |
| 581 $path = false; | 593 $path = false; |
| 582 foreach ($this->skin_paths as $skin_path) { | 594 foreach ($this->skin_paths as $skin_path) { |
| 583 $path = RCUBE_INSTALL_PATH . "$skin_path/templates/$name.html"; | 595 $path = RCUBE_INSTALL_PATH . "$skin_path/templates/$name.html"; |
| 584 | 596 |
| 585 // fallback to deprecated template names | 597 // fallback to deprecated template names |
| 586 if (!is_readable($path) && ($dname = $this->deprecated_templates[$realname])) { | 598 if (!is_readable($path) && !empty($this->deprecated_templates[$realname])) { |
| 587 $path = RCUBE_INSTALL_PATH . "$skin_path/templates/$dname.html"; | 599 $dname = $this->deprecated_templates[$realname]; |
| 600 $path = RCUBE_INSTALL_PATH . "$skin_path/templates/$dname.html"; | |
| 588 | 601 |
| 589 if (is_readable($path)) { | 602 if (is_readable($path)) { |
| 590 rcube::raise_error(array( | 603 rcube::raise_error(array( |
| 591 'code' => 502, 'file' => __FILE__, 'line' => __LINE__, | 604 'code' => 502, 'file' => __FILE__, 'line' => __LINE__, |
| 592 'message' => "Using deprecated template '$dname' in $skin_path/templates. Please rename to '$realname'" | 605 'message' => "Using deprecated template '$dname' in $skin_path/templates. Please rename to '$realname'" |
| 629 array($this->app->plugins->url, '\\1'.$this->app->plugins->url.$skin_dir.'/'), | 642 array($this->app->plugins->url, '\\1'.$this->app->plugins->url.$skin_dir.'/'), |
| 630 $templ | 643 $templ |
| 631 ); | 644 ); |
| 632 } | 645 } |
| 633 | 646 |
| 634 // parse for specialtags | 647 // parse for special tags |
| 635 $output = $this->parse_conditions($templ); | 648 $output = $this->parse_conditions($templ); |
| 636 $output = $this->parse_xml($output); | 649 $output = $this->parse_xml($output); |
| 637 #rcube::write_log('mail',"px: ".strlen($output)); | 650 #rcube::write_log('mail',"px: ".strlen($output)); |
| 638 | 651 |
| 639 // trigger generic hook where plugins can put additional content to the page | 652 // trigger generic hook where plugins can put additional content to the page |
| 662 */ | 675 */ |
| 663 protected function get_js_commands(&$framed = null) | 676 protected function get_js_commands(&$framed = null) |
| 664 { | 677 { |
| 665 $out = ''; | 678 $out = ''; |
| 666 $parent_commands = 0; | 679 $parent_commands = 0; |
| 680 $parent_prefix = ''; | |
| 667 $top_commands = array(); | 681 $top_commands = array(); |
| 668 | 682 |
| 669 // these should be always on top, | 683 // these should be always on top, |
| 670 // e.g. hide_message() below depends on env.framed | 684 // e.g. hide_message() below depends on env.framed |
| 671 if (!$this->framed && !empty($this->js_env)) { | 685 if (!$this->framed && !empty($this->js_env)) { |
| 674 if (!empty($this->js_labels)) { | 688 if (!empty($this->js_labels)) { |
| 675 $top_commands[] = array('add_label', $this->js_labels); | 689 $top_commands[] = array('add_label', $this->js_labels); |
| 676 } | 690 } |
| 677 | 691 |
| 678 // unlock interface after iframe load | 692 // unlock interface after iframe load |
| 679 $unlock = preg_replace('/[^a-z0-9]/i', '', $_REQUEST['_unlock']); | 693 $unlock = isset($_REQUEST['_unlock']) ? preg_replace('/[^a-z0-9]/i', '', $_REQUEST['_unlock']) : 0; |
| 680 if ($this->framed) { | 694 if ($this->framed) { |
| 681 $top_commands[] = array('iframe_loaded', $unlock); | 695 $top_commands[] = array('iframe_loaded', $unlock); |
| 682 } | 696 } |
| 683 else if ($unlock) { | 697 else if ($unlock) { |
| 684 $top_commands[] = array('hide_message', $unlock); | 698 $top_commands[] = array('hide_message', $unlock); |
| 727 * | 741 * |
| 728 * @return string URL | 742 * @return string URL |
| 729 */ | 743 */ |
| 730 public function abs_url($str, $search_path = false) | 744 public function abs_url($str, $search_path = false) |
| 731 { | 745 { |
| 732 if ($str[0] == '/') { | 746 if (isset($str[0]) && $str[0] == '/') { |
| 733 if ($search_path && ($file_url = $this->get_skin_file($str, $skin_path))) { | 747 if ($search_path && ($file_url = $this->get_skin_file($str, $skin_path))) { |
| 734 return $file_url; | 748 return $file_url; |
| 735 } | 749 } |
| 736 | 750 |
| 737 return $this->base_path . $str; | 751 return $this->base_path . $str; |
| 875 | 889 |
| 876 return $file; | 890 return $file; |
| 877 } | 891 } |
| 878 | 892 |
| 879 /** | 893 /** |
| 880 * Public wrapper to dipp into template parsing. | 894 * Public wrapper to dip into template parsing. |
| 881 * | 895 * |
| 882 * @param string $input Template content | 896 * @param string $input Template content |
| 883 * | 897 * |
| 884 * @return string | 898 * @return string |
| 885 * @uses rcmail_output_html::parse_xml() | 899 * @uses rcmail_output_html::parse_xml() |
| 955 protected function alter_form_tag($matches) | 969 protected function alter_form_tag($matches) |
| 956 { | 970 { |
| 957 $out = $matches[0]; | 971 $out = $matches[0]; |
| 958 $attrib = html::parse_attrib_string($matches[1]); | 972 $attrib = html::parse_attrib_string($matches[1]); |
| 959 | 973 |
| 960 if (strtolower($attrib['method']) == 'post') { | 974 if (!empty($attrib['method']) && strtolower($attrib['method']) == 'post') { |
| 961 $hidden = new html_hiddenfield(array('name' => '_token', 'value' => $this->app->get_request_token())); | 975 $hidden = new html_hiddenfield(array('name' => '_token', 'value' => $this->app->get_request_token())); |
| 962 $out .= "\n" . $hidden->show(); | 976 $out .= "\n" . $hidden->show(); |
| 963 } | 977 } |
| 964 | 978 |
| 965 return $out; | 979 return $out; |
| 985 '/template:name/i', | 999 '/template:name/i', |
| 986 ), | 1000 ), |
| 987 array( | 1001 array( |
| 988 "\$_SESSION['\\1']", | 1002 "\$_SESSION['\\1']", |
| 989 "\$this->app->config->get('\\1',rcube_utils::get_boolean('\\3'))", | 1003 "\$this->app->config->get('\\1',rcube_utils::get_boolean('\\3'))", |
| 990 "\$this->env['\\1']", | 1004 "(\$this->env['\\1'] ?? null)", |
| 991 "rcube_utils::get_input_value('\\1', rcube_utils::INPUT_GPC)", | 1005 "rcube_utils::get_input_value('\\1', rcube_utils::INPUT_GPC)", |
| 992 "\$_COOKIE['\\1']", | 1006 "(\$_COOKIE['\\1'] ?? null)", |
| 993 "\$this->browser->{'\\1'}", | 1007 "(\$this->browser->{'\\1'} ?? null)", |
| 994 "'{$this->template_name}'", | 1008 "'{$this->template_name}'", |
| 995 ), | 1009 ), |
| 996 $expression | 1010 $expression |
| 997 ); | 1011 ); |
| 998 | 1012 |
| 1044 | 1058 |
| 1045 // execute command | 1059 // execute command |
| 1046 switch ($command) { | 1060 switch ($command) { |
| 1047 // return a button | 1061 // return a button |
| 1048 case 'button': | 1062 case 'button': |
| 1049 if ($attrib['name'] || $attrib['command']) { | 1063 if (!empty($attrib['name']) || !empty($attrib['command'])) { |
| 1050 #rcube::write_log('lab',"button in: ".print_r($attrib,true)); | 1064 #rcube::write_log('lab',"button in: ".print_r($attrib,true)); |
| 1051 $but = $this->button($attrib); | 1065 $but = $this->button($attrib); |
| 1052 #rcube::write_log('lab',"button out:\n$but"); | 1066 #rcube::write_log('lab',"button out:\n$but"); |
| 1053 return $but; | 1067 return $but; |
| 1054 | 1068 |
| 1060 return $this->frame($attrib); | 1074 return $this->frame($attrib); |
| 1061 break; | 1075 break; |
| 1062 | 1076 |
| 1063 // show a label | 1077 // show a label |
| 1064 case 'label': | 1078 case 'label': |
| 1065 if ($attrib['expression']) | 1079 if (!empty($attrib['expression'])) { |
| 1066 $attrib['name'] = $this->eval_expression($attrib['expression']); | 1080 $attrib['name'] = $this->eval_expression($attrib['expression']); |
| 1067 | 1081 } |
| 1068 if ($attrib['name'] || $attrib['command']) { | 1082 |
| 1069 $vars = $attrib + array('product' => $this->config->get('product_name')); | 1083 if (!empty($attrib['name']) || !empty($attrib['command'])) { |
| 1084 $vars = $attrib + ['product' => $this->config->get('product_name')]; | |
| 1070 unset($vars['name'], $vars['command']); | 1085 unset($vars['name'], $vars['command']); |
| 1071 | 1086 |
| 1072 $label = $this->app->gettext($attrib + array('vars' => $vars)); | 1087 $label = $this->app->gettext($attrib + ['vars' => $vars]); |
| 1073 $quoting = !empty($attrib['quoting']) ? strtolower($attrib['quoting']) : (rcube_utils::get_boolean((string)$attrib['html']) ? 'no' : ''); | 1088 $quoting = null; |
| 1089 | |
| 1090 if (!empty($attrib['quoting'])) { | |
| 1091 $quoting = strtolower($attrib['quoting']); | |
| 1092 } | |
| 1093 else if (isset($attrib['html'])) { | |
| 1094 $quoting = rcube_utils::get_boolean((string) $attrib['html']) ? 'no' : ''; | |
| 1095 } | |
| 1074 | 1096 |
| 1075 // 'noshow' can be used in skins to define new labels | 1097 // 'noshow' can be used in skins to define new labels |
| 1076 if ($attrib['noshow']) { | 1098 if (!empty($attrib['noshow'])) { |
| 1077 return ''; | 1099 return ''; |
| 1078 } | 1100 } |
| 1079 | 1101 |
| 1080 switch ($quoting) { | 1102 switch ($quoting) { |
| 1081 case 'no': | 1103 case 'no': |
| 1099 break; | 1121 break; |
| 1100 | 1122 |
| 1101 // include a file | 1123 // include a file |
| 1102 case 'include': | 1124 case 'include': |
| 1103 $old_base_path = $this->base_path; | 1125 $old_base_path = $this->base_path; |
| 1104 if (!empty($attrib['skin_path'])) $attrib['skinpath'] = $attrib['skin_path']; | 1126 $attr_skin_path = !empty($attrib['skinpath']) ? $attrib['skinpath'] : null; |
| 1105 if ($path = $this->get_skin_file($attrib['file'], $skin_path, $attrib['skinpath'])) { | 1127 |
| 1128 if (!empty($attrib['skin_path'])) { | |
| 1129 $attr_skin_path = $attrib['skin_path']; | |
| 1130 } | |
| 1131 | |
| 1132 if ($path = $this->get_skin_file($attrib['file'], $skin_path, $attr_skin_path)) { | |
| 1106 // set base_path to core skin directory (not plugin's skin) | 1133 // set base_path to core skin directory (not plugin's skin) |
| 1107 $this->base_path = preg_replace('!plugins/\w+/!', '', $skin_path); | 1134 $this->base_path = preg_replace('!plugins/\w+/!', '', $skin_path); |
| 1108 $path = realpath(RCUBE_INSTALL_PATH . $path); | 1135 $path = realpath(RCUBE_INSTALL_PATH . $path); |
| 1109 } | 1136 } |
| 1110 | 1137 |
| 1127 $hook = $this->app->plugins->exec_hook("template_plugin_include", $attrib); | 1154 $hook = $this->app->plugins->exec_hook("template_plugin_include", $attrib); |
| 1128 return $hook['content']; | 1155 return $hook['content']; |
| 1129 | 1156 |
| 1130 // define a container block | 1157 // define a container block |
| 1131 case 'container': | 1158 case 'container': |
| 1132 if ($attrib['name'] && $attrib['id']) { | 1159 if (!empty($attrib['name']) && !empty($attrib['id'])) { |
| 1133 $this->command('gui_container', $attrib['name'], $attrib['id']); | 1160 $this->command('gui_container', $attrib['name'], $attrib['id']); |
| 1134 // let plugins insert some content here | 1161 // let plugins insert some content here |
| 1135 $hook = $this->app->plugins->exec_hook("template_container", $attrib); | 1162 $hook = $this->app->plugins->exec_hook("template_container", $attrib); |
| 1136 return $hook['content']; | 1163 return $hook['content']; |
| 1137 } | 1164 } |
| 1139 | 1166 |
| 1140 // return code for a specific application object | 1167 // return code for a specific application object |
| 1141 case 'object': | 1168 case 'object': |
| 1142 $object = strtolower($attrib['name']); | 1169 $object = strtolower($attrib['name']); |
| 1143 $content = ''; | 1170 $content = ''; |
| 1144 | 1171 $handler = null; |
| 1145 // we are calling a class/method | 1172 |
| 1146 if (($handler = $this->object_handlers[$object]) && is_array($handler)) { | 1173 if (!empty($this->object_handlers[$object])) { |
| 1147 if (is_callable($handler)) { | 1174 $handler = $this->object_handlers[$object]; |
| 1148 // We assume that objects with src attribute are internal (in most | |
| 1149 // cases this is a watermark frame). We need this to make sure assets_path | |
| 1150 // is added to the internal assets paths | |
| 1151 $external = empty($attrib['src']); | |
| 1152 $content = call_user_func($handler, $attrib); | |
| 1153 } | |
| 1154 } | 1175 } |
| 1155 // execute object handler function | 1176 // execute object handler function |
| 1156 else if (function_exists($handler)) { | 1177 if (is_callable($handler)) { |
| 1157 $content = call_user_func($handler, $attrib); | 1178 |
| 1179 // We assume that objects with src attribute are internal (in most | |
| 1180 // cases this is a watermark frame). We need this to make sure assets_path | |
| 1181 // is added to the internal assets paths | |
| 1182 $external = empty($attrib['src']); | |
| 1183 $content = call_user_func($handler, $attrib); | |
| 1158 } | 1184 } |
| 1159 else if ($object == 'doctype') { | 1185 else if ($object == 'doctype') { |
| 1160 $content = html::doctype($attrib['value']); | 1186 $content = html::doctype($attrib['value']); |
| 1161 } | 1187 } |
| 1162 else if ($object == 'logo') { | 1188 else if ($object == 'logo') { |
| 1183 $content = html::quote($name); | 1209 $content = html::quote($name); |
| 1184 } | 1210 } |
| 1185 else if ($object == 'version') { | 1211 else if ($object == 'version') { |
| 1186 $ver = (string)RCMAIL_VERSION; | 1212 $ver = (string)RCMAIL_VERSION; |
| 1187 if (is_file(RCUBE_INSTALL_PATH . '.svn/entries')) { | 1213 if (is_file(RCUBE_INSTALL_PATH . '.svn/entries')) { |
| 1188 if (preg_match('/Revision:\s(\d+)/', @shell_exec('svn info'), $regs)) | 1214 if (preg_match('/Revision:\s(\d+)/', (string) @shell_exec('svn info'), $regs)) |
| 1189 $ver .= ' [SVN r'.$regs[1].']'; | 1215 $ver .= ' [SVN r'.$regs[1].']'; |
| 1190 } | 1216 } |
| 1191 else if (is_file(RCUBE_INSTALL_PATH . '.git/index')) { | 1217 else if (is_file(RCUBE_INSTALL_PATH . '.git/index')) { |
| 1192 if (preg_match('/Date:\s+([^\n]+)/', @shell_exec('git log -1'), $regs)) { | 1218 if (preg_match('/Date:\s+([^\n]+)/', (string) @shell_exec('git log -1'), $regs)) { |
| 1193 if ($date = date('Ymd.Hi', strtotime($regs[1]))) { | 1219 if ($date = date('Ymd.Hi', strtotime($regs[1]))) { |
| 1194 $ver .= ' [GIT '.$date.']'; | 1220 $ver .= ' [GIT '.$date.']'; |
| 1195 } | 1221 } |
| 1196 } | 1222 } |
| 1197 } | 1223 } |
| 1210 $title .= $this->get_pagetitle(); | 1236 $title .= $this->get_pagetitle(); |
| 1211 $content = html::quote($title); | 1237 $content = html::quote($title); |
| 1212 } | 1238 } |
| 1213 | 1239 |
| 1214 // exec plugin hooks for this template object | 1240 // exec plugin hooks for this template object |
| 1215 $hook = $this->app->plugins->exec_hook("template_object_$object", $attrib + array('content' => $content)); | 1241 $hook = $this->app->plugins->exec_hook("template_object_$object", $attrib + array('content' => (string) $content)); |
| 1216 | 1242 |
| 1217 if (strlen($hook['content']) && !empty($external)) { | 1243 if (strlen($hook['content']) && !empty($external)) { |
| 1218 $object_id = uniqid('TEMPLOBJECT:', true); | 1244 $object_id = uniqid('TEMPLOBJECT:', true); |
| 1219 $this->objects[$object_id] = $hook['content']; | 1245 $this->objects[$object_id] = $hook['content']; |
| 1220 $hook['content'] = $object_id; | 1246 $hook['content'] = $object_id; |
| 1232 $name = $var[1]; | 1258 $name = $var[1]; |
| 1233 $value = ''; | 1259 $value = ''; |
| 1234 | 1260 |
| 1235 switch ($var[0]) { | 1261 switch ($var[0]) { |
| 1236 case 'env': | 1262 case 'env': |
| 1237 $value = $this->env[$name]; | 1263 $value = $this->env[$name] ?? null; |
| 1238 break; | 1264 break; |
| 1239 case 'config': | 1265 case 'config': |
| 1240 $value = $this->config->get($name); | 1266 $value = $this->config->get($name); |
| 1241 if (is_array($value) && $value[$_SESSION['storage_host']]) { | 1267 if (is_array($value) && !empty($value[$_SESSION['storage_host']])) { |
| 1242 $value = $value[$_SESSION['storage_host']]; | 1268 $value = $value[$_SESSION['storage_host']]; |
| 1243 } | 1269 } |
| 1244 break; | 1270 break; |
| 1245 case 'request': | 1271 case 'request': |
| 1246 $value = rcube_utils::get_input_value($name, rcube_utils::INPUT_GPC); | 1272 $value = rcube_utils::get_input_value($name, rcube_utils::INPUT_GPC); |
| 1247 break; | 1273 break; |
| 1248 case 'session': | 1274 case 'session': |
| 1249 $value = $_SESSION[$name]; | 1275 $value = $_SESSION[$name] ?? ''; |
| 1250 break; | 1276 break; |
| 1251 case 'cookie': | 1277 case 'cookie': |
| 1252 $value = htmlspecialchars($_COOKIE[$name]); | 1278 $value = htmlspecialchars($_COOKIE[$name]); |
| 1253 break; | 1279 break; |
| 1254 case 'browser': | 1280 case 'browser': |
| 1255 $value = $this->browser->{$name}; | 1281 $value = $this->browser->{$name} ?? ''; |
| 1256 break; | 1282 break; |
| 1257 } | 1283 } |
| 1258 | 1284 |
| 1259 if (is_array($value)) { | 1285 if (is_array($value)) { |
| 1260 $value = implode(', ', $value); | 1286 $value = implode(', ', $value); |
| 1290 */ | 1316 */ |
| 1291 protected function postrender($output) | 1317 protected function postrender($output) |
| 1292 { | 1318 { |
| 1293 // insert objects' contents | 1319 // insert objects' contents |
| 1294 foreach ($this->objects as $key => $val) { | 1320 foreach ($this->objects as $key => $val) { |
| 1295 $output = str_replace($key, $val, $output, $count); | 1321 $output = str_replace($key, (string) $val, $output, $count); |
| 1296 if ($count) { | 1322 if ($count) { |
| 1297 $this->objects[$key] = null; | 1323 $this->objects[$key] = null; |
| 1298 } | 1324 } |
| 1299 } | 1325 } |
| 1300 | 1326 |
| 1319 static $disabled_actions = null; | 1345 static $disabled_actions = null; |
| 1320 | 1346 |
| 1321 // these commands can be called directly via url | 1347 // these commands can be called directly via url |
| 1322 $a_static_commands = array('compose', 'list', 'preferences', 'folders', 'identities'); | 1348 $a_static_commands = array('compose', 'list', 'preferences', 'folders', 'identities'); |
| 1323 | 1349 |
| 1324 if (!($attrib['command'] || $attrib['name'] || $attrib['href'])) { | 1350 if (empty($attrib['command']) && empty($attrib['name']) && empty($attrib['href'])) { |
| 1325 return ''; | 1351 return ''; |
| 1326 } | 1352 } |
| 1327 | 1353 |
| 1328 // try to find out the button type | 1354 // try to find out the button type |
| 1329 if ($attrib['type']) { | 1355 if (!empty($attrib['type'])) { |
| 1330 $attrib['type'] = strtolower($attrib['type']); | 1356 $attrib['type'] = strtolower($attrib['type']); |
| 1331 if ($pos = strpos($attrib['type'], '-menuitem')) { | 1357 if ($pos = strpos($attrib['type'], '-menuitem')) { |
| 1332 $attrib['type'] = substr($attrib['type'], 0, -9); | 1358 $attrib['type'] = substr($attrib['type'], 0, -9); |
| 1333 $menuitem = true; | 1359 $menuitem = true; |
| 1334 } | 1360 } |
| 1335 } | 1361 } |
| 1336 else { | 1362 else { |
| 1337 $attrib['type'] = ($attrib['image'] || $attrib['imagepas'] || $attrib['imageact']) ? 'image' : 'link'; | 1363 $attrib['type'] = (!empty($attrib['image']) || !empty($attrib['imagepas']) || !empty($attrib['imageact'])) ? 'image' : 'link'; |
| 1338 } | 1364 } |
| 1339 | 1365 |
| 1340 $command = $attrib['command']; | 1366 $command = $attrib['command']??''; |
| 1341 | 1367 |
| 1342 if ($attrib['task']) { | 1368 if (!empty($attrib['task'])) { |
| 1343 $element = $command = $attrib['task'] . '.' . $command; | 1369 $element = $command = $attrib['task'] . '.' . $command; |
| 1344 } | 1370 } |
| 1345 else { | 1371 else { |
| 1346 $element = ($this->env['task'] ? $this->env['task'] . '.' : '') . $command; | 1372 $element = (!empty($this->env['task']) ? $this->env['task'] . '.' : '') . $command; |
| 1347 } | 1373 } |
| 1348 | 1374 |
| 1349 if ($disabled_actions === null) { | 1375 if ($disabled_actions === null) { |
| 1350 $disabled_actions = (array) $this->config->get('disabled_actions'); | 1376 $disabled_actions = (array) $this->config->get('disabled_actions'); |
| 1351 } | 1377 } |
| 1353 // remove buttons for disabled actions | 1379 // remove buttons for disabled actions |
| 1354 if (in_array($element, $disabled_actions)) { | 1380 if (in_array($element, $disabled_actions)) { |
| 1355 return ''; | 1381 return ''; |
| 1356 } | 1382 } |
| 1357 | 1383 |
| 1358 if (!$attrib['image']) { | 1384 if (empty($attrib['image'])) { |
| 1359 $attrib['image'] = $attrib['imagepas'] ? $attrib['imagepas'] : $attrib['imageact']; | 1385 if (!empty($attrib['imagepas'])) { |
| 1360 } | 1386 $attrib['image'] = $attrib['imagepas']; |
| 1361 | 1387 } |
| 1362 if (!$attrib['id']) { | 1388 else if (!empty($attrib['imageact'])) { |
| 1389 $attrib['image'] = $attrib['imageact']; | |
| 1390 } | |
| 1391 } | |
| 1392 | |
| 1393 if (empty($attrib['id'])) { | |
| 1363 $attrib['id'] = sprintf('rcmbtn%d', $s_button_count++); | 1394 $attrib['id'] = sprintf('rcmbtn%d', $s_button_count++); |
| 1364 } | 1395 } |
| 1365 // get localized text for labels and titles | 1396 // get localized text for labels and titles |
| 1366 if ($attrib['title']) { | 1397 $domain = !empty($attrib['domain']) ? $attrib['domain'] : null; |
| 1367 $attrib['title'] = html::quote($this->app->gettext($attrib['title'], $attrib['domain'])); | 1398 if (!empty($attrib['title'])) { |
| 1368 } | 1399 $attrib['title'] = html::quote($this->app->gettext($attrib['title'], $domain)); |
| 1369 if ($attrib['label']) { | 1400 } |
| 1370 $attrib['label'] = html::quote($this->app->gettext($attrib['label'], $attrib['domain'])); | 1401 if (!empty($attrib['label'])) { |
| 1371 } | 1402 $attrib['label'] = html::quote($this->app->gettext($attrib['label'], $domain)); |
| 1372 if ($attrib['alt']) { | 1403 } |
| 1373 $attrib['alt'] = html::quote($this->app->gettext($attrib['alt'], $attrib['domain'])); | 1404 if (!empty($attrib['alt'])) { |
| 1405 $attrib['alt'] = html::quote($this->app->gettext($attrib['alt'], $domain)); | |
| 1374 } | 1406 } |
| 1375 | 1407 |
| 1376 // set accessibility attributes | 1408 // set accessibility attributes |
| 1377 if (!$attrib['role']) { | 1409 if (empty($attrib['role'])) { |
| 1378 $attrib['role'] = 'button'; | 1410 $attrib['role'] = 'button'; |
| 1379 } | 1411 } |
| 1380 if (!empty($attrib['class']) && !empty($attrib['classact']) || !empty($attrib['imagepas']) && !empty($attrib['imageact'])) { | 1412 if (!empty($attrib['class']) && !empty($attrib['classact']) || !empty($attrib['imagepas']) && !empty($attrib['imageact'])) { |
| 1381 if (array_key_exists('tabindex', $attrib)) | 1413 if (array_key_exists('tabindex', $attrib)) { |
| 1382 $attrib['data-tabindex'] = $attrib['tabindex']; | 1414 $attrib['data-tabindex'] = $attrib['tabindex']; |
| 1383 $attrib['tabindex'] = '-1'; // disable button by default | 1415 } |
| 1416 $attrib['tabindex'] = '-1'; // disable button by default | |
| 1384 $attrib['aria-disabled'] = 'true'; | 1417 $attrib['aria-disabled'] = 'true'; |
| 1385 } | 1418 } |
| 1386 | 1419 |
| 1387 // set title to alt attribute for IE browsers | 1420 // set title to alt attribute for IE browsers |
| 1388 if ($this->browser->ie && !$attrib['title'] && $attrib['alt']) { | 1421 if ($this->browser->ie && empty($attrib['title']) && !empty($attrib['alt'])) { |
| 1389 $attrib['title'] = $attrib['alt']; | 1422 $attrib['title'] = $attrib['alt']; |
| 1390 } | 1423 } |
| 1391 | 1424 |
| 1392 // add empty alt attribute for XHTML compatibility | 1425 // add empty alt attribute for XHTML compatibility |
| 1393 if (!isset($attrib['alt'])) { | 1426 if (!isset($attrib['alt'])) { |
| 1394 $attrib['alt'] = ''; | 1427 $attrib['alt'] = ''; |
| 1395 } | 1428 } |
| 1396 | 1429 |
| 1397 // register button in the system | 1430 // register button in the system |
| 1398 if ($attrib['command']) { | 1431 if (!empty($attrib['command'])) { |
| 1399 $this->add_script(sprintf( | 1432 $this->add_script(sprintf( |
| 1400 "%s.register_button('%s', '%s', '%s', '%s', '%s', '%s');", | 1433 "%s.register_button('%s', '%s', '%s', '%s', '%s', '%s');", |
| 1401 self::JS_OBJECT_NAME, | 1434 self::JS_OBJECT_NAME, |
| 1402 $command, | 1435 $command, |
| 1403 $attrib['id'], | 1436 $attrib['id'], |
| 1404 $attrib['type'], | 1437 $attrib['type'], |
| 1405 $attrib['imageact'] ? $this->abs_url($attrib['imageact']) : $attrib['classact'], | 1438 !empty($attrib['imageact']) ? $this->abs_url($attrib['imageact']) : (!empty($attrib['classact']) ? $attrib['classact'] : ''), |
| 1406 $attrib['imagesel'] ? $this->abs_url($attrib['imagesel']) : $attrib['classsel'], | 1439 !empty($attrib['imagesel']) ? $this->abs_url($attrib['imagesel']) : (!empty($attrib['classsel']) ? $attrib['classsel'] : ''), |
| 1407 $attrib['imageover'] ? $this->abs_url($attrib['imageover']) : '' | 1440 !empty($attrib['imageover']) ? $this->abs_url($attrib['imageover']) : '' |
| 1408 )); | 1441 )); |
| 1409 | 1442 |
| 1410 // make valid href to specific buttons | 1443 // make valid href to specific buttons |
| 1411 if (in_array($attrib['command'], rcmail::$main_tasks)) { | 1444 if (in_array($attrib['command'], rcmail::$main_tasks)) { |
| 1412 $attrib['href'] = $this->app->url(array('task' => $attrib['command'])); | 1445 $attrib['href'] = $this->app->url(array('task' => $attrib['command'])); |
| 1413 $attrib['onclick'] = sprintf("return %s.command('switch-task','%s',this,event)", self::JS_OBJECT_NAME, $attrib['command']); | 1446 $attrib['onclick'] = sprintf("return %s.command('switch-task','%s',this,event)", self::JS_OBJECT_NAME, $attrib['command']); |
| 1414 } | 1447 } |
| 1415 else if ($attrib['task'] && in_array($attrib['task'], rcmail::$main_tasks)) { | 1448 else if (!empty($attrib['task']) && in_array($attrib['task'], rcmail::$main_tasks)) { |
| 1416 $attrib['href'] = $this->app->url(array('action' => $attrib['command'], 'task' => $attrib['task'])); | 1449 $attrib['href'] = $this->app->url(['action' => $attrib['command'], 'task' => $attrib['task']]); |
| 1417 } | 1450 } |
| 1418 else if (in_array($attrib['command'], $a_static_commands)) { | 1451 else if (in_array($attrib['command'], $a_static_commands)) { |
| 1419 $attrib['href'] = $this->app->url(array('action' => $attrib['command'])); | 1452 $attrib['href'] = $this->app->url(array('action' => $attrib['command'])); |
| 1420 } | 1453 } |
| 1421 else if (($attrib['command'] == 'permaurl' || $attrib['command'] == 'extwin') && !empty($this->env['permaurl'])) { | 1454 else if (($attrib['command'] == 'permaurl' || $attrib['command'] == 'extwin') && !empty($this->env['permaurl'])) { |
| 1422 $attrib['href'] = $this->env['permaurl']; | 1455 $attrib['href'] = $this->env['permaurl']; |
| 1423 } | 1456 } |
| 1424 } | 1457 } |
| 1425 | 1458 |
| 1426 // overwrite attributes | 1459 // overwrite attributes |
| 1427 if (!$attrib['href']) { | 1460 if (empty($attrib['href'])) { |
| 1428 $attrib['href'] = '#'; | 1461 $attrib['href'] = '#'; |
| 1429 } | 1462 } |
| 1430 if ($attrib['task']) { | 1463 |
| 1431 if ($attrib['classact']) | 1464 if (!empty($attrib['task'])) { |
| 1465 if (!empty($attrib['classact'])) { | |
| 1432 $attrib['class'] = $attrib['classact']; | 1466 $attrib['class'] = $attrib['classact']; |
| 1433 } | 1467 } |
| 1434 else if ($command && !$attrib['onclick']) { | 1468 } |
| 1469 else if ($command && empty($attrib['onclick'])) { | |
| 1435 $attrib['onclick'] = sprintf( | 1470 $attrib['onclick'] = sprintf( |
| 1436 "return %s.command('%s','%s',this,event)", | 1471 "return %s.command('%s','%s',this,event)", |
| 1437 self::JS_OBJECT_NAME, | 1472 self::JS_OBJECT_NAME, |
| 1438 $command, | 1473 $command, |
| 1439 $attrib['prop'] | 1474 !empty($attrib['prop']) ? $attrib['prop'] : '' |
| 1440 ); | 1475 ); |
| 1441 } | 1476 } |
| 1442 | 1477 |
| 1443 $out = ''; | 1478 $out = ''; |
| 1479 $btn_content = null; | |
| 1480 $link_attrib = []; | |
| 1444 | 1481 |
| 1445 // generate image tag | 1482 // generate image tag |
| 1446 if ($attrib['type'] == 'image') { | 1483 if ($attrib['type'] == 'image') { |
| 1447 $attrib_str = html::attrib_string( | 1484 $attrib_str = html::attrib_string( |
| 1448 $attrib, | 1485 $attrib, |
| 1450 'style', 'class', 'id', 'width', 'height', 'border', 'hspace', | 1487 'style', 'class', 'id', 'width', 'height', 'border', 'hspace', |
| 1451 'vspace', 'align', 'alt', 'tabindex', 'title' | 1488 'vspace', 'align', 'alt', 'tabindex', 'title' |
| 1452 ) | 1489 ) |
| 1453 ); | 1490 ); |
| 1454 $btn_content = sprintf('<img src="%s"%s />', $this->abs_url($attrib['image']), $attrib_str); | 1491 $btn_content = sprintf('<img src="%s"%s />', $this->abs_url($attrib['image']), $attrib_str); |
| 1455 if ($attrib['label']) { | 1492 if (!empty($attrib['label'])) { |
| 1456 $btn_content .= ' '.$attrib['label']; | 1493 $btn_content .= ' '.$attrib['label']; |
| 1457 } | 1494 } |
| 1458 $link_attrib = array('href', 'onclick', 'onmouseover', 'onmouseout', 'onmousedown', 'onmouseup', 'target'); | 1495 $link_attrib = array('href', 'onclick', 'onmouseover', 'onmouseout', 'onmousedown', 'onmouseup', 'target'); |
| 1459 } | 1496 } |
| 1460 else if ($attrib['type'] == 'link') { | 1497 else if ($attrib['type'] == 'link') { |
| 1461 $btn_content = isset($attrib['content']) ? $attrib['content'] : ($attrib['label'] ? $attrib['label'] : $attrib['command']); | 1498 $btn_content = $attrib['content'] ?? (!empty($attrib['label']) ? $attrib['label'] : $attrib['command']); |
| 1462 $link_attrib = array_merge(html::$common_attrib, array('href', 'onclick', 'tabindex', 'target')); | 1499 $link_attrib = array_merge(html::$common_attrib, ['href', 'onclick', 'tabindex', 'target', 'rel']); |
| 1463 if ($attrib['innerclass']) | 1500 if (!empty($attrib['innerclass'])) { |
| 1464 $btn_content = html::span($attrib['innerclass'], $btn_content); | 1501 $btn_content = html::span($attrib['innerclass'], $btn_content); |
| 1502 } | |
| 1465 } | 1503 } |
| 1466 else if ($attrib['type'] == 'input') { | 1504 else if ($attrib['type'] == 'input') { |
| 1467 $attrib['type'] = 'button'; | 1505 $attrib['type'] = 'button'; |
| 1468 | 1506 |
| 1469 if ($attrib['label']) { | 1507 if (!empty($attrib['label'])) { |
| 1470 $attrib['value'] = $attrib['label']; | 1508 $attrib['value'] = $attrib['label']; |
| 1471 } | 1509 } |
| 1472 if ($attrib['command']) { | 1510 if (!empty($attrib['command'])) { |
| 1473 $attrib['disabled'] = 'disabled'; | 1511 $attrib['disabled'] = 'disabled'; |
| 1474 } | 1512 } |
| 1475 | 1513 |
| 1476 $out = html::tag('input', $attrib, null, array('type', 'value', 'onclick', 'id', 'class', 'style', 'tabindex', 'disabled')); | 1514 $out = html::tag('input', $attrib, null, ['type', 'value', 'onclick', 'id', 'class', 'style', 'tabindex', 'disabled']); |
| 1515 } | |
| 1516 else { | |
| 1517 if (!empty($attrib['label'])) { | |
| 1518 $attrib['value'] = $attrib['label']; | |
| 1519 } | |
| 1520 if (!empty($attrib['command'])) { | |
| 1521 $attrib['disabled'] = 'disabled'; | |
| 1522 } | |
| 1523 | |
| 1524 $content = $attrib['content'] ?? $attrib['label']; | |
| 1525 $out = html::tag('button', $attrib, $content, ['type', 'value', 'onclick', 'id', 'class', 'style', 'tabindex', 'disabled']); | |
| 1477 } | 1526 } |
| 1478 | 1527 |
| 1479 // generate html code for button | 1528 // generate html code for button |
| 1480 if ($btn_content) { | 1529 if ($btn_content) { |
| 1481 $attrib_str = html::attrib_string($attrib, $link_attrib); | 1530 $attrib_str = html::attrib_string($attrib, $link_attrib); |
| 1482 $out = sprintf('<a%s>%s</a>', $attrib_str, $btn_content); | 1531 $out = sprintf('<a%s>%s</a>', $attrib_str, $btn_content); |
| 1483 } | 1532 } |
| 1484 | 1533 |
| 1485 if ($attrib['wrapper']) { | 1534 if (!empty($attrib['wrapper'])) { |
| 1486 $out = html::tag($attrib['wrapper'], null, $out); | 1535 $out = html::tag($attrib['wrapper'], null, $out); |
| 1487 } | 1536 } |
| 1488 | 1537 |
| 1489 if ($menuitem) { | 1538 if (!empty($menuitem)) { |
| 1490 $class = $attrib['menuitem-class'] ? ' class="' . $attrib['menuitem-class'] . '"' : ''; | 1539 $class = !empty($attrib['menuitem-class']) ? ' class="' . $attrib['menuitem-class'] . '"' : ''; |
| 1491 $out = '<li role="menuitem"' . $class . '>' . $out . '</li>'; | 1540 $out = '<li role="menuitem"' . $class . '>' . $out . '</li>'; |
| 1492 } | 1541 } |
| 1493 | 1542 |
| 1494 return $out; | 1543 return $out; |
| 1495 } | 1544 } |
| 1504 { | 1553 { |
| 1505 if (!preg_match('|^https?://|i', $file) && $file[0] != '/') { | 1554 if (!preg_match('|^https?://|i', $file) && $file[0] != '/') { |
| 1506 $file = $this->file_mod($this->scripts_path . $file); | 1555 $file = $this->file_mod($this->scripts_path . $file); |
| 1507 } | 1556 } |
| 1508 | 1557 |
| 1509 if (!is_array($this->script_files[$position])) { | 1558 if (!isset($this->script_files[$position]) || !is_array($this->script_files[$position])) { |
| 1510 $this->script_files[$position] = array(); | 1559 $this->script_files[$position] = array(); |
| 1511 } | 1560 } |
| 1512 | 1561 |
| 1513 if (!in_array($file, $this->script_files[$position])) { | 1562 if (!in_array($file, $this->script_files[$position])) { |
| 1514 $this->script_files[$position][] = $file; | 1563 $this->script_files[$position][] = $file; |
| 1551 $this->header .= "\n" . $str; | 1600 $this->header .= "\n" . $str; |
| 1552 } | 1601 } |
| 1553 | 1602 |
| 1554 /** | 1603 /** |
| 1555 * Add HTML code to the page footer | 1604 * Add HTML code to the page footer |
| 1556 * To be added right befor </body> | 1605 * To be added right before </body> |
| 1557 * | 1606 * |
| 1558 * @param string $str HTML code | 1607 * @param string $str HTML code |
| 1559 */ | 1608 */ |
| 1560 public function add_footer($str) | 1609 public function add_footer($str) |
| 1561 { | 1610 { |
| 1625 // put docready commands into page footer | 1674 // put docready commands into page footer |
| 1626 if (!empty($this->scripts['docready'])) { | 1675 if (!empty($this->scripts['docready'])) { |
| 1627 $this->add_script('$(document).ready(function(){ ' . $this->scripts['docready'] . "\n});", 'foot'); | 1676 $this->add_script('$(document).ready(function(){ ' . $this->scripts['docready'] . "\n});", 'foot'); |
| 1628 } | 1677 } |
| 1629 | 1678 |
| 1630 if (is_array($this->script_files['foot'])) { | 1679 if (!empty($this->script_files['foot'])) { |
| 1631 foreach ($this->script_files['foot'] as $file) { | 1680 foreach ($this->script_files['foot'] as $file) { |
| 1632 $page_footer .= html::script($file); | 1681 $page_footer .= html::script($file); |
| 1633 } | 1682 } |
| 1634 } | 1683 } |
| 1635 | 1684 |
| 1656 $hpos++; | 1705 $hpos++; |
| 1657 } | 1706 } |
| 1658 $page_header = "<head>\n<title>$page_title</title>\n$page_header\n</head>\n"; | 1707 $page_header = "<head>\n<title>$page_title</title>\n$page_header\n</head>\n"; |
| 1659 } | 1708 } |
| 1660 | 1709 |
| 1661 // add page hader | 1710 // add page header |
| 1662 if ($hpos) { | 1711 if ($hpos) { |
| 1663 $output = substr_replace($output, $page_header, $hpos, 0); | 1712 $output = substr_replace($output, $page_header, $hpos, 0); |
| 1664 } | 1713 } |
| 1665 else { | 1714 else { |
| 1666 $output = $page_header . $output; | 1715 $output = $page_header . $output; |
| 1673 else { | 1722 else { |
| 1674 $output .= "\n".$page_footer; | 1723 $output .= "\n".$page_footer; |
| 1675 } | 1724 } |
| 1676 | 1725 |
| 1677 // add css files in head, before scripts, for speed up with parallel downloads | 1726 // add css files in head, before scripts, for speed up with parallel downloads |
| 1678 if (!empty($this->css_files) && !$is_empty | 1727 if (!empty($this->css_files) && empty($is_empty) |
| 1679 && (($pos = stripos($output, '<script ')) || ($pos = stripos($output, '</head>'))) | 1728 && (($pos = stripos($output, '<script ')) || ($pos = stripos($output, '</head>'))) |
| 1680 ) { | 1729 ) { |
| 1681 $css = ''; | 1730 $css = ''; |
| 1682 foreach ($this->css_files as $file) { | 1731 foreach ($this->css_files as $file) { |
| 1683 $css .= html::tag('link', array('rel' => 'stylesheet', | 1732 $css .= html::tag('link', array('rel' => 'stylesheet', |
| 1716 */ | 1765 */ |
| 1717 public function frame($attrib, $is_contentframe = false) | 1766 public function frame($attrib, $is_contentframe = false) |
| 1718 { | 1767 { |
| 1719 static $idcount = 0; | 1768 static $idcount = 0; |
| 1720 | 1769 |
| 1721 if (!$attrib['id']) { | 1770 if (empty($attrib['id'])) { |
| 1722 $attrib['id'] = 'rcmframe' . ++$idcount; | 1771 $attrib['id'] = 'rcmframe' . ++$idcount; |
| 1723 } | 1772 } |
| 1724 | 1773 |
| 1725 $attrib['name'] = $attrib['id']; | 1774 $attrib['name'] = $attrib['id']; |
| 1726 $attrib['src'] = $attrib['src'] ? $this->abs_url($attrib['src'], true) : 'program/resources/blank.gif'; | 1775 $attrib['src'] = !empty($attrib['src']) ? $this->abs_url($attrib['src'], true) : 'program/resources/blank.gif'; |
| 1727 | 1776 |
| 1728 // register as 'contentframe' object | 1777 // register as 'contentframe' object |
| 1729 if ($is_contentframe || $attrib['contentframe']) { | 1778 if ($is_contentframe || !empty($attrib['contentframe'])) { |
| 1730 $this->set_env('contentframe', $attrib['contentframe'] ? $attrib['contentframe'] : $attrib['name']); | 1779 $this->set_env('contentframe', !empty($attrib['contentframe']) ? $attrib['contentframe'] : $attrib['name']); |
| 1731 $this->set_env('blankpage', $this->asset_url($attrib['src'])); | 1780 $this->set_env('blankpage', $this->asset_url($attrib['src'])); |
| 1732 } | 1781 } |
| 1733 | 1782 |
| 1734 return html::iframe($attrib); | 1783 return html::iframe($attrib); |
| 1735 } | 1784 } |
| 1745 * | 1794 * |
| 1746 * @return string HTML code for the form | 1795 * @return string HTML code for the form |
| 1747 */ | 1796 */ |
| 1748 public function form_tag($attrib, $content = null) | 1797 public function form_tag($attrib, $content = null) |
| 1749 { | 1798 { |
| 1750 if ($this->env['extwin']) { | 1799 $hidden = ''; |
| 1751 $hiddenfield = new html_hiddenfield(array('name' => '_extwin', 'value' => '1')); | 1800 |
| 1801 if (!empty($this->env['extwin'])) { | |
| 1802 $hiddenfield = new html_hiddenfield(['name' => '_extwin', 'value' => '1']); | |
| 1752 $hidden = $hiddenfield->show(); | 1803 $hidden = $hiddenfield->show(); |
| 1753 } | 1804 } |
| 1754 else if ($this->framed || $this->env['framed']) { | 1805 else if ($this->framed || !empty($this->env['framed'])) { |
| 1755 $hiddenfield = new html_hiddenfield(array('name' => '_framed', 'value' => '1')); | 1806 $hiddenfield = new html_hiddenfield(['name' => '_framed', 'value' => '1']); |
| 1756 $hidden = $hiddenfield->show(); | 1807 $hidden = $hiddenfield->show(); |
| 1757 } | 1808 } |
| 1758 | 1809 |
| 1759 if (!$content) { | 1810 if (!$content) { |
| 1760 $attrib['noclose'] = true; | 1811 $attrib['noclose'] = true; |
| 1777 * @return string HTML code for the form | 1828 * @return string HTML code for the form |
| 1778 */ | 1829 */ |
| 1779 public function request_form($attrib, $content = '') | 1830 public function request_form($attrib, $content = '') |
| 1780 { | 1831 { |
| 1781 $hidden = new html_hiddenfield(); | 1832 $hidden = new html_hiddenfield(); |
| 1782 if ($attrib['task']) { | 1833 |
| 1783 $hidden->add(array('name' => '_task', 'value' => $attrib['task'])); | 1834 if (!empty($attrib['task'])) { |
| 1784 } | 1835 $hidden->add(['name' => '_task', 'value' => $attrib['task']]); |
| 1785 if ($attrib['action']) { | 1836 } |
| 1786 $hidden->add(array('name' => '_action', 'value' => $attrib['action'])); | 1837 |
| 1838 if (!empty($attrib['action'])) { | |
| 1839 $hidden->add(['name' => '_action', 'value' => $attrib['action']]); | |
| 1787 } | 1840 } |
| 1788 | 1841 |
| 1789 // we already have a <form> tag | 1842 // we already have a <form> tag |
| 1790 if ($attrib['form']) { | 1843 if (!empty($attrib['form'])) { |
| 1791 if ($this->framed || $this->env['framed']) { | 1844 if ($this->framed || !empty($this->env['framed'])) { |
| 1792 $hidden->add(array('name' => '_framed', 'value' => '1')); | 1845 $hidden->add(['name' => '_framed', 'value' => '1']); |
| 1793 } | 1846 } |
| 1794 | 1847 |
| 1795 return $hidden->show() . $content; | 1848 return $hidden->show() . $content; |
| 1796 } | 1849 } |
| 1797 | 1850 |
| 1811 */ | 1864 */ |
| 1812 public function current_username($attrib) | 1865 public function current_username($attrib) |
| 1813 { | 1866 { |
| 1814 static $username; | 1867 static $username; |
| 1815 | 1868 |
| 1816 // alread fetched | 1869 // already fetched |
| 1817 if (!empty($username)) { | 1870 if (!empty($username)) { |
| 1818 return $username; | 1871 return $username; |
| 1819 } | 1872 } |
| 1820 | 1873 |
| 1821 // Current username is an e-mail address | 1874 // Current username is an e-mail address |
| 1822 if (strpos($_SESSION['username'], '@')) { | 1875 if (isset($_SESSION['username']) && strpos($_SESSION['username'], '@')) { |
| 1823 $username = $_SESSION['username']; | 1876 $username = $_SESSION['username']; |
| 1824 } | 1877 } |
| 1825 // get e-mail address from default identity | 1878 // get e-mail address from default identity |
| 1826 else if ($sql_arr = $this->app->user->get_identity()) { | 1879 else if ($sql_arr = $this->app->user->get_identity()) { |
| 1827 $username = $sql_arr['email']; | 1880 $username = $sql_arr['email']; |
| 1828 } | 1881 } |
| 1829 else { | 1882 else { |
| 1830 $username = $this->app->user->get_username(); | 1883 $username = $this->app->user->get_username(); |
| 1831 } | 1884 } |
| 1832 | 1885 |
| 1833 return rcube_utils::idn_to_utf8($username); | 1886 $username = rcube_utils::idn_to_utf8($username); |
| 1887 | |
| 1888 return html::quote($username); | |
| 1834 } | 1889 } |
| 1835 | 1890 |
| 1836 /** | 1891 /** |
| 1837 * GUI object 'loginform' | 1892 * GUI object 'loginform' |
| 1838 * Returns code for the webmail login form | 1893 * Returns code for the webmail login form |
| 1848 | 1903 |
| 1849 $_SESSION['temp'] = true; | 1904 $_SESSION['temp'] = true; |
| 1850 | 1905 |
| 1851 // save original url | 1906 // save original url |
| 1852 $url = rcube_utils::get_input_value('_url', rcube_utils::INPUT_POST); | 1907 $url = rcube_utils::get_input_value('_url', rcube_utils::INPUT_POST); |
| 1853 if (empty($url) && !preg_match('/_(task|action)=logout/', $_SERVER['QUERY_STRING'])) | 1908 if (empty($url) |
| 1854 $url = $_SERVER['QUERY_STRING']; | 1909 && !empty($_SERVER['QUERY_STRING']) |
| 1910 && !preg_match('/_(task|action)=logout/', $_SERVER['QUERY_STRING']) | |
| 1911 ) { | |
| 1912 $url = $_SERVER['QUERY_STRING']; | |
| 1913 } | |
| 1855 | 1914 |
| 1856 // Disable autocapitalization on iPad/iPhone (#1488609) | 1915 // Disable autocapitalization on iPad/iPhone (#1488609) |
| 1857 $attrib['autocapitalize'] = 'off'; | 1916 $attrib['autocapitalize'] = 'off'; |
| 1858 | 1917 |
| 1859 $form_name = !empty($attrib['form']) ? $attrib['form'] : 'form'; | 1918 $form_name = !empty($attrib['form']) ? $attrib['form'] : 'form'; |
| 1951 { | 2010 { |
| 1952 $images = preg_split('/[\s\t\n,]+/', $attrib['images'], -1, PREG_SPLIT_NO_EMPTY); | 2011 $images = preg_split('/[\s\t\n,]+/', $attrib['images'], -1, PREG_SPLIT_NO_EMPTY); |
| 1953 $images = array_map(array($this, 'abs_url'), $images); | 2012 $images = array_map(array($this, 'abs_url'), $images); |
| 1954 $images = array_map(array($this, 'asset_url'), $images); | 2013 $images = array_map(array($this, 'asset_url'), $images); |
| 1955 | 2014 |
| 1956 if (empty($images) || $_REQUEST['_task'] == 'logout') { | 2015 if (empty($images) || (isset($_REQUEST['_task']) && $_REQUEST['_task'] == 'logout')) { |
| 1957 return; | 2016 return; |
| 1958 } | 2017 } |
| 1959 | 2018 |
| 1960 $this->add_script('var images = ' . self::json_serialize($images, $this->devel_mode) .'; | 2019 $this->add_script('var images = ' . self::json_serialize($images, $this->devel_mode) .'; |
| 1961 for (var i=0; i<images.length; i++) { | 2020 for (var i=0; i<images.length; i++) { |
| 1980 $attrib['name'] = '_q'; | 2039 $attrib['name'] = '_q'; |
| 1981 | 2040 |
| 1982 if (empty($attrib['id'])) { | 2041 if (empty($attrib['id'])) { |
| 1983 $attrib['id'] = 'rcmqsearchbox'; | 2042 $attrib['id'] = 'rcmqsearchbox'; |
| 1984 } | 2043 } |
| 1985 if ($attrib['type'] == 'search' && !$this->browser->khtml) { | 2044 if (isset($attrib['type']) && $attrib['type'] == 'search' && !$this->browser->khtml) { |
| 1986 unset($attrib['type'], $attrib['results']); | 2045 unset($attrib['type'], $attrib['results']); |
| 1987 } | 2046 } |
| 1988 | 2047 |
| 1989 $input_q = new html_inputfield($attrib); | 2048 $input_q = new html_inputfield($attrib); |
| 1990 $out = $input_q->show(); | 2049 $out = $input_q->show(); |
| 2004 } | 2063 } |
| 2005 | 2064 |
| 2006 /** | 2065 /** |
| 2007 * Builder for GUI object 'message' | 2066 * Builder for GUI object 'message' |
| 2008 * | 2067 * |
| 2009 * @param array Named tag parameters | 2068 * @param array $attrib Named tag parameters |
| 2010 * @return string HTML code for the gui object | 2069 * @return string HTML code for the gui object |
| 2011 */ | 2070 */ |
| 2012 protected function message_container($attrib) | 2071 protected function message_container($attrib) |
| 2013 { | 2072 { |
| 2014 if (isset($attrib['id']) === false) { | 2073 if (isset($attrib['id']) === false) { |
