1<?php 2// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project 3// 4// All Rights Reserved. See copyright.txt for details and a complete list of authors. 5// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details. 6// $Id$ 7 8if (basename($_SERVER['SCRIPT_NAME']) === basename(__FILE__)) { 9 die('This script may only be included.'); 10} 11 12// need to rebuild because they were created in tiki-setup and just removed due to clear cache 13// we need to create upfront in case codemirror is used later on. 14require_once("lib/codemirror_tiki/tiki_codemirror.php"); 15createCodemirrorModes(); 16 17// Javascript auto-detection 18// (to be able to generate non-javascript code if there is no javascript, when noscript tag is not useful enough) 19// It uses cookies instead of session vars to keep the correct value after a session timeout 20 21$js_cookie = getCookie('javascript_enabled'); 22 23if ($prefs['disableJavascript'] == 'y') { 24 $prefs['javascript_enabled'] = 'n'; 25} elseif (! empty($js_cookie)) { 26 // Update the pref with the cookie value 27 $prefs['javascript_enabled'] = 'y'; 28 if ($js_cookie !== 'y') { // if it's not 'y' then it's the expiry in ms 29 setcookie('javascript_enabled', 'y', $js_cookie / 1000); 30 } 31 setCookieSection('javascript_enabled_detect', '', '', time() - 3600); // remove the test cookie 32} else { 33 if (isset($_COOKIE['runs_before_js_detect'])) { // pre-tiki 14 method detected, delete both test cookies (reloading here caused redirect a loop in some case) 34 setcookie('runs_before_js_detect', '', time() - 3600); 35 setcookie('javascript_enabled_detect', '', time() - 3600); 36 } 37 $prefs['javascript_enabled'] = ''; 38} 39 40// the first and second time, we should not trust the absence of javascript_enabled cookie yet, 41// as it could be a redirection and the js will not get a chance to run yet, so we wait until the third run, 42// assuming that js is on before then 43$javascript_enabled_detect = getCookie('javascript_enabled_detect', '', '0'); 44 45// Cookie Consent: setCookieSection uses the session tiki_cookie_jar to simulate cookies, 46// so check that $feature_no_cookie is not true because cookies are not really set when using cookie_consent_feature 47// and so javascript will get disabled by mistake 48 49if (empty($javascript_enabled_detect) && $feature_no_cookie) { 50 $prefs['javascript_enabled'] = 'y'; // assume javascript should be enabled while cookie consent is pending 51} elseif ($prefs['javascript_enabled'] === '' && $prefs['disableJavascript'] != 'y' && $javascript_enabled_detect < 3) { 52 // Set the cookie to 'y', through javascript - expires: approx. 1 year 53 $prefs['javascript_enabled'] = 'y'; // temporarily enable to we output the test js 54 $plus_one_year = ($tikilib->now + 365 * 24 * 3600) * 1000; // ms 55 $headerlib->add_js("setCookieBrowser('javascript_enabled', '{$plus_one_year}', '', new Date({$plus_one_year}));", 0); // setCookieBrowser does not use the tiki_cookie_jar 56 57 if (strpos($_SERVER['PHP_SELF'], 'tiki-download') === false && 58 strpos($_SERVER['PHP_SELF'], 'tiki-ajax_services.php') === false && 59 strpos($_SERVER['PHP_SELF'], 'tiki-login.php') === false && 60 strpos($_SERVER['PHP_SELF'], 'tiki-install.php') === false) { 61 $javascript_enabled_detect++; 62 if ($prefs['javascript_assume_enabled'] != 'y') { 63 setCookieSection('javascript_enabled_detect', $javascript_enabled_detect, '', $plus_one_year / 1000); 64 } 65 } 66} elseif ($js_cookie !== 'y') { // no js cookie detected 67 $prefs['javascript_enabled'] = 'n'; 68} 69 70if ($prefs['javascript_enabled'] == 'n') { 71 // disable js dependant features 72 $prefs['feature_tabs'] = 'n'; 73 $prefs['feature_jquery'] = 'n'; 74 $prefs['feature_shadowbox'] = 'n'; 75 $prefs['feature_wysiwyg'] = 'n'; 76 $prefs['feature_ajax'] = 'n'; 77 $prefs['calendar_fullcalendar'] = 'n'; 78 // assign short variable for use in templates 79 $smarty->assign('js', 0); 80 //for use in setting tags for css menus as fallback for action dropdowns in case of no javascript 81 $smarty->assign('libeg', '<li>'); 82 $smarty->assign('liend', '</li>'); 83} 84 85if ($prefs['javascript_enabled'] == 'y') { // we have JavaScript 86 // assign short variable for use in templates 87 $smarty->assign('js', 1); 88 //for use in setting tags for css menus as fallback for action dropdowns in case of no javascript 89 $smarty->assign('libeg', ''); 90 $smarty->assign('liend', ''); 91 92 $prefs['feature_jquery'] = 'y'; // just in case 93 94 // load translations lang object from /lang/xx/language.js if there 95 if (file_exists('lang/' . $prefs['language'] . '/language.js')) { 96 // after the usual lib includes (up to 10) but before custom.js (50) 97 $headerlib 98 ->add_jsfile_late('lang/' . $prefs['language'] . '/language.js') 99 ->add_js("$.lang = '" . $prefs['language'] . "';"); 100 } 101 102 103 /** Use custom.js in lang dir if there **/ 104 $language = $prefs['language']; 105 if (is_file("lang/$language/custom.js")) { 106 TikiLib::lib('header')->add_jsfile_late("lang/$language/custom.js"); // before styles custom.js 107 } 108 109 if (! empty($tikidomain) && is_file("lang/$language/$tikidomain/custom.js")) { // Note: lang tikidomain dirs not created automatically 110 TikiLib::lib('header')->add_jsfile_late("lang/$language/$tikidomain/custom.js"); 111 } 112 113 114 /** Use custom.js in themes or options dir if there **/ 115 $themelib = TikiLib::lib('theme'); 116 //consider Admin Theme 117 if (! empty($prefs['theme_admin']) && ($section === 'admin' || empty($section))) { // use admin theme if set 118 $custom_js = $themelib->get_theme_path($prefs['theme_admin'], $prefs['theme_option_admin'], 'custom.js'); 119 } else { 120 $custom_js = $themelib->get_theme_path($prefs['theme'], $prefs['theme_option'], 'custom.js'); 121 } 122 if (! empty($custom_js)) { 123 $headerlib->add_jsfile($custom_js); 124 } else { // there's no custom.js in the current theme or option 125 $custom_js = $themelib->get_theme_path('', '', 'custom.js'); // so use one in the root of /themes if there 126 if (! empty($custom_js)) { 127 $headerlib->add_jsfile($custom_js); 128 } 129 } 130 131 132 133 // setup timezone array 134 $tz = TikiDate::getTimezoneAbbreviations(); 135 $headerlib->add_js( 136 ' 137try { 138 var timezone = Intl.DateTimeFormat().resolvedOptions().timeZone; 139 setCookie("local_tz", timezone); 140} catch (e) {} 141 142// this is used by tiki-confirm.js checkTimeout, so needs to be always set 143var now = new Date(); 144 145if (! timezone) { 146 function inArray(item, array) { 147 for (var i in array) { 148 if (array[i] === item) { 149 return i; 150 } 151 } 152 return false; 153 } 154 var allTimeZoneCodes = ' . json_encode(array_map("strtoupper", $tz)) . '; 155 var now_string = now.toString(); 156 var offsethours = - now.getTimezoneOffset() / 60; 157 setCookie("local_tzoffset", offsethours); 158 var m = now_string.match(/[ \(]([A-Z]{3,6})[ \)]?[ \d]*$/); // try three or more char tz first at the end or just before the year 159 if (!m) { 160 m = now_string.match(/[ \(]([A-Z]{1,6})[ \)]?[ \d]*$/); // might be a "military" one if not 161 } 162 if (m) { 163 m = m[1]; 164 } else { // IE (sometimes) gives UTC +offset instead of the abbreviation 165 // sadly this workaround will fail for non-whole hour offsets 166 var hours = - now.getTimezoneOffset() / 60; 167 m = "GMT" + (hours > 0 ? "+" : "") + hours; 168 } 169 // Etc/GMT+ is equivalent to GMT- 170 if (m.substring(0,4) == "GMT+") { 171 m = "Etc/GMT-" + m.substring(4); 172 setCookie("local_tz", m); 173 } 174 if (m.substring(0,4) == "GMT-") { 175 m = "Etc/GMT+" + m.substring(4); 176 setCookie("local_tz", m); 177 } 178 if (inArray(m, allTimeZoneCodes)) { 179 setCookie("local_tz", m); 180 } 181} 182', 183 2 184 ); 185 186 $jqueryTiki['ui'] = $prefs['feature_jquery_ui'] === 'y' ? true : false; 187 $jqueryTiki['ui_theme'] = $prefs['feature_jquery_ui_theme']; 188 $jqueryTiki['tooltips'] = $prefs['feature_jquery_tooltips'] === 'y' ? true : false; 189 $jqueryTiki['autocomplete'] = $prefs['feature_jquery_autocomplete'] === 'y' ? true : false; 190 $jqueryTiki['superfish'] = $prefs['feature_jquery_superfish'] === 'y' ? true : false; 191 $jqueryTiki['reflection'] = $prefs['feature_jquery_reflection'] === 'y' ? true : false; 192 $jqueryTiki['tablesorter'] = $prefs['feature_jquery_tablesorter'] === 'y' ? true : false; 193 $jqueryTiki['colorbox'] = $prefs['feature_shadowbox'] === 'y' ? true : false; 194 $jqueryTiki['cboxCurrent'] = "{current} / {total}"; 195 $jqueryTiki['sheet'] = $prefs['feature_sheet'] === 'y' ? true : false; 196 $jqueryTiki['carousel'] = $prefs['feature_jquery_carousel'] === 'y' ? true : false; 197 $jqueryTiki['validate'] = $prefs['feature_jquery_validation'] === 'y' ? true : false; 198 $jqueryTiki['zoom'] = $prefs['feature_jquery_zoom'] === 'y' ? true : false; 199 200 // Default effect 201 $jqueryTiki['effect'] = $prefs['jquery_effect']; 202 // "horizontal" | "vertical" etc 203 $jqueryTiki['effect_direction'] = $prefs['jquery_effect_direction']; 204 // "slow" | "normal" | "fast" | milliseconds (int) ] 205 $jqueryTiki['effect_speed'] = $prefs['jquery_effect_speed'] === 'normal' ? '400' : $prefs['jquery_effect_speed']; 206 $jqueryTiki['effect_tabs'] = $prefs['jquery_effect_tabs']; // Different effect for tabs 207 $jqueryTiki['effect_tabs_direction'] = $prefs['jquery_effect_tabs_direction']; 208 $jqueryTiki['effect_tabs_speed'] = $prefs['jquery_effect_tabs_speed'] === 'normal' ? '400' : $prefs['jquery_effect_tabs_speed']; 209 $jqueryTiki['home_file_gallery'] = $prefs['home_file_gallery']; 210 211 $jqueryTiki['autosave'] = $prefs['ajax_autosave'] === 'y' ? true : false; 212 $jqueryTiki['sefurl'] = $prefs['feature_sefurl'] === 'y' ? true : false; 213 $jqueryTiki['ajax'] = $prefs['feature_ajax'] === 'y' ? true : false; 214 $jqueryTiki['syntaxHighlighter'] = $prefs['feature_syntax_highlighter'] === 'y' ? true : false; 215 $jqueryTiki['chosen'] = $prefs['jquery_ui_chosen'] === 'y' ? true : false; 216 $jqueryTiki['chosen_sortable'] = $prefs['jquery_ui_chosen_sortable'] === 'y' ? true : false; 217 $jqueryTiki['mapTileSets'] = $tikilib->get_preference('geo_tilesets', ['openstreetmap'], true); 218 $jqueryTiki['infoboxTypes'] = Services_Object_Controller::supported(); 219 $jqueryTiki['googleStreetView'] = $prefs['geo_google_streetview'] === 'y' ? true : false; 220 $jqueryTiki['googleStreetViewOverlay'] = $prefs['geo_google_streetview_overlay'] === 'y' ? true : false; 221 $jqueryTiki['googleMapsAPIKey'] = $prefs['gmap_key']; 222 $jqueryTiki['structurePageRepeat'] = $prefs['page_n_times_in_a_structure'] === 'y' ? true : false; 223 $jqueryTiki['mobile'] = $prefs['mobile_mode'] === 'y' ? true : false; 224 $jqueryTiki['no_cookie'] = false; 225 $jqueryTiki['language'] = $prefs['language']; 226 $jqueryTiki['useInlineComment'] = $prefs['feature_inline_comments'] === 'y' ? true : false; 227 $jqueryTiki['useInlineAnnotations'] = $prefs['comments_inline_annotator'] === 'y' ? true : false; 228 $jqueryTiki['helpurl'] = $prefs['feature_help'] === 'y' ? $prefs['helpurl'] : ''; 229 $jqueryTiki['shortDateFormat'] = $prefs['short_date_format_js']; 230 $jqueryTiki['shortTimeFormat'] = $prefs['short_time_format_js']; 231 $jqueryTiki['username'] = $user; 232 $jqueryTiki['userRealName'] = TikiLib::lib('user')->clean_user($user); 233 $jqueryTiki['userAvatar'] = $base_url . TikiLib::lib('userprefs')->get_public_avatar_path($user); 234 $jqueryTiki['autoToc_inline'] = $prefs['wiki_inline_auto_toc'] === 'y' ? true : false; 235 $jqueryTiki['autoToc_pos'] = $prefs['wiki_toc_pos']; 236 $jqueryTiki['autoToc_offset'] = $prefs['wiki_toc_offset']; 237 $jqueryTiki['bingMapsAPIKey'] = $prefs['geo_bingmaps_key']; 238 $jqueryTiki['nextzenAPIKey'] = $prefs['geo_nextzen_key']; 239 $jqueryTiki['numericFieldScroll'] = $prefs['unified_numeric_field_scroll']; 240 //set at 4 hours if empty 241 $jqueryTiki['securityTimeout'] = !empty($prefs['site_security_timeout']) ? $prefs['site_security_timeout'] 242 : TikiLib::lib('access')->getDefaultTimeout(); 243 244 if (empty($object)) { 245 $object = current_object(); 246 } 247 $jqueryTiki['current_object'] = $object; 248 249 250 if ($prefs['feature_calendar'] === 'y') { 251 $calendarlib = TikiLib::lib('calendar'); 252 $jqueryTiki['firstDayofWeek'] = $calendarlib->firstDayofWeek(); 253 } 254 255 $js = ' 256// JS Object to hold prefs for jq 257var jqueryTiki = ' . json_encode($jqueryTiki, JSON_UNESCAPED_SLASHES) . "\n"; 258 259 if ($prefs['feature_syntax_highlighter'] !== 'y') { 260 // add a dummy syntaxHighlighter object as it seems to be used all over the place without checking for the feature 261 $js .= ' 262var syntaxHighlighter = { 263 ready: function(textarea, settings) { return null; }, 264 sync: function(textarea) { return null; }, 265 add: function(editor, $input, none, skipResize) { return null; }, 266 remove: function($input) { return null; }, 267 get: function($input) { return null; }, 268 fullscreen: function(textarea) { return null; }, 269 find: function(textareaEditor, val) { return null; }, 270 searchCursor: [], 271 replace: function(textareaEditor, val, replaceVal) { return null; }, 272 insertAt: function(textareaEditor, replaceString, perLine, blockLevel) { return null; } 273}; 274'; 275 } 276 277 if ($prefs['jquery_ui_modals_draggable'] === 'y') { 278 $js .= ' 279$(document).on("shown.bs.modal", function (event) { 280 $(event.target).find(".modal-dialog") 281 .css({left: "", top: ""}) 282 .draggable({ 283 handle: ".modal-header", 284 cursor: "grabbing" 285 }); 286}); 287'; 288 $headerlib->add_css('.modal-header {cursor: grab}'); 289 } 290 291 if ($prefs['jquery_ui_modals_resizable'] === 'y') { 292 $js .= ' 293$(document).on("tiki.modal.redraw", function (event) { 294 var $modalContent = $(event.target); 295 if (! $modalContent.is(".modal-content")) { 296 $modalContent = $modalContent.find(".modal-content") 297 } 298 if ($modalContent.is(".ui-resizable")) { 299 $modalContent.resizable( "destroy" ); 300 } 301 $modalContent 302 .css({width: "", height: ""}) 303 .resizable({ 304 minHeight: 100, 305 minWidth: 200 306 }) 307 .find(".modal-body").css({ 308 "overflow": "auto" 309 }); 310});'; 311 } 312 313 $headerlib->add_js($js); 314} 315 316if ($prefs['feature_ajax'] != 'y') { 317 $prefs['ajax_autosave'] = 'n'; 318} 319