diff --git a/SSI.php b/SSI.php index b4d9af584a..f72bcad299 100644 --- a/SSI.php +++ b/SSI.php @@ -81,6 +81,10 @@ require_once($sourcedir . '/Class-BrowserDetect.php'); require_once($sourcedir . '/Subs-Auth.php'); +// Ensure we don't trip over disabled internal functions +if (version_compare(PHP_VERSION, '8.0.0', '>=')) + require_once($sourcedir . '/Subs-Compat.php'); + // Create a variable to store some SMF specific functions in. $smcFunc = array(); diff --git a/Sources/Cache/APIs/FileBased.php b/Sources/Cache/APIs/FileBased.php index f2228371c4..d571bf1f95 100644 --- a/Sources/Cache/APIs/FileBased.php +++ b/Sources/Cache/APIs/FileBased.php @@ -224,7 +224,8 @@ public function cacheSettings(array &$config_vars) if (!isset($context['settings_post_javascript'])) $context['settings_post_javascript'] = ''; - $context['settings_post_javascript'] .= ' + if (empty($context['settings_not_writable'])) + $context['settings_post_javascript'] .= ' $("#cache_accelerator").change(function (e) { var cache_type = e.currentTarget.value; $("#cachedir").prop("disabled", cache_type != "'. $class_name .'"); diff --git a/Sources/Cache/APIs/MemcacheImplementation.php b/Sources/Cache/APIs/MemcacheImplementation.php index 2aef2b366d..b065bbe5ce 100644 --- a/Sources/Cache/APIs/MemcacheImplementation.php +++ b/Sources/Cache/APIs/MemcacheImplementation.php @@ -164,7 +164,8 @@ public function cacheSettings(array &$config_vars) if (!isset($context['settings_post_javascript'])) $context['settings_post_javascript'] = ''; - $context['settings_post_javascript'] .= ' + if (empty($context['settings_not_writable'])) + $context['settings_post_javascript'] .= ' $("#cache_accelerator").change(function (e) { var cache_type = e.currentTarget.value; $("#'. self::CLASS_KEY .'").prop("disabled", cache_type != "MemcacheImplementation" && cache_type != "MemcachedImplementation"); diff --git a/Sources/Cache/APIs/MemcachedImplementation.php b/Sources/Cache/APIs/MemcachedImplementation.php index 8faace6fce..02e128e9cf 100644 --- a/Sources/Cache/APIs/MemcachedImplementation.php +++ b/Sources/Cache/APIs/MemcachedImplementation.php @@ -184,7 +184,8 @@ public function cacheSettings(array &$config_vars) if (!isset($context['settings_post_javascript'])) $context['settings_post_javascript'] = ''; - $context['settings_post_javascript'] .= ' + if (empty($context['settings_not_writable'])) + $context['settings_post_javascript'] .= ' $("#cache_accelerator").change(function (e) { var cache_type = e.currentTarget.value; $("#'. self::CLASS_KEY .'").prop("disabled", cache_type != "MemcacheImplementation" && cache_type != "MemcachedImplementation"); diff --git a/Sources/Cache/APIs/Sqlite.php b/Sources/Cache/APIs/Sqlite.php index 6bfbc92fc5..5c082f1801 100755 --- a/Sources/Cache/APIs/Sqlite.php +++ b/Sources/Cache/APIs/Sqlite.php @@ -146,7 +146,8 @@ public function cacheSettings(array &$config_vars) if (!isset($context['settings_post_javascript'])) $context['settings_post_javascript'] = ''; - $context['settings_post_javascript'] .= ' + if (empty($context['settings_not_writable'])) + $context['settings_post_javascript'] .= ' $("#cache_accelerator").change(function (e) { var cache_type = e.currentTarget.value; $("#cachedir_'. $class_name_txt_key .'").prop("disabled", cache_type != "'. $class_name .'"); diff --git a/Sources/Calendar.php b/Sources/Calendar.php index f3c52e93b7..4d6c52d759 100644 --- a/Sources/Calendar.php +++ b/Sources/Calendar.php @@ -113,7 +113,7 @@ function CalendarMain() // Need a start date for all views if (!empty($_REQUEST['start_date'])) { - $start_parsed = date_parse(convertDateToEnglish($_REQUEST['start_date'])); + $start_parsed = date_parse(str_replace(',', '', convertDateToEnglish($_REQUEST['start_date']))); if (empty($start_parsed['error_count']) && empty($start_parsed['warning_count'])) { $_REQUEST['year'] = $start_parsed['year']; @@ -125,12 +125,12 @@ function CalendarMain() $month = !empty($_REQUEST['month']) ? (int) $_REQUEST['month'] : $today['month']; $day = !empty($_REQUEST['day']) ? (int) $_REQUEST['day'] : (!empty($_REQUEST['month']) ? 1 : $today['day']); - $start_object = checkdate($month, $day, $year) === true ? date_create(implode('-', array($year, $month, $day))) : date_create(implode('-', array($today['year'], $today['month'], $today['day']))); + $start_object = checkdate($month, $day, $year) === true ? date_create(implode('-', array($year, $month, $day)) . ' ' . getUserTimezone()) : date_create(implode('-', array($today['year'], $today['month'], $today['day'])) . ' ' . getUserTimezone()); // Need an end date for the list view if (!empty($_REQUEST['end_date'])) { - $end_parsed = date_parse(convertDateToEnglish($_REQUEST['end_date'])); + $end_parsed = date_parse(str_replace(',', '', convertDateToEnglish($_REQUEST['end_date']))); if (empty($end_parsed['error_count']) && empty($end_parsed['warning_count'])) { $_REQUEST['end_year'] = $end_parsed['year']; @@ -146,14 +146,14 @@ function CalendarMain() if (isset($end_month, $end_day, $end_year) && checkdate($end_month, $end_day, $end_year)) { - $end_object = date_create(implode('-', array($end_year, $end_month, $end_day))); + $end_object = date_create(implode('-', array($end_year, $end_month, $end_day)) . ' ' . getUserTimezone()); } if (empty($end_object) || $start_object >= $end_object) { $num_days_shown = empty($modSettings['cal_days_for_index']) || $modSettings['cal_days_for_index'] < 1 ? 1 : $modSettings['cal_days_for_index']; - $end_object = date_create(date_format($start_object, 'Y-m-d')); + $end_object = date_create(date_format($start_object, 'Y-m-d') . ' ' . getUserTimezone()); date_add($end_object, date_interval_create_from_date_string($num_days_shown . ' days')); } diff --git a/Sources/Load.php b/Sources/Load.php index 7545ecfe23..3d0eb4f261 100644 --- a/Sources/Load.php +++ b/Sources/Load.php @@ -1850,6 +1850,7 @@ function loadMemberContext($user, $display_custom_fields = false) $value = $value ? $txt['yes'] : $txt['no']; // Enclosing the user input within some other text? + $simple_value = $value; if (!empty($custom['enclose'])) $value = strtr($custom['enclose'], array( '{SCRIPTURL}' => $scripturl, @@ -1863,6 +1864,7 @@ function loadMemberContext($user, $display_custom_fields = false) 'title' => tokenTxtReplace(!empty($custom['title']) ? $custom['title'] : $custom['col_name']), 'col_name' => tokenTxtReplace($custom['col_name']), 'value' => un_htmlspecialchars(tokenTxtReplace($value)), + 'simple' => tokenTxtReplace($simple_value), 'raw' => $profile['options'][$custom['col_name']], 'placement' => !empty($custom['placement']) ? $custom['placement'] : 0, ); diff --git a/Sources/ManageServer.php b/Sources/ManageServer.php index 763ee8f813..eb06d487b7 100644 --- a/Sources/ManageServer.php +++ b/Sources/ManageServer.php @@ -115,13 +115,7 @@ function ModifySettings() $settings_not_writable = !is_writable($boarddir . '/Settings.php'); $settings_backup_fail = !@is_writable($boarddir . '/Settings_bak.php') || !@copy($boarddir . '/Settings.php', $boarddir . '/Settings_bak.php'); - if ($settings_not_writable) - $context['settings_message'] = array( - 'label' => $txt['settings_not_writable'], - 'tag' => 'div', - 'class' => 'centertext strong' - ); - elseif ($settings_backup_fail) + if ($settings_backup_fail) $context['settings_message'] = array( 'label' => $txt['admin_backup_fail'], 'tag' => 'div', @@ -188,6 +182,7 @@ function ModifyGeneralSettings($return_config = false) // Setup the template stuff. $context['post_url'] = $scripturl . '?action=admin;area=serversettings;sa=general;save'; $context['settings_title'] = $txt['general_settings']; + $context['save_disabled'] = $context['settings_not_writable']; // Saving settings? if (isset($_REQUEST['save'])) @@ -226,7 +221,8 @@ function ModifyGeneralSettings($return_config = false) prepareServerSettingsContext($config_vars); // Some javascript for SSL - addInlineJavaScript(' + if (empty($context['settings_not_writable'])) + addInlineJavaScript(' $(function() { $("#force_ssl").change(function() @@ -535,6 +531,7 @@ function hideGlobalCookies() $context['post_url'] = $scripturl . '?action=admin;area=serversettings;sa=cookie;save'; $context['settings_title'] = $txt['cookies_sessions_settings']; + $context['save_disabled'] = $context['settings_not_writable']; // Saving settings? if (isset($_REQUEST['save'])) @@ -731,7 +728,7 @@ function ModifyGeneralSecuritySettings($return_config = false) */ function ModifyCacheSettings($return_config = false) { - global $context, $scripturl, $txt, $cacheAPI, $cache_enable; + global $context, $scripturl, $txt, $cacheAPI, $cache_enable, $cache_accelerator; // Detect all available optimizers $detectedCacheApis = loadCacheAPIs(); @@ -1041,7 +1038,14 @@ function ModifyLoadBalancingSettings($return_config = false) */ function prepareServerSettingsContext(&$config_vars) { - global $context, $modSettings, $smcFunc; + global $context, $modSettings, $smcFunc, $txt; + + if ($context['settings_not_writable']) + $context['settings_message'] = array( + 'label' => $txt['settings_not_writable'], + 'tag' => 'div', + 'class' => 'centertext strong' + ); if (isset($_SESSION['adm-save'])) { diff --git a/Sources/ManageSettings.php b/Sources/ManageSettings.php index 9e954e45c4..2ec6790545 100644 --- a/Sources/ManageSettings.php +++ b/Sources/ManageSettings.php @@ -785,7 +785,7 @@ function ModifyAntispamSettings($return_config = false) $context['question_answers'][$row['id_question']] = array( 'lngfile' => $lang, 'question' => $row['question'], - 'answers' => $smcFunc['json_decode']($row['answers'], true), + 'answers' => (array) $smcFunc['json_decode']($row['answers'], true), ); $context['qa_by_lang'][$lang][] = $row['id_question']; } diff --git a/Sources/Memberlist.php b/Sources/Memberlist.php index 185dc31bb7..abdf366ab5 100644 --- a/Sources/Memberlist.php +++ b/Sources/Memberlist.php @@ -575,7 +575,7 @@ function MLSearch() } foreach ($context['custom_search_fields'] as $field) - $context['search_fields']['cust_' . $field['colname']] = sprintf($txt['mlist_search_by'], $field['name']); + $context['search_fields']['cust_' . $field['colname']] = sprintf($txt['mlist_search_by'], tokenTxtReplace($field['name'])); $context['sub_template'] = 'search'; $context['old_search'] = isset($_GET['search']) ? $_GET['search'] : (isset($_POST['search']) ? $smcFunc['htmlspecialchars']($_POST['search']) : ''); diff --git a/Sources/News.php b/Sources/News.php index a532f2ea4c..206ce924a9 100644 --- a/Sources/News.php +++ b/Sources/News.php @@ -2071,7 +2071,7 @@ function getXmlProfile($xml_format) $data[] = array( 'tag' => $custom_field['col_name'], 'attributes' => array('label' => $custom_field['title']), - 'content' => $custom_field['raw'], + 'content' => $custom_field['simple'], 'cdata' => true, ); } diff --git a/Sources/Post.php b/Sources/Post.php index 0b84c3c6e8..614bf6fa53 100644 --- a/Sources/Post.php +++ b/Sources/Post.php @@ -1234,9 +1234,18 @@ function($m) foreach ($attachmentRestrictionTypes as $type) if (!empty($modSettings[$type])) { + $context['attachment_restrictions'][$type] = sprintf($txt['attach_restrict_' . $type . ($modSettings[$type] >= 1024 ? '_MB' : '')], comma_format($modSettings[$type] >= 1024 ? $modSettings[$type] / 1024 : $modSettings[$type], 2)); + // Show the max number of attachments if not 0. if ($type == 'attachmentNumPerPostLimit') - $context['attachment_restrictions'][] = sprintf($txt['attach_remaining'], max($modSettings['attachmentNumPerPostLimit'] - $context['attachments']['quantity'], 0)); + { + $context['attachment_restrictions'][$type] .= ' (' . sprintf($txt['attach_remaining'], max($modSettings['attachmentNumPerPostLimit'] - $context['attachments']['quantity'], 0)) . ')'; + } + elseif ($type == 'attachmentPostLimit' && $context['attachments']['total_size'] > 0) + { + $context['attachment_restrictions'][$type] .= ' (' . sprintf($txt['attach_available'], max($modSettings['attachmentPostLimit'] - ($context['attachments']['total_size'] / 1024), 0)) . ')'; + } + } } @@ -2233,8 +2242,8 @@ function Post2() unlink($attachment['tmp_name']); } } - unset($_SESSION['temp_attachments']); } + unset($_SESSION['temp_attachments']); // Make the poll... if (isset($_REQUEST['poll'])) diff --git a/Sources/Profile-Export.php b/Sources/Profile-Export.php index 34c9b0428b..8539cba42d 100644 --- a/Sources/Profile-Export.php +++ b/Sources/Profile-Export.php @@ -655,9 +655,6 @@ function export_attachment($uid) send_http_status(403); exit; } - - // We need the topic. - list ($_REQUEST['topic']) = $smcFunc['db_fetch_row']($request); $smcFunc['db_free_result']($request); // This doesn't count as a normal download. diff --git a/Sources/Profile-Modify.php b/Sources/Profile-Modify.php index 09009f4c08..4f45fc3f3d 100644 --- a/Sources/Profile-Modify.php +++ b/Sources/Profile-Modify.php @@ -966,25 +966,25 @@ function saveProfileChanges(&$profile_vars, &$post_errors, $memID) 'ignore_boards', ); - if (isset($_POST['sa']) && $_POST['sa'] == 'ignoreboards' && empty($_POST['ignore_brd'])) - $_POST['ignore_brd'] = array(); + if (isset($_POST['sa']) && $_POST['sa'] == 'ignoreboards' && empty($_POST['brd'])) + $_POST['brd'] = array(); unset($_POST['ignore_boards']); // Whatever it is set to is a dirty filthy thing. Kinda like our minds. - if (isset($_POST['ignore_brd'])) + if (isset($_POST['brd'])) { - if (!is_array($_POST['ignore_brd'])) - $_POST['ignore_brd'] = array($_POST['ignore_brd']); + if (!is_array($_POST['brd'])) + $_POST['brd'] = array($_POST['brd']); - foreach ($_POST['ignore_brd'] as $k => $d) + foreach ($_POST['brd'] as $k => $d) { $d = (int) $d; if ($d != 0) - $_POST['ignore_brd'][$k] = $d; + $_POST['brd'][$k] = $d; else - unset($_POST['ignore_brd'][$k]); + unset($_POST['brd'][$k]); } - $_POST['ignore_boards'] = implode(',', $_POST['ignore_brd']); - unset($_POST['ignore_brd']); + $_POST['ignore_boards'] = implode(',', $_POST['brd']); + unset($_POST['brd']); } // Here's where we sort out all the 'other' values... @@ -1278,7 +1278,7 @@ function makeCustomFieldChanges($memID, $area, $sanitize = true, $returnErrors = if (empty($value) && !is_numeric($value)) $value = ''; - if ($row['mask'] == 'nohtml' && ($valueReference != strip_tags($valueReference) || $value != filter_var($value, FILTER_SANITIZE_STRING) || preg_match('/<(.+?)[\s]*\/?[\s]*>/si', $valueReference))) + if ($row['mask'] == 'nohtml' && ($valueReference != strip_tags($valueReference) || $value != filter_var($value, FILTER_SANITIZE_FULL_SPECIAL_CHARS) || preg_match('/<(.+?)[\s]*\/?[\s]*>/si', $valueReference))) { if ($returnErrors) $errors[] = 'custom_field_nohtml_fail'; diff --git a/Sources/ShowAttachments.php b/Sources/ShowAttachments.php index 18e808a003..52560efec4 100644 --- a/Sources/ShowAttachments.php +++ b/Sources/ShowAttachments.php @@ -64,12 +64,10 @@ function showAttachment() } // A thumbnail has been requested? madness! madness I say! - $preview = isset($_REQUEST['preview']) ? $_REQUEST['preview'] : (isset($_REQUEST['type']) && $_REQUEST['type'] == 'preview' ? $_REQUEST['type'] : 0); $showThumb = isset($_REQUEST['thumb']); - $attachTopic = isset($_REQUEST['topic']) ? (int) $_REQUEST['topic'] : 0; - // No access in strict maintenance mode or you don't have permission to see attachments. - if ((!empty($maintenance) && $maintenance == 2) || (!allowedTo('view_attachments') && !isset($_SESSION['attachments_can_preview'][$attachId]))) + // No access in strict maintenance mode. + if (!empty($maintenance) && $maintenance == 2) { send_http_status(404, 'File Not Found'); die('404 File Not Found'); @@ -92,13 +90,16 @@ function showAttachment() // Make sure this attachment is on this board and load its info while we are at it. $request = $smcFunc['db_query']('', ' SELECT - id_folder, filename, file_hash, fileext, id_attach, - id_thumb, attachment_type, mime_type, approved, id_msg - FROM {db_prefix}attachments - WHERE id_attach = {int:attach}' . (!empty($context['preview_message']) ? ' - AND a.id_msg != 0' : '') . ' + {string:source} AS source, + a.id_folder, a.filename, a.file_hash, a.fileext, a.id_attach, + a.id_thumb, a.attachment_type, a.mime_type, a.approved, a.id_msg, + m.id_board + FROM {db_prefix}attachments AS a + LEFT JOIN {db_prefix}messages AS m ON (m.id_msg = a.id_msg) + WHERE a.id_attach = {int:attach} LIMIT 1', array( + 'source' => 'SMF', 'attach' => $attachId, ) ); @@ -114,63 +115,6 @@ function showAttachment() $file = $smcFunc['db_fetch_assoc']($request); $smcFunc['db_free_result']($request); - // If theres a message ID stored, we NEED a topic ID. - if (!empty($file['id_msg']) && empty($attachTopic) && empty($preview)) - { - send_http_status(404, 'File Not Found'); - die('404 File Not Found'); - } - - // Previews doesn't have this info. - if (empty($preview) && is_resource($attachRequest)) - { - $request2 = $smcFunc['db_query']('', ' - SELECT a.id_msg - FROM {db_prefix}attachments AS a - INNER JOIN {db_prefix}messages AS m ON (m.id_msg = a.id_msg AND m.id_topic = {int:current_topic}) - WHERE {query_see_message_board} - AND a.id_attach = {int:attach} - LIMIT 1', - array( - 'attach' => $attachId, - 'current_topic' => $attachTopic, - ) - ); - - // The provided topic must match the one stored in the DB for this particular attachment, also. - if ($smcFunc['db_num_rows']($request2) == 0) - { - send_http_status(404, 'File Not Found'); - die('404 File Not Found'); - } - - $smcFunc['db_free_result']($request2); - } - - // If attachment is unapproved, see if user is allowed to approve - if (!$file['approved'] && $modSettings['postmod_active'] && !allowedTo('approve_posts')) - { - $request3 = $smcFunc['db_query']('', ' - SELECT id_member - FROM {db_prefix}messages - WHERE id_msg = {int:id_msg} - LIMIT 1', - array( - 'id_msg' => $file['id_msg'], - ) - ); - - $id_member = $smcFunc['db_fetch_assoc']($request3)['id_member']; - $smcFunc['db_free_result']($request3); - - // Let users see own unapproved attachments - if ($id_member != $user_info['id']) - { - send_http_status(403, 'Forbidden'); - die('403 Forbidden'); - } - } - // set filePath and ETag time $file['filePath'] = getAttachmentFilename($file['filename'], $attachId, $file['id_folder'], false, $file['file_hash']); // ensure variant attachment compatibility @@ -210,6 +154,63 @@ function showAttachment() cache_put_data('attachment_lookup_id-' . $file['id_attach'], array($file, $thumbFile), mt_rand(850, 900)); } + // No access if you don't have permission to see this attachment. + if + ( + // This was from SMF or a hook didn't claim it. + ( + empty($file['source']) + || $file['source'] == 'SMF' + ) + && ( + // No id_msg and no id_member, so we don't know where its from. + // Avatars will have id_msg = 0 and id_member > 0. + ( + empty($file['id_msg']) + && empty($file['id_member']) + ) + // When we have a message, we need a board and that board needs to + // let us view the attachment. + || ( + !empty($file['id_msg']) + && ( + empty($file['id_board']) + || !allowedTo('view_attachments', $file['id_board']) + ) + ) + ) + // We are not previewing an attachment. + && !isset($_SESSION['attachments_can_preview'][$attachId]) + ) + { + send_http_status(404, 'File Not Found'); + die('404 File Not Found'); + } + + // If attachment is unapproved, see if user is allowed to approve + if (!$file['approved'] && $modSettings['postmod_active'] && !allowedTo('approve_posts')) + { + $request = $smcFunc['db_query']('', ' + SELECT id_member + FROM {db_prefix}messages + WHERE id_msg = {int:id_msg} + LIMIT 1', + array( + 'id_msg' => $file['id_msg'], + ) + ); + + $id_member = $smcFunc['db_fetch_assoc']($request)['id_member']; + $smcFunc['db_free_result']($request); + + // Let users see own unapproved attachments + if ($id_member != $user_info['id']) + { + send_http_status(403, 'Forbidden'); + die('403 Forbidden'); + } + } + // Replace the normal file with its thumbnail if it has one! if (!empty($showThumb) && !empty($thumbFile)) $file = $thumbFile; diff --git a/Sources/Subs-Attachments.php b/Sources/Subs-Attachments.php index 7986b5fb39..b017df028e 100644 --- a/Sources/Subs-Attachments.php +++ b/Sources/Subs-Attachments.php @@ -1003,7 +1003,10 @@ function parseAttachBBC($attachID = 0) $attachInfo = getAttachMsgInfo($attachID); // There is always the chance this attachment no longer exists or isn't associated to a message anymore... - if (empty($attachInfo) || empty($attachInfo['msg']) && empty($context['preview_message'])) + if (empty($attachInfo)) + return 'attachments_no_data_loaded'; + + if (empty($attachInfo['msg']) && empty($context['preview_message'])) return 'attachments_no_msg_associated'; // Can the user view attachments on the board that holds the attachment's original post? @@ -1057,18 +1060,6 @@ function parseAttachBBC($attachID = 0) if ($check_board_perms && !in_array($attachContext['board'], $view_attachment_boards)) return 'attachments_not_allowed_to_see'; - // Previewing much? No msg ID has been set yet. - if (!empty($context['preview_message'])) - { - $attachContext['href'] = $scripturl . '?action=dlattach;attach=' . $attachID . ';type=preview'; - - $attachContext['link'] = '' . $smcFunc['htmlspecialchars']($attachContext['name']) . ''; - - // Fix the thumbnail too, if the image has one. - if (!empty($attachContext['thumbnail']) && !empty($attachContext['thumbnail']['has_thumb'])) - $attachContext['thumbnail']['href'] = $scripturl . '?action=dlattach;attach=' . $attachContext['thumbnail']['id'] . ';image;type=preview'; - } - // You may or may not want to show this under the post. if (!empty($modSettings['dont_show_attach_under_post']) && !isset($context['show_attach_under_post'][$attachID])) $context['show_attach_under_post'][$attachID] = $attachID; @@ -1207,8 +1198,8 @@ function loadAttachmentContext($id_msg, $attachments) 'downloads' => $attachment['downloads'], 'size' => ($attachment['filesize'] < 1024000) ? round($attachment['filesize'] / 1024, 2) . ' ' . $txt['kilobyte'] : round($attachment['filesize'] / 1024 / 1024, 2) . ' ' . $txt['megabyte'], 'byte_size' => $attachment['filesize'], - 'href' => $scripturl . '?action=dlattach;topic=' . $attachment['topic'] . '.0;attach=' . $attachment['id_attach'], - 'link' => '' . $smcFunc['htmlspecialchars']($attachment['filename']) . '', + 'href' => $scripturl . '?action=dlattach;attach=' . $attachment['id_attach'], + 'link' => '' . $smcFunc['htmlspecialchars']($attachment['filename']) . '', 'is_image' => !empty($attachment['width']) && !empty($attachment['height']), 'is_approved' => $attachment['approved'], 'topic' => $attachment['topic'], @@ -1314,7 +1305,7 @@ function loadAttachmentContext($id_msg, $attachments) if (!empty($attachment['id_thumb'])) $attachmentData[$i]['thumbnail'] = array( 'id' => $attachment['id_thumb'], - 'href' => $scripturl . '?action=dlattach;topic=' . $attachment['topic'] . '.0;attach=' . $attachment['id_thumb'] . ';image', + 'href' => $scripturl . '?action=dlattach;attach=' . $attachment['id_thumb'] . ';image', ); $attachmentData[$i]['thumbnail']['has_thumb'] = !empty($attachment['id_thumb']); diff --git a/Sources/Subs-Calendar.php b/Sources/Subs-Calendar.php index 2f7688c97e..4b48a3c4d3 100644 --- a/Sources/Subs-Calendar.php +++ b/Sources/Subs-Calendar.php @@ -122,10 +122,10 @@ function getEventRange($low_date, $high_date, $use_permissions = true) require_once($sourcedir . '/Subs.php'); if (empty($timezone_array['default'])) - $timezone_array['default'] = timezone_open(date_default_timezone_get()); + $timezone_array['default'] = timezone_open(getUserTimezone()); - $low_object = date_create($low_date); - $high_object = date_create($high_date); + $low_object = date_create($low_date, $timezone_array['default']); + $high_object = date_create($high_date, $timezone_array['default']); // Find all the calendar info... $result = $smcFunc['db_query']('calendar_get_events', ' @@ -372,10 +372,10 @@ function canLinkEvent() function getTodayInfo() { return array( - 'day' => (int) smf_strftime('%d', time()), - 'month' => (int) smf_strftime('%m', time()), - 'year' => (int) smf_strftime('%Y', time()), - 'date' => smf_strftime('%Y-%m-%d', time()), + 'day' => (int) smf_strftime('%d', time(), getUserTimezone()), + 'month' => (int) smf_strftime('%m', time(), getUserTimezone()), + 'year' => (int) smf_strftime('%Y', time(), getUserTimezone()), + 'date' => smf_strftime('%Y-%m-%d', time(), getUserTimezone()), ); } @@ -392,12 +392,12 @@ function getCalendarGrid($selected_date, $calendarOptions, $is_previous = false, { global $scripturl, $modSettings; - $selected_object = date_create($selected_date); + $selected_object = date_create($selected_date . ' ' . getUserTimezone()); - $next_object = date_create($selected_date); + $next_object = date_create($selected_date . ' ' . getUserTimezone()); $next_object->modify('first day of next month'); - $prev_object = date_create($selected_date); + $prev_object = date_create($selected_date . ' ' . getUserTimezone()); $prev_object->modify('first day of previous month'); // Eventually this is what we'll be returning. @@ -431,8 +431,8 @@ function getCalendarGrid($selected_date, $calendarOptions, $is_previous = false, // Get today's date. $today = getTodayInfo(); - $first_day_object = date_create(date_format($selected_object, 'Y-m-01')); - $last_day_object = date_create(date_format($selected_object, 'Y-m-t')); + $first_day_object = date_create(date_format($selected_object, 'Y-m-01') . ' ' . getUserTimezone()); + $last_day_object = date_create(date_format($selected_object, 'Y-m-t') . ' ' . getUserTimezone()); // Get information about this month. $month_info = array( @@ -445,8 +445,8 @@ function getCalendarGrid($selected_date, $calendarOptions, $is_previous = false, 'day_of_month' => date_format($last_day_object, 't'), 'date' => date_format($last_day_object, 'Y-m-d'), ), - 'first_day_of_year' => date_format(date_create(date_format($selected_object, 'Y-01-01')), 'w'), - 'first_day_of_next_year' => date_format(date_create((date_format($selected_object, 'Y') + 1) . '-01-01'), 'w'), + 'first_day_of_year' => date_format(date_create(date_format($selected_object, 'Y-01-01') . ' ' . getUserTimezone()), 'w'), + 'first_day_of_next_year' => date_format(date_create((date_format($selected_object, 'Y') + 1) . '-01-01' . ' ' . getUserTimezone()), 'w'), ); // The number of days the first row is shifted to the right for the starting day. @@ -545,7 +545,7 @@ function getCalendarWeek($selected_date, $calendarOptions) { global $scripturl, $modSettings, $txt; - $selected_object = date_create($selected_date); + $selected_object = date_create($selected_date . ' ' . getUserTimezone()); // Get today's date. $today = getTodayInfo(); @@ -553,7 +553,7 @@ function getCalendarWeek($selected_date, $calendarOptions) // What is the actual "start date" for the passed day. $calendarOptions['start_day'] = empty($calendarOptions['start_day']) ? 0 : (int) $calendarOptions['start_day']; $day_of_week = date_format($selected_object, 'w'); - $first_day_object = date_create($selected_date); + $first_day_object = date_create($selected_date . ' ' . getUserTimezone()); if ($day_of_week != $calendarOptions['start_day']) { // Here we offset accordingly to get things to the real start of a week. @@ -564,17 +564,17 @@ function getCalendarWeek($selected_date, $calendarOptions) date_sub($first_day_object, date_interval_create_from_date_string($date_diff . ' days')); } - $last_day_object = date_create(date_format($first_day_object, 'Y-m-d')); + $last_day_object = date_create(date_format($first_day_object, 'Y-m-d') . ' ' . getUserTimezone()); date_add($last_day_object, date_interval_create_from_date_string('1 week')); $month = date_format($first_day_object, 'n'); $year = date_format($first_day_object, 'Y'); $day = date_format($first_day_object, 'd'); - $next_object = date_create($selected_date); + $next_object = date_create($selected_date . ' ' . getUserTimezone()); date_add($next_object, date_interval_create_from_date_string('1 week')); - $prev_object = date_create($selected_date); + $prev_object = date_create($selected_date . ' ' . getUserTimezone()); date_sub($prev_object, date_interval_create_from_date_string('1 week')); // Now start filling in the calendar grid. @@ -609,7 +609,7 @@ function getCalendarWeek($selected_date, $calendarOptions) // This holds all the main data - there is at least one month! $calendarGrid['months'] = array(); - $current_day_object = date_create(date_format($first_day_object, 'Y-m-d')); + $current_day_object = date_create(date_format($first_day_object, 'Y-m-d') . ' ' . getUserTimezone()); for ($i = 0; $i < 7; $i++) { $current_month = date_format($current_day_object, 'n'); @@ -660,8 +660,8 @@ function getCalendarList($start_date, $end_date, $calendarOptions) require_once($sourcedir . '/Subs.php'); // DateTime objects make life easier - $start_object = date_create($start_date); - $end_object = date_create($end_date); + $start_object = date_create($start_date . ' ' . getUserTimezone()); + $end_object = date_create($end_date . ' ' . getUserTimezone()); $calendarGrid = array( 'start_date' => timeformat(date_format($start_object, 'U'), get_date_or_time_format('date')), @@ -1053,7 +1053,7 @@ function validateEventPost() // The 2.1 way if (isset($_POST['start_date'])) { - $d = date_parse(convertDateToEnglish($_POST['start_date'])); + $d = date_parse(str_replace(',', '', convertDateToEnglish($_POST['start_date']))); if (!empty($d['error_count']) || !empty($d['warning_count'])) fatal_lang_error('invalid_date', false); if (empty($d['year'])) @@ -1063,7 +1063,7 @@ function validateEventPost() } elseif (isset($_POST['start_datetime'])) { - $d = date_parse(convertDateToEnglish($_POST['start_datetime'])); + $d = date_parse(str_replace(',', '', convertDateToEnglish($_POST['start_datetime']))); if (!empty($d['error_count']) || !empty($d['warning_count'])) fatal_lang_error('invalid_date', false); if (empty($d['year'])) @@ -1572,16 +1572,16 @@ function setEventStartEnd($eventOptions = array()) // If some form of string input was given, override individually defined options with it if (isset($start_string)) { - $start_string_parsed = date_parse(convertDateToEnglish($start_string)); + $start_string_parsed = date_parse(str_replace(',', '', convertDateToEnglish($start_string))); if (empty($start_string_parsed['error_count']) && empty($start_string_parsed['warning_count'])) { - if ($start_string_parsed['year'] != false) + if ($start_string_parsed['year'] !== false) { $start_year = $start_string_parsed['year']; $start_month = $start_string_parsed['month']; $start_day = $start_string_parsed['day']; } - if ($start_string_parsed['hour'] != false) + if ($start_string_parsed['hour'] !== false) { $start_hour = $start_string_parsed['hour']; $start_minute = $start_string_parsed['minute']; @@ -1591,16 +1591,16 @@ function setEventStartEnd($eventOptions = array()) } if (isset($end_string)) { - $end_string_parsed = date_parse(convertDateToEnglish($end_string)); + $end_string_parsed = date_parse(str_replace(',', '', convertDateToEnglish($end_string))); if (empty($end_string_parsed['error_count']) && empty($end_string_parsed['warning_count'])) { - if ($end_string_parsed['year'] != false) + if ($end_string_parsed['year'] !== false) { $end_year = $end_string_parsed['year']; $end_month = $end_string_parsed['month']; $end_day = $end_string_parsed['day']; } - if ($end_string_parsed['hour'] != false) + if ($end_string_parsed['hour'] !== false) { $end_hour = $end_string_parsed['hour']; $end_minute = $end_string_parsed['minute']; diff --git a/Sources/Subs-Compat.php b/Sources/Subs-Compat.php index 5ab4c51bec..69aa512678 100644 --- a/Sources/Subs-Compat.php +++ b/Sources/Subs-Compat.php @@ -510,4 +510,34 @@ function idn_to_utf8($domain, $flags = 0, $variant = 1, &$idna_info = null) } } +/** + * Prevent fatal errors under PHP 8 when a disabled internal function is called. + * + * Before PHP 8, calling a disabled internal function merely generated a + * warning that could be easily suppressed by the @ operator. But as of PHP 8 + * a disabled internal function is treated like it is undefined, which means + * a fatal error will be thrown and execution will halt. SMF expects the old + * behaviour, so these no-op polyfills make sure that is what happens. + */ +if (version_compare(PHP_VERSION, '8.0.0', '>=')) +{ + /* + * This array contains function names that meet the following conditions: + * + * 1. SMF assumes they are defined, even if disabled. Note that prior to + * PHP 8, this was always true for internal functions. + * + * 2. Some hosts are known to disable them. + * + * 3. SMF can get by without them (as opposed to missing functions that + * really SHOULD cause execution to halt). + */ + foreach (array('set_time_limit') as $func) + { + if (!function_exists($func)) + eval('function ' . $func . '() { trigger_error("' . $func . '() has been disabled for security reasons", E_USER_WARNING); }'); + } + unset($func); +} + ?> \ No newline at end of file diff --git a/Sources/Subs-Editor.php b/Sources/Subs-Editor.php index cf205e9bec..5829f8e93e 100644 --- a/Sources/Subs-Editor.php +++ b/Sources/Subs-Editor.php @@ -1759,6 +1759,9 @@ function create_control_richedit($editorOptions) 'hr' => 'horizontalrule', ); + // Define this here so mods can add to it via the hook. + $context['disabled_tags'] = array(); + // Allow mods to modify BBC buttons. // Note: passing the array here is not necessary and is deprecated, but it is kept for backward compatibility with 2.0 call_integration_hook('integrate_bbc_buttons', array(&$context['bbc_tags'], &$editor_tag_map)); @@ -1778,6 +1781,12 @@ function create_control_richedit($editorOptions) $context['disabled_tags']['orderedlist'] = true; } + if ($tag === 'float') + { + $context['disabled_tags']['floatleft'] = true; + $context['disabled_tags']['floatright'] = true; + } + foreach ($editor_tag_map as $thisTag => $tagNameBBC) if ($tag === $thisTag) $context['disabled_tags'][$tagNameBBC] = true; @@ -1798,7 +1807,12 @@ function create_control_richedit($editorOptions) foreach ($tagRow as $tag) { - if ((!empty($tag['code'])) && empty($context['disabled_tags'][$tag['code']])) + if (empty($tag['code'])) + { + $context['bbc_toolbar'][$row][] = implode(',', $tagsRow); + $tagsRow = array(); + } + elseif (empty($context['disabled_tags'][$tag['code']])) { $tagsRow[] = $tag['code']; @@ -1829,11 +1843,6 @@ function create_control_richedit($editorOptions) $context['bbcodes_handlers'] .= ' });'; } - else - { - $context['bbc_toolbar'][$row][] = implode(',', $tagsRow); - $tagsRow = array(); - } } if (!empty($tagsRow)) @@ -2069,7 +2078,7 @@ function create_control_verification(&$verificationOptions, $do_test = false) $id_question = $row['id_question']; unset ($row['id_question']); // Make them all lowercase. We can't directly use $smcFunc['strtolower'] with array_walk, so do it manually, eh? - $row['answers'] = $smcFunc['json_decode']($row['answers'], true); + $row['answers'] = (array) $smcFunc['json_decode']($row['answers'], true); foreach ($row['answers'] as $k => $v) $row['answers'][$k] = $smcFunc['strtolower']($v); diff --git a/Sources/Subs-Graphics.php b/Sources/Subs-Graphics.php index cba018c549..7d86e08ba1 100644 --- a/Sources/Subs-Graphics.php +++ b/Sources/Subs-Graphics.php @@ -186,6 +186,8 @@ function reencodeImage($fileName, $preferred_format = 0) if (!rename($fileName . '.tmp', $fileName)) return false; + + return true; } /** diff --git a/Sources/Subs-Timezones.php b/Sources/Subs-Timezones.php index 03a5a285cc..84085758f3 100644 --- a/Sources/Subs-Timezones.php +++ b/Sources/Subs-Timezones.php @@ -486,7 +486,7 @@ function get_tzid_metazones($when = 'now') 'Pacific/Efate' => 'Pacific_Vanuatu', // No DST - 'Pacific/Enderbury' => 'Pacific_Phoenix_Islands', + 'Pacific/Kanton' => 'Pacific_Phoenix_Islands', // No DST 'Pacific/Fakaofo' => 'Pacific_Tokelau', @@ -1065,6 +1065,7 @@ function get_sorted_tzids_for_country($country_code, $when = 'now') 'KI' => array( 'Pacific/Tarawa', 'Pacific/Kiritimati', + 'Pacific/Kanton', 'Pacific/Enderbury', ), 'KM' => array( @@ -1617,6 +1618,12 @@ function get_tzid_fallbacks($tzids, $when = 'now') 'tzid' => 'Pacific/Truk', ), ), + 'Pacific/Kanton' => array( + array( + 'ts' => PHP_INT_MIN, + 'tzid' => 'Pacific/Enderbury', + ), + ), 'Pacific/Pohnpei' => array( array( 'ts' => PHP_INT_MIN, diff --git a/Sources/Subs.php b/Sources/Subs.php index 7992b4800f..dd5fd29a1a 100644 --- a/Sources/Subs.php +++ b/Sources/Subs.php @@ -849,18 +849,23 @@ function get_date_or_time_format($type = '', $format = '') array( // Anything that isn't a specification, punctuation mark, or whitespace. '~(?(\1|[^%\P{Po}])\s*(?!$))*~u', + // Repeated punctuation marks (except %), possibly separated by whitespace. + '~(?'.'>([^%\P{P}])\s*(?=\1))*~u', + '~([^%\P{P}])(?'.'>\1(?!$))*~u', // Unwanted trailing punctuation and whitespace. '~(?'.'>([\p{Pd}\p{Ps}\p{Pi}\p{Pc}]|[^%\P{Po}])\s*)*$~u', // Unwanted opening punctuation and whitespace. '~^\s*(?'.'>([\p{Pd}\p{Pe}\p{Pf}\p{Pc}]|[^%\P{Po}])\s*)*~u', + // Runs of horizontal whitespace. + '~\s+~', ), array( '', + '$1', '$1$2', '', '', + ' ', ), $format ); @@ -1740,7 +1745,7 @@ function parse_bbc($message, $smileys = true, $cache_id = '', $parse_tags = arra // parseAttachBBC will return a string ($txt key) rather than dying with a fatal_error. Up to you to decide what to do. if (is_string($currentAttachment)) - return $data = !empty($txt[$currentAttachment]) ? $txt[$currentAttachment] : $currentAttachment; + return $data = '' . (!empty($txt[$currentAttachment]) ? $txt[$currentAttachment] : $currentAttachment) . ''; // We need a display mode. if (empty($params['{display}'])) diff --git a/Themes/default/Display.template.php b/Themes/default/Display.template.php index ed2f47fead..bc76e1b136 100644 --- a/Themes/default/Display.template.php +++ b/Themes/default/Display.template.php @@ -783,7 +783,7 @@ function template_single_post($message) '; else echo ' - '; + '; echo ' '; diff --git a/Themes/default/Post.template.php b/Themes/default/Post.template.php index 15d7f68955..aaf6a19ed7 100644 --- a/Themes/default/Post.template.php +++ b/Themes/default/Post.template.php @@ -320,7 +320,7 @@ function addPollOption() echo '
- ', $txt['attached'], ': + ', $txt['attachments'], ':
@@ -349,7 +349,7 @@ function addPollOption() echo '
- ', $txt['attached'], ': + ', $txt['attachments'], ':
@@ -392,9 +392,6 @@ function addPollOption() echo '
-
- ', $txt['attach'], ': -
diff --git a/Themes/default/css/index.css b/Themes/default/css/index.css index 7075ba8e51..026d4fb2d4 100644 --- a/Themes/default/css/index.css +++ b/Themes/default/css/index.css @@ -2414,6 +2414,7 @@ dl { -webkit-hyphens: auto; -ms-hyphens: auto; hyphens: auto; + overflow-wrap: break-word; } .topic h4 { margin: 3px 0; @@ -3544,8 +3545,6 @@ ul.post_options li { height: 22px; } #post_settings, #postAttachment, #postAttachment2, #attachment_previews { - border-top: 1px solid #ddd; - margin: -1px 0 0 0; padding: 10px 0; } #postAttachment dd, #postAttachment2 dd { @@ -4197,6 +4196,7 @@ tr[id^='list_news_lists_'] textarea { .videocontainer video { object-fit: contain; background: black; + max-width: 100%; } .backtrace:not(:last-child) { diff --git a/Themes/default/languages/Post.english.php b/Themes/default/languages/Post.english.php index 44780c57d4..9876b20f08 100644 --- a/Themes/default/languages/Post.english.php +++ b/Themes/default/languages/Post.english.php @@ -78,10 +78,10 @@ $txt['reported_profile'] = 'Reported user'; $txt['report_following_user'] = 'The profile of "%1$s" at %2$s'; -$txt['attach_restrict_attachmentPostLimit'] = 'maximum total size %1$d KB'; -$txt['attach_restrict_attachmentPostLimit_MB'] = 'maximum total size %1$d MB'; -$txt['attach_restrict_attachmentSizeLimit'] = 'maximum individual size %1$d KB'; -$txt['attach_restrict_attachmentSizeLimit_MB'] = 'maximum individual size %1$d MB'; +$txt['attach_restrict_attachmentPostLimit'] = 'maximum total size %1$s KB'; +$txt['attach_restrict_attachmentPostLimit_MB'] = 'maximum total size %1$s MB'; +$txt['attach_restrict_attachmentSizeLimit'] = 'maximum individual size %1$s KB'; +$txt['attach_restrict_attachmentSizeLimit_MB'] = 'maximum individual size %1$s MB'; $txt['attach_restrict_attachmentNumPerPostLimit'] = '%1$d per post'; $txt['attach_restrictions'] = 'Restrictions:'; @@ -174,7 +174,7 @@ $txt['attach_folder_admin_warning'] = 'The path to the attachments directory (%1$s) is incorrect. Please correct it in the attachment settings area of your admin panel.'; $txt['attach_limit_nag'] = 'You have reached the maximum number of attachments allowed per post.'; $txt['attach_no_upload'] = 'There was a problem and your attachments could not be uploaded'; -$txt['attach_remaining'] = '%1$d attachments remaining'; +$txt['attach_remaining'] = '%1$d remaining'; $txt['attach_available'] = '%1$s KB available'; $txt['attach_kb'] = ' (%1$s KB)'; $txt['attach_0_byte_file'] = 'The file appears to be empty. Please contact your forum administrator if this continues to be a problem'; diff --git a/Themes/default/languages/Timezones.english.php b/Themes/default/languages/Timezones.english.php index a495bb70d0..6aade1254e 100644 --- a/Themes/default/languages/Timezones.english.php +++ b/Themes/default/languages/Timezones.english.php @@ -573,6 +573,7 @@ $txt['Pacific/Guadalcanal'] = 'Guadalcanal'; $txt['Pacific/Guam'] = 'Guam'; $txt['Pacific/Honolulu'] = 'Honolulu'; +$txt['Pacific/Kanton'] = 'Canton Island'; $txt['Pacific/Kiritimati'] = 'Kiritimati'; $txt['Pacific/Kosrae'] = 'Tofol'; $txt['Pacific/Kwajalein'] = 'Kwajalein'; diff --git a/Themes/default/languages/index.english.php b/Themes/default/languages/index.english.php index ed5b2d2a1d..4d0b7db389 100644 --- a/Themes/default/languages/index.english.php +++ b/Themes/default/languages/index.english.php @@ -887,7 +887,7 @@ // Inline attachments messages. $txt['attachments_not_enable'] = 'Attachments are disabled'; $txt['attachments_no_data_loaded'] = 'Not a valid attachment ID.'; -$txt['attachments_not_allowed_to_see'] = 'You cannot see attachments on this board.'; +$txt['attachments_not_allowed_to_see'] = 'You cannot view this attachment.'; $txt['attachments_no_msg_associated'] = 'No message is associated with this attachment.'; $txt['attachments_unapproved'] = 'Attachment is awaiting approval.'; diff --git a/Themes/default/scripts/smf_fileUpload.js b/Themes/default/scripts/smf_fileUpload.js index e3d4f80e42..9517e372d9 100644 --- a/Themes/default/scripts/smf_fileUpload.js +++ b/Themes/default/scripts/smf_fileUpload.js @@ -515,6 +515,9 @@ function smf_fileUpload(oOptions) { $('#attachment_previews').show(); + // Hide this, too. The progress bar does a better job. + $('.attach_available').remove(); + // Show the drag-and-drop instructions and buttons $('#drop_zone_ui').show(); diff --git a/cron.php b/cron.php index 07963203df..48732c3a40 100644 --- a/cron.php +++ b/cron.php @@ -103,6 +103,10 @@ require_once($sourcedir . '/Security.php'); require_once($sourcedir . '/Subs.php'); +// Ensure we don't trip over disabled internal functions +if (version_compare(PHP_VERSION, '8.0.0', '>=')) + require_once($sourcedir . '/Subs-Compat.php'); + // Create a variable to store some SMF specific functions in. $smcFunc = array(); diff --git a/index.php b/index.php index 18cb079c52..dfaffb1cf9 100644 --- a/index.php +++ b/index.php @@ -77,6 +77,10 @@ require_once($sourcedir . '/Load.php'); require_once($sourcedir . '/Security.php'); +// Ensure we don't trip over disabled internal functions +if (version_compare(PHP_VERSION, '8.0.0', '>=')) + require_once($sourcedir . '/Subs-Compat.php'); + // If $maintenance is set specifically to 2, then we're upgrading or something. if (!empty($maintenance) && 2 === $maintenance) { diff --git a/other/install.php b/other/install.php index a3551947c5..c27275d35c 100644 --- a/other/install.php +++ b/other/install.php @@ -35,6 +35,9 @@ require_once('Sources/Class-Package.php'); +if (version_compare(PHP_VERSION, '8.0.0', '>=')) + require_once('Sources/Subs-Compat.php'); + // Database info. $databases = array( 'mysql' => array( @@ -1293,7 +1296,7 @@ function DatabasePopulation() $current_statement = ''; // Wait, wait, I'm still working here! - set_time_limit(60); + @set_time_limit(60); } // Sort out the context for the SQL. diff --git a/other/install_2-1_mysql.sql b/other/install_2-1_mysql.sql index cd9cf71420..0f2922591e 100644 --- a/other/install_2-1_mysql.sql +++ b/other/install_2-1_mysql.sql @@ -735,7 +735,7 @@ CREATE TABLE {$db_prefix}members ( warning TINYINT NOT NULL DEFAULT '0', passwd_flood VARCHAR(12) NOT NULL DEFAULT '', pm_receive_from TINYINT UNSIGNED NOT NULL DEFAULT '1', - timezone VARCHAR(80) NOT NULL DEFAULT 'UTC', + timezone VARCHAR(80) NOT NULL DEFAULT '', tfa_secret VARCHAR(24) NOT NULL DEFAULT '', tfa_backup VARCHAR(64) NOT NULL DEFAULT '', PRIMARY KEY (id_member), diff --git a/other/install_2-1_postgresql.sql b/other/install_2-1_postgresql.sql index 69eb77a4c1..8607520c21 100644 --- a/other/install_2-1_postgresql.sql +++ b/other/install_2-1_postgresql.sql @@ -1103,7 +1103,7 @@ CREATE TABLE {$db_prefix}members ( warning smallint NOT NULL DEFAULT '0', passwd_flood varchar(12) NOT NULL DEFAULT '', pm_receive_from smallint NOT NULL DEFAULT '1', - timezone varchar(80) NOT NULL DEFAULT 'UTC', + timezone varchar(80) NOT NULL DEFAULT '', tfa_secret varchar(24) NOT NULL DEFAULT '', tfa_backup varchar(64) NOT NULL DEFAULT '', PRIMARY KEY (id_member) diff --git a/other/upgrade.php b/other/upgrade.php index bfbc22a9a6..b873620b16 100644 --- a/other/upgrade.php +++ b/other/upgrade.php @@ -115,7 +115,6 @@ $upcontext['database_step'] = 3; // Secure some resources -@set_time_limit(600); @ini_set('mysql.connect_timeout', -1); @ini_set('default_socket_timeout', 900); @ini_set('memory_limit', '512M'); @@ -689,6 +688,11 @@ function loadEssentialData() require_once($sourcedir . '/Subs.php'); + if (version_compare(PHP_VERSION, '8.0.0', '>=')) + require_once($sourcedir . '/Subs-Compat.php'); + + @set_time_limit(600); + $smcFunc['random_int'] = function($min = 0, $max = PHP_INT_MAX) { global $sourcedir; @@ -2634,7 +2638,6 @@ function cmdStep0() while (ob_get_level() > 0) ob_end_clean(); ob_implicit_flush(1); - @set_time_limit(600); if (!isset($_SERVER['argv'])) $_SERVER['argv'] = array(); diff --git a/other/upgrade_2-1_mysql.sql b/other/upgrade_2-1_mysql.sql index 8b4e4365d7..de13ca212b 100644 --- a/other/upgrade_2-1_mysql.sql +++ b/other/upgrade_2-1_mysql.sql @@ -2383,7 +2383,7 @@ ADD COLUMN modified_reason VARCHAR(255) NOT NULL DEFAULT ''; --- Adding timezone support /******************************************************************************/ ---# Adding the "timezone" column to the members table -ALTER TABLE {$db_prefix}members ADD timezone VARCHAR(80) NOT NULL DEFAULT 'UTC'; +ALTER TABLE {$db_prefix}members ADD timezone VARCHAR(80) NOT NULL DEFAULT ''; ---# ---# Converting time offset to timezone diff --git a/other/upgrade_2-1_postgresql.sql b/other/upgrade_2-1_postgresql.sql index cd72a8b3f7..1856792576 100644 --- a/other/upgrade_2-1_postgresql.sql +++ b/other/upgrade_2-1_postgresql.sql @@ -811,7 +811,12 @@ ADD COLUMN IF NOT EXISTS status smallint NOT NULL default '0', ADD COLUMN IF NOT EXISTS id_member_acted int NOT NULL default '0', ADD COLUMN IF NOT EXISTS member_name_acted varchar(255) NOT NULL default '', ADD COLUMN IF NOT EXISTS time_acted int NOT NULL default '0', -ADD COLUMN IF NOT EXISTS act_reason text NOT NULL; +ADD COLUMN IF NOT EXISTS act_reason text NOT NULL default ''; +---# + +---# Adding new columns to log_group_requests - drop defaults now that existing rows have been set +ALTER TABLE {$db_prefix}log_group_requests +ALTER COLUMN act_reason DROP DEFAULT; ---# ---# Adjusting the indexes for log_group_requests @@ -824,7 +829,12 @@ CREATE INDEX {$db_prefix}log_group_requests_id_member ON {$db_prefix}log_group_r /******************************************************************************/ ---# Adding support for tag in package manager ALTER TABLE {$db_prefix}log_packages -ADD COLUMN IF NOT EXISTS credits TEXT NOT NULL; +ADD COLUMN IF NOT EXISTS credits TEXT NOT NULL default ''; +---# + +---# Adding support for - drop default now that existing rows have been set +ALTER TABLE {$db_prefix}log_packages +ALTER COLUMN credits DROP DEFAULT; ---# ---# Adding support for package hashes @@ -2616,7 +2626,7 @@ ADD COLUMN IF NOT EXISTS modified_reason varchar(255) NOT NULL default ''; --- Adding timezone support /******************************************************************************/ ---# Adding the "timezone" column to the members table -ALTER TABLE {$db_prefix}members ADD IF NOT EXISTS timezone VARCHAR(80) NOT NULL DEFAULT 'UTC'; +ALTER TABLE {$db_prefix}members ADD IF NOT EXISTS timezone VARCHAR(80) NOT NULL DEFAULT ''; ---# ---# Converting time offset to timezone diff --git a/proxy.php b/proxy.php index 51785f6b6d..f650deb31f 100644 --- a/proxy.php +++ b/proxy.php @@ -81,6 +81,10 @@ public function __construct() require_once(dirname(__FILE__) . '/Settings.php'); require_once($sourcedir . '/Subs.php'); + // Ensure we don't trip over disabled internal functions + if (version_compare(PHP_VERSION, '8.0.0', '>=')) + require_once($sourcedir . '/Subs-Compat.php'); + // Make absolutely sure the cache directory is defined and writable. if (empty($cachedir) || !is_dir($cachedir) || !is_writable($cachedir)) { diff --git a/subscriptions.php b/subscriptions.php index db20796cc6..0a022bc1cb 100644 --- a/subscriptions.php +++ b/subscriptions.php @@ -28,6 +28,10 @@ // For any admin emailing. require_once($sourcedir . '/Subs-Admin.php'); +// Ensure we don't trip over disabled internal functions +if (version_compare(PHP_VERSION, '8.0.0', '>=')) + require_once($sourcedir . '/Subs-Compat.php'); + loadLanguage('ManagePaid'); // If there's literally nothing coming in, let's take flight!