Tried claude to make t to run in latest version of PHP. #203
Open
akshyin-v2 wants to merge 56 commits into
Open
Tried claude to make t to run in latest version of PHP. #203akshyin-v2 wants to merge 56 commits into
akshyin-v2 wants to merge 56 commits into
Conversation
In PHP 8+, referencing an undefined constant is a fatal error.
During installation, config.inc.php does not yet exist, so AT_CONTENT_DIR
is undefined when constants.inc.php is loaded from not_installed.php.
Guard WORKSPACE_FILE_PATH and AT_BACKUP_DIR definitions with
defined('AT_CONTENT_DIR') checks to prevent the installer from crashing.
get_magic_quotes_gpc() was removed in PHP 7.0 and causes a fatal error in PHP 8. Guard the call with function_exists() so the installer and runtime proceed correctly on modern PHP versions where magic quotes no longer exist.
- Add a 'System Requirements' section to README.md listing PHP extensions including mbstring, which is strongly recommended and required for upgrades. - Update the installer warning message to show the Debian/Ubuntu command for installing php-mbstring, making it easier for users to resolve.
- queryDButf8: give defaults to $sanitize and $db so optional params are not declared before required ones (deprecated in PHP 8). - common.inc.php: guard $msg and $savant with isset() checks; fix undefined array key $_POST['old_path']. - header.php: guard $step with isset() before comparison. - index.php: prevent redefining MYSQLI_ENABLED by adding !defined() guard.
In sqlutility.class.php:200, queryDB() was called for a CREATE TABLE statement with oneRow=false, returning a boolean/resource rather than an array. count() on a non-array throws TypeError in PHP 8. Replace count() > 0 with !== false to correctly check query success for DDL statements.
MYSQL_ASSOC was removed in PHP 8 along with the old mysql extension. Change the default $array_type in queryDButf8() from MYSQL_ASSOC to MYSQLI_ASSOC to match queryDB() and prevent a fatal Error.
In install.inc.php:462, queryDButf8() was called with $db_name (a string) as the $params argument, but vsprintf() inside queryDButf8() requires an array. Wrap $db_name in array() to match the correct call pattern used on line 466.
Add validation in step2.php to ensure required database fields (db_host, db_port, db_login, db_name) are not empty before calling create_and_switch_db(). Prevents 'Incorrect database name' errors when the form is submitted with missing values.
- Add an early guard in create_and_switch_db() to return a clear error when $db_name is empty instead of letting MySQL throw a fatal exception. - Harden step2.php to only process database setup when $_POST['db_name'] is actually present (not just when $_POST['submit'] exists). This prevents the installer from crashing when first loading step 2 after agreeing to terms.
In the installer, $db is passed as a local parameter, but $addslashes (set to my_add_null_slashes) relies on global $db which is null in that context. This causes real_escape_string to receive null, producing an empty string, which makes vsprintf generate SHOW CREATE DATABASE and MySQL rejects it. In queryDButf8(), since we already have $db as a parameter, bypass the $addslashes closure and call $db->real_escape_string() directly. This removes the dependency on global state and fixes the installer crash. Also removes temporary debug logging.
- install.php:22: ['new_version'] may not be set on Step 3, causing an undefined array key warning. Guard with isset() and provide fallback. - install.inc.php:172: INSERT into members used '0000-00-00' as dob, which MySQL 5.7+ / MariaDB rejects under strict mode (NO_ZERO_DATE). Replace with '1900-01-01' so the account creation succeeds.
The installer's INSERT into %smembers set last_login to NULL, but the schema defines last_login as TIMESTAMP NOT NULL. Under MySQL strict mode this throws a 'Column cannot be null' error. Use NOW() instead of NULL to match the admins INSERT and satisfy the NOT NULL constraint.
- install/index.php: Guard gd_info() JPG/JPEG Support keys with isset(). - install/install.php: Guard $_POST['step'] and $_POST['submit'] with isset(). - install/include/step2.php: Guard $_POST['db_login'] and $_POST['db_password'] before htmlspecialchars() to avoid null deprecation warnings. - install/include/common.inc.php: Guard $_POST['step'.] with isset() in print_hidden(), and add missing $_defaults['email'] key. - install/include/step3.php: Guard $_POST['action'], $_POST['upgrade_action'], and $_POST['just_social'] with isset() checks.
…ariables, and fsockopen deadlocks - Fix stray backslashes before $ variables causing parse errors in install/index.php and install/include/step2.php - Add missing initialization and type guards for $svn_data in install/include/step6.php to prevent TypeError on count(null) - Fix fsockopen self-deadlock in install/include/step4.php when running PHP built-in single-threaded server - Fix MySQL TIMESTAMP NOT NULL without default in schema causing strict mode INSERT failures - Update mysqli connection logic and add diagnostics for install hangs - Fix undefined array key and null value warnings in installer forms
…ce string offsets, and time() argument count
…and each() removal; add new Modern theme
- Fix fatal error: ATutor.setcookie() is not valid PHP; use setcookie() - Fix undefined $last_login when auto-login is disabled - Fix undefined array key users/profile.php in profile_pictures module Co-Authored-By: Claude <noreply@anthropic.com>
Refactor the themes/modern/ template system to deliver a modern Bootstrap-based look & feel, with all CSS/JS/fonts stored locally (no CDN). - Bundle Bootstrap 5.3.8 (css + js bundle w/ Popper) and Bootstrap Icons 1.11.3 (css + woff2/woff) under themes/modern/lib/ for a fully offline install. - Rewrite header/footer/index .tmpl.php to use Bootstrap 5 components (navbar, nav nav-underline, breadcrumb, nav-pills, card grid, container-fluid, form-select, btn, pagination, alert, badge, bi-* icons). All legacy element IDs/classes are preserved so ATutor.js, scroll-to-fixed and subnav-toggle keep working. - Rewrite modern-overrides.css to compose on top of Bootstrap, rebinding --bs-primary to the modern palette and mapping legacy IDs to Bootstrap design tokens, with a responsive breakpoint. - Register the 'modern' theme in the atutor_schema.sql themes seed (it existed only on disk and never appeared in the picker) and bump theme_info.xml to "Modern (Bootstrap 5)" v1.1. Legacy jQuery 1.6.1 / Infusion scripts are intentionally kept loaded alongside Bootstrap 5, because ATutor.js, jquery-ui, jquery.switch, jquery.cookie, jquery-scrolltofixed and TinyMCE all depend on jQuery; removing it would break the app. Bootstrap 5 itself is jQuery-free. The 15 legacy themes are untouched. Co-Authored-By: Claude <noreply@anthropic.com>
…ault The enhanced interface was not showing because Bootstrap's global .row grid rules were clobbering ATutor's ~500 legacy .row form rows (turning them into flex grids with gutter padding), and modern-overrides.css was loaded before forms.css so legacy form styles won. Fixes: - Load order: modern-overrides.css now loads LAST (after styles.css and forms.css) so it is authoritative. - Neutralise Bootstrap's .row and .row > * in modern-overrides.css so legacy form rows keep their block layout. - Replace Bootstrap row/col-* grid classes in header.tmpl.php and index.tmpl.php with non-colliding custom classes (.at-content-grid, .at-side-col, .at-main-col, .at-card-grid, .at-card-item) so the refactored layout no longer depends on the colliding .row. - Comprehensively restyle every legacy content class in modern-overrides.css (.input-form cards, fieldset.group_form / legend.group_form, .formfield, .button/.buttons, .required, .contentbox/.headingbox, .data tables, .paginator, .sort, .box, .contentrow, social/profile/photo widgets, etc.) so all 221 sub-templates get a cohesive modern Bootstrap-consistent look at once. - Make the modern theme the default desktop theme (status 2) and demote the legacy default to enabled (status 1). Default remains the Savant inheritance fallback, so legacy sub-templates still resolve. Templates render verified via a Savant2 harness (31 KB output, all Bootstrap CSS/JS/Icons + custom grids + nav/breadcrumb/footer present, no new template-level errors). Co-Authored-By: Claude <noreply@anthropic.com>
Rewrite themes/modern/login.tmpl.php to use Bootstrap 5 (cards, card-header/card-body, form-control, form-label, btn btn-primary / btn-outline-primary, d-grid, d-flex responsive layout, Bootstrap Icons) for a modern login look. All PHP logic preserved: sha1 password challenge (sha-1factory.js + encrypt_password + session token), hidden form fields, AT_EMAIL_CONFIRMATION notice, and registration gating. Added a missing isset() guard on $_GET['course'] (PHP 8 notice fix). Add `global $_config;` in the template so the "New User" registration card reliably renders -- Savant2 renders templates in method scope, so the global $_config (built by vitals.inc.php) is not auto-visible and the original if($_config['allow_registration']==1) evaluated against an undefined var, hiding the card on the legacy login page. Add a login-specific rule block to modern-overrides.css so the fieldset.group_form inside the login cards does not render as a nested box (it is meant for collapsible sections elsewhere). Validated via a Savant2 render harness (production-realistic scope): both cards render, all Bootstrap component classes present, sha1 JS and session token flow through, hidden fields emitted, zero PHP notices/warnings. Co-Authored-By: Claude <noreply@anthropic.com>
The Language class used a PHP4-style constructor (function Language(...)).
PHP 8.3 no longer invokes methods named the same as the class as a
constructor, so every Language object was created with an empty $code.
getMyLanguage() then saved an empty code into $_SESSION['lang'], and _AT()
queried language_code="" -> no rows matched -> it fell back to printing
sprintf('[ %s ]', $term) for every label (login, register, returning_user,
AT_FEEDBACK_LOGOUT, etc.).
Rename the constructor to __construct() and update the one explicit caller
(LanguageEditor::__construct called $this->Language(); now parent::__construct()).
Co-Authored-By: Claude <noreply@anthropic.com>
AT_DEVEL was set to 1, which gates several page-rendered diagnostics: the footer debug box (TIME USED, TABLE_PREFIX, DB_NAME, VERSION, SESSION:, CONFIGURATION) that print_r's $_SESSION and $_config into the HTML, the (term_name) suffixes appended to feedback messages, and raw SQL/DB errors in failed-query messages. None of these gate required functionality. Set AT_DEVEL to 0. Console error_log diagnostics are independent of AT_DEVEL and remain intact. Co-Authored-By: Claude <noreply@anthropic.com>
- Responsive two-card grid (side-by-side on md+, stacked on mobile) - Gradient card headers with circular icon chips - Input-group icons for login and password fields - Password show/hide toggle (type=button so it never submits; sha1 encrypt_password() flow unchanged) - "Forgot your password?" link inline with the password label - Course-context banner when ?course= is set - Hover lift/shadow micro-interactions; registration button fills on hover - Secure-login footer note with site name All functional pieces preserved: encrypt_password() sha1 logic, hidden fields (form_login_action, form_course_id, form_password_hidden, p), field names, form action, autofocus via $onload. Co-Authored-By: Claude <noreply@anthropic.com>
The default site chrome (near-black top bar, blue header gradient, blue nav states) plus the blue login cards/buttons made the login page feel heavy and high-contrast. Add an at-login-page body class (set in header.tmpl.php when PHP_SELF is login.php) and scope a calmer palette to it in modern-overrides.css: - body background: soft warm cream-to-sage gradient - top bar: muted dark sage-slate instead of near-black - header bar + nav active states: muted sage-teal instead of blue - login card primary header + button: sage-teal - registration card header: warm sand with a sage icon chip - borders, muted text, input icon chips recoloured to warm/sage tones Scoped to the login page only; the rest of the site keeps its default colours. Co-Authored-By: Claude <noreply@anthropic.com>
Adapt the design tokens from freelearnerchoice.org and apply them to the modern (default) theme. Because the theme is token-driven, remapping the :root variables recolours the whole site at once. Design tokens (themes/modern/modern-overrides.css :root): - --at-primary: #2563eb -> #0EA5E9 (sky) - --at-accent: #0ea5e9 -> #f97316 (warm orange CTA) + hover/light/rgb - --at-dark: #0f172a -> #0C4A6E (deep navy, softer than near-black) - --at-bg: #f4f6fb -> #F0F9FF (light sky) - --at-text: #1e293b -> #075985; new --at-text-head #0C4A6E - radii 8/14px, new --at-font Inter stack Chrome & components: - Header band: signature deep-navy -> sky gradient (var(--at-dark) -> --at-dark-2 -> --at-primary), replacing the flat indigo->cyan. - Top bar uses the new navy; jump menu recoloured to match. - Headings navy + 700 + -0.01em; body uses Inter. - Login primary card header sky gradient; registration card header warmed to a soft orange tint with an orange icon chip. Inter font loaded via Google Fonts in header.tmpl.php (falls back to system-ui offline). A new at-login-page body class is added on the login page (basename(PHP_SELF) === 'login.php') for future scoping. Warm-orange CTA on key primary actions (matches the reference site): - New reusable .at-cta class (orange bg/border + glow, hover lift). - Applied to: login submit, registration "login" + create-account "save", password reminder submit, password change submit. - Default .btn-primary/.button stay sky (brand) so the LMS is not overwhelmed with orange; only the key CTAs are orange. The earlier login-only "sage" palette experiment is removed in favour of this global sky+orange system. Co-Authored-By: Claude <noreply@anthropic.com>
The LearnerChoice rebrand (prev commit) added an external Google Fonts request for Inter, breaking the modern theme's fully-offline property. Replace it with a local bundle, matching how Bootstrap/Bootstrap-Icons are already bundled. - themes/modern/lib/inter/: 7 variable-font woff2 files (one per unicode-range subset — latin, latin-ext, cyrillic, cyrillic-ext, greek, greek-ext, vietnamese; weights 300-800; ~218 KB total) plus a generated inter.css with @font-face blocks preserving the per-subset unicode-ranges so all scripts render. Files downloaded from Google Fonts' gstatic CDN. - header.tmpl.php: $_inter_url = $_theme_url.'/lib/inter'; load <link href="$_inter_url/inter.css"> instead of the three Google Fonts links (preconnect x2 + stylesheet). No external request remains. Verified: render of login.php references the local inter.css, zero fonts.googleapis.com/gstatic references in head, header.tmpl.php lints clean, all woff2 files have valid 'wOF2' magic. Co-Authored-By: Claude <noreply@anthropic.com>
queryDB() runs vsprintf(), which converts PHP NULL to an empty string,
so a missing release_date/end_date produced release_date='' — rejected
by MySQL strict mode for datetime columns ('Incorrect datetime value').
Build the column fragment directly so an unset date emits the unquoted
NULL keyword instead of an empty string.
Co-Authored-By: Claude <noreply@anthropic.com>
The application assigns NULL when an instructor leaves the release/end date blank, but the schema declared both columns datetime NOT NULL with no default. With the insert now correctly emitting the NULL keyword (prior commit), MySQL rejected it with 'Column release_date cannot be null' (sqlstate 23000). Make both columns nullable to match the app's optional-date semantics. Co-Authored-By: Claude <noreply@anthropic.com>
initContent() is called right after a new course is created (before the default welcome page is added), when the content table has no rows for the course yet. $_menu stays empty, so count($_menu[0]) becomes count(null) — a fatal TypeError on PHP 8 (only a notice on PHP 7). The same crash hits any empty course on every page load, since vitals.inc.php constructs ContentManager and calls initContent() when a course context is active. Skip the ordering walk and set safe defaults when there is no content. Co-Authored-By: Claude <noreply@anthropic.com>
PHP 8 removed the __autoload() magic function; defining it (even inside a dead else-branch for PHP < 5.1.2) raises a compile-time fatal '__autoload() is no longer supported, use spl_autoload_register() instead' when Autoload.php is included, 500-ing every page. SPL autoloading is available in all supported PHP versions, so drop the version check and register unconditionally. Co-Authored-By: Claude <noreply@anthropic.com>
ReflectionClass::newInstanceArgs() now treats associative-array string
keys as named constructor parameters (PHP 8.0+). The call passed
array('StdClass' => $data), but the model constructors declare $stdClass
(lowercase d), so PHP 8 raised 'Unknown named parameter $StdClass' and
500'd every page during module load. Pass $data positionally instead,
which matches the pre-PHP 8 behaviour (the string key was ignored then).
Co-Authored-By: Claude <noreply@anthropic.com>
Two issues in the gameme module, both surfaced when executeEvent() ran on page load: 1. gm_user_events.points_counter (and event_counter) were int NOT NULL with no default. increaseEventCounter() inserts event_counter=1 but omits points_counter, so MySQL strict mode rejected the row with 'Field points_counter doesn't have a default value' (errno 1364), 500-ing the page. Add DEFAULT '0' to both counter columns (module.sql) and ALTER the live table. 2. PHP 8 emits an E_WARNING 'Undefined array key' for $this->eventsTriggers[$alias] when the event has no triggers; the following null check already handles that case, so use ?? null to silence the warning. Co-Authored-By: Claude <noreply@anthropic.com>
- securimage.php: PHP 8 removed curly-brace string/array offset access
($this->code{$i}, $this->charset{...}, $code{$i}). This was a compile
fatal that 500'd registration.php (CAPTCHA rendering). Use [] syntax.
- tile_search/module.php: $_config['transformable_uri'] is undefined
when the Transformable service isn't configured; PHP 8 warns on the
undefined array key during define(). Null-coalesce to ''.
- blogs/module.php: $_SESSION['is_admin'] may be unset; PHP 8 warns on
the undefined key in the comparison. Null-coalesce to 0.
Co-Authored-By: Claude <noreply@anthropic.com>
Rebuild themes/modern/registration.tmpl.php with the same Bootstrap-5 card chrome as the recently-redesigned login page: an orange 'new user' gradient header with an icon chip, grouped Required/Personal sections shown as bordered fieldset cards, a 2-column CSS-grid field layout that stacks on narrow viewports, input-group icon chips, a styled CAPTCHA box (Bootstrap Icons replacing the old GIF links), and a right-aligned action row (orange Save CTA + neutral Cancel). The returning-user login form is restyled as a toggleable sky card. Markup/CSS only — every form name, hidden input, field name/id, POST echo, JS handler (encrypt_password, encrypt_password_login, show_login_form), and conditional block (master list, admin account status/picture, captcha, auto-enroll, logged-in confirm exit) is preserved unchanged. Add a scoped '8c. REGISTRATION PAGE' section to modern-overrides.css reusing existing sky/orange tokens (no new palette values); rules are namespaced under .at-register-* / .at-register-card.at-login-card so the login page is unaffected. Co-Authored-By: Claude <noreply@anthropic.com>
Registration (and profile create/edit) write dob='0000-00-00' when no date
of birth is supplied, but MySQL strict mode with NO_ZERO_DATE/NO_ZERO_IN_DATE
rejects it: 'Incorrect date value: 0000-00-00 for column dob'. The app's data
model uses '0000-00-00' as the 'no date' sentinel throughout — edit pages
read it back with explode('-', $row['dob']) and templates check
!= '0000-00-00' — so switching the column to NULL would require rewriting
~12 read/write/display sites and would surface PHP 8 explode(null) warnings.
Instead, align the session sql_mode with the app's existing design in the
single connection path (at_db_connect): drop only NO_ZERO_DATE and
NO_ZERO_IN_DATE, preserving every other server mode (notably
STRICT_TRANS_TABLES, which still catches genuinely empty values for NOT
NULL columns — the class fixed for courses.release_date/end_date). This
resolves dob and any other date column using the same sentinel, with no
per-file changes. Verified the adjusted mode accepts '0000-00-00' into a
date NOT NULL column and that the registration page still renders cleanly.
Co-Authored-By: Claude <noreply@anthropic.com>
execute_sql() raised a 'DB_QUERY' message (translation has 3 %s placeholders) whenever a query returned a bool result with $oneRow=TRUE. For a SUCCESSFUL INSERT/UPDATE/DELETE/REPLACE, $displayErrorMessage was still just ['DB_QUERY', date] (1 argument) — the error/sql args are only appended in the failure else-branch — so the queued message had 1 arg vs. 3 placeholders. PHP 8's vsprintf throws ValueError for too few arguments (PHP 7 silently substituted empty strings), fataling the page when the message was later printed (e.g. on the next GET /registration.php). - mysql_connect.inc.php: a bool/null result is a non-SELECT query; a failure (false/null) is already reported in the else-branch, and a success (true) must NOT raise a spurious 'unable to access the database' error. Drop the bogus addError for the oneRow+bool path. - Message.class.php: pad the arguments array to the format's placeholder count before vsprintf, so any other translation/caller arg-count mismatch degrades gracefully instead of 500ing the page. Co-Authored-By: Claude <noreply@anthropic.com>
members.last_login is TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, so the explicit NULL inserted by registration (and admin create_user) was rejected with 'Column last_login cannot be null'. The app's 'never logged in' sentinel is the zero datetime, not NULL: mods/_core/users/users.php filters never-logged-in users with 'last_login+0=0'. Insert '0000-00-00 00:00:00' instead, which (a) is accepted now that the session sql_mode drops NO_ZERO_DATE and (b) keeps last_login+0=0 so the admin filter still works. The non-confirmation registration path already overwrites it with now() immediately after. Co-Authored-By: Claude <noreply@anthropic.com>
PHP 8 made undefined constants a fatal Error (PHP 7 treated barewords like LOGIN_SUCCESS_AUTO_ENROLL as the string itself). registration.php used bareword message codes and bareword array keys outside of string interpolation: - array(AUTO_ENROLL_ALREADY_ENROLLED, ...) and array(LOGIN_SUCCESS_AUTO_ENROLL, ...) in addInfo/addFeedback (lines 43, 50, 335) — quote the message codes. - $_POST[login] and $_SESSION[lang] outside strings (lines 341, 344) — quote the array keys. (Bareword keys inside the double-quoted INSERT SQL are fine; PHP interpolates them as strings.) Co-Authored-By: Claude <noreply@anthropic.com>
…nd core - registration.php: guard $_POST['gender'] with isset(); quote bareword $_config[pref_defaults] (PHP 8 fatal) - auto_enroll_courses.inc.php: initialize $course_names and $course_registered_names outside the en_id block - vital_funcs.inc.php: isset-guard $_SESSION['course_id'], 'is_admin', 'privileges', 'cid_time', and 'member_id' - login_functions.inc.php: null-coalesce $_POST['form_login'] - header.inc.php: isset-guard 'course_id' and 'is_admin' checks - modern/header.tmpl.php: guard foreach over nav_courses when null - 17 module files: isset-guard $_SESSION['is_admin'] before comparison - helpme/module.php + helpme_js.php: initialize $helpme_total; guard 'valid_user', 'course_id', 'member_id', and 'is_admin' - gameme/module.php: guard 'valid_user'; early-return gamemeEnabled() when course_id is absent - PhotoAlbum.class.php: initialize group_albums1, course_albums1, my_albums1, and rows_clean; isset-guard $_SESSION['groups'] and 'member_id' Co-Authored-By: Claude <noreply@anthropic.com>
…RCE, SQLi, SSRF/LFI, missing auth - gameme/upload_level_icon.php, upload_badge.php: restrict uploads to images, validate with getimagesize(), use safe uniqid filenames, add auth check - gameme/save_event.php, save_badge.php, save_level.php: add authenticate() - get_course_icon.php: restore realpath-based path validation for custom/stock icons - Module.class.php: replace eval() with call_user_func() to prevent RCE - mysql_connect.inc.php: escape db_name in at_is_db() to prevent SQLi - content.php: restrict file_get_contents to AT_CONTENT_DIR to prevent SSRF/LFI Co-Authored-By: Claude <noreply@anthropic.com>
… XSS - bounce.php: strengthen open-redirect validation to block protocol-relative URLs (//evil.com) and non-HTTP schemes (javascript:, data:, ftp:) - accessibility.php: use sanitized in unlink() and hidden input to prevent path traversal; also sanitize cid in hidden form field - custom_logo.php: escape custom_logo_alt_text and custom_logo_url with htmlspecialchars() before outputting in HTML attributes to prevent stored XSS Co-Authored-By: Claude <noreply@anthropic.com>
- login_functions.inc.php: remove attacker-controlled CSRF token override (POST['token'] could set the session token to any value, bypassing CSRF protection entirely). Token is now generated server-side only. - login_functions.inc.php: validate redirect target after login to block absolute URLs and protocol-relative URLs (open redirect via POST['p']). - All 11 theme footer templates: escape custom_logo_url and custom_logo_alt_text with htmlspecialchars() before echoing into HTML attributes, preventing stored XSS from database/config values. Co-Authored-By: Claude <noreply@anthropic.com>
- zip.php: escape pathext, file, popup, framed GET parameters with htmlspecialchars/intval before echoing into hidden form fields - new.php: escape pathext REQUEST parameter - rename.php: escape pathext, oldname, new_name with htmlspecialchars; cast framed/popup to int - preview_top.php: use ENT_QUOTES when escaping file name to ensure single quotes are also encoded in href attributes Co-Authored-By: Claude <noreply@anthropic.com>
…l error write_to_log() was inserting NULL for the time column, which is NOT NULL. Replace with NOW() so admin login logging works again. Co-Authored-By: Claude <noreply@anthropic.com>
- Replace create_function() with closures/anonymous functions
- Replace split() with preg_split()
- Replace eregi() with preg_match('/i')
Co-Authored-By: Claude <noreply@anthropic.com>
Prevent continued script execution after redirects in nusoap WSDL handler and group manual creation. Co-Authored-By: Claude <noreply@anthropic.com>
Add is_array() checks before implode() on checkbox arrays. Prevents fatal error when form fields are manipulated or omitted. Co-Authored-By: Claude <noreply@anthropic.com>
Prevents LFI if an attacker manipulates the uploaded file tmp_name through crafted multipart requests or extract() abuse. Co-Authored-By: Claude <noreply@anthropic.com>
Prevents PHP 8 fatal errors in phpmailer, nusoap, and PEAR Config. Co-Authored-By: Claude <noreply@anthropic.com>
get_group_concat() passed '' as params to queryDB, but vsprintf() expects an array. Causes TypeError: vsprintf(): Argument atutor#2 must be of type array, string given. Co-Authored-By: Claude <noreply@anthropic.com>
README.md: - Raise minimum PHP to 8.0+ (tested up to 8.3) - Replace 'mysql' with 'mysqli' as the required extension - Promote mbstring from recommended to required - Add note about MySQL strict mode support - Add Compatibility & Known Issues section documentation/admin/requirements_recommendations.php: - Update PHP requirement from 5.0.2 to 8.0+ - Mark mysqli as required and mysql as removed - Mark mbstring as required - Remove obsolete safe_mode, register_globals, magic_quotes_* - Update MySQL requirement to 5.7+/MariaDB 10.2+ documentation/developer/guidelines.html: - Update portable code minimum from PHP 5.0.2 to 8.0 - List removed functions (mysql_*, eregi, split, each, create_function) Co-Authored-By: Claude <noreply@anthropic.com>
- enrollment.inc.php: guard undefined $_GET['reset_filter'], $_GET['search'] - enrollment.inc.php: guard undefined $_POST['view_select'] with null coalescing - enrollment.inc.php: initialize $page_string before string concatenation - mysql_connect.inc.php: guard foreach() with is_array($params) in both queryDButf8() and create_sql() to prevent foreach on string fatal Co-Authored-By: Claude <noreply@anthropic.com>
Prevents PHP 8 fatal errors when queryDB returns a non-array (e.g., affected_rows integer on error paths) by guarding foreach loops in core include files. Co-Authored-By: Claude <noreply@anthropic.com>
- Update atutor_schema.sql: time column now defaults to CURRENT_TIMESTAMP - Add upgrade SQL atutor_upgrade_2.2.4_to_2.2.5.sql for existing installs - Simplify write_to_log() to omit explicit NOW() and rely on DB default Co-Authored-By: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
statisfied with the improvement. Let me know if there is ok.