Skip to content

Latest commit

 

History

History
1636 lines (1242 loc) · 69.1 KB

File metadata and controls

1636 lines (1242 loc) · 69.1 KB

Nuked-Klan PHP 8.0 Migration Guide - Complete Technical Documentation

Overview

This document provides complete technical documentation of the migration of Nuked-Klan CMS v1.7.15 from PHP 5.x to PHP 8.0, including all fixes applied, issues encountered, and solutions implemented.

Migration Date: January 15, 2026
Status:COMPLETE - Website fully functional on PHP 8.0
PHP Version: 8.0.30 (PHP-FPM)
Target Environment: Your server environment, Nginx, MySQL


Migration Summary

Original Setup

  • Old Version: Nuked-Klan 1.7.9 (PHP 5.x)
  • Location: /path/to/your/webroot/
  • Database: Lost (recreated fresh)
  • Customizations: Any custom themes or modifications from the original installation

New Setup

  • Version: Nuked-Klan 1.7.15 (patched for PHP 8.0)
  • Location: /path/to/your/webroot/
  • Database: your_database_name (fresh installation)
  • Table Prefix: nuked
  • Admin Account: YourUsername (level 9)

All PHP 8.0 Compatibility Fixes Applied

1. MySQL Extension Deprecation

Problem: PHP 8.0 removed the deprecated mysql_* functions.

Solution: Created a comprehensive MySQLi compatibility layer.

Files Created:

  • Includes/mysqli_compat.php (NEW - 300+ lines)

Files Modified:

  • index.php - Added include_once('Includes/mysqli_compat.php');
  • INSTALL/index.php - Added require_once dirname(__DIR__) . "/Includes/mysqli_compat.php";

Functions Implemented:

  • mysql_connect()mysqli_connect()
  • mysql_select_db()mysqli_select_db()
  • mysql_query()mysqli_query()
  • mysql_fetch_array()mysqli_fetch_array()
  • mysql_fetch_assoc()mysqli_fetch_assoc()
  • mysql_fetch_row()mysqli_fetch_row()
  • mysql_num_rows()mysqli_num_rows()
  • mysql_affected_rows()mysqli_affected_rows()
  • mysql_result() → Custom implementation using mysqli_data_seek()
  • mysql_real_escape_string()mysqli_real_escape_string()
  • mysql_escape_string() → Alias for mysql_real_escape_string()
  • mysql_error()mysqli_error()
  • mysql_errno()mysqli_errno()
  • mysql_close()mysqli_close()
  • mysql_insert_id()mysqli_insert_id()
  • mysql_free_result()mysqli_free_result()
  • mysql_data_seek()mysqli_data_seek()
  • mysql_set_charset()mysqli_set_charset() (NEW)
  • mysql_get_server_info()mysqli_get_server_info() (NEW)

2. Magic Quotes Functions Deprecation

Problem: get_magic_quotes_gpc() and set_magic_quotes_runtime() removed in PHP 7.4+.

Files Modified:

  • globals.php
    • Removed get_magic_quotes_gpc() check
    • Removed set_magic_quotes_runtime(0) call
    • Updated SecureVar() function to always apply addslashes()

3. strftime() Deprecation (PHP 8.1)

Problem: strftime() deprecated in PHP 8.1.

Solution: Created nk_strftime() compatibility function using IntlDateFormatter.

Files Modified:

  • nuked.php
    • Added nk_strftime() function with IntlDateFormatter fallback
    • Replaced all strftime() calls with nk_strftime()

4. utf8_encode() Deprecation (PHP 8.2)

Problem: utf8_encode() deprecated in PHP 8.2.

Solution: Created nk_utf8_encode() compatibility function using mb_convert_encoding.

Files Modified:

  • nuked.php
    • Added nk_utf8_encode() function
    • Replaced all utf8_encode() calls with nk_utf8_encode()

5. Curly Brace Array Access (PHP 8.0)

Problem: $array{index} syntax removed in PHP 8.0.

Files Modified:

  • INSTALL/includes/class/process.class.php (line 772)
    • Changed: $charPool{mt_rand(0, $poolLength)}
    • To: $charPool[mt_rand(0, $poolLength)]

6. Required Parameter After Optional (PHP 8.0)

Problem: Required parameter $callbackUpdateFunction follows optional $fieldId.

Files Modified:

  • INSTALL/includes/class/dbTable.class.php (line 519)
    • Changed: applyUpdateFieldListToData($fieldId = 'id', $callbackUpdateFunction)
    • To: applyUpdateFieldListToData($callbackUpdateFunction, $fieldId = 'id')
  • INSTALL/tables/*.php (28 files)
    • Updated all function calls to match new parameter order

7. Undefined Array Key Warnings (PHP 8.0)

Problem: PHP 8.0 throws warnings for undefined array keys.

Files Modified:

  • globals.php (line 69): isset($_SERVER['QUERY_STRING'])
  • index.php (lines 89, 172, 228): Added isset checks for $user array, $_REQUEST arrays
  • INSTALL/index.php (line 21): isset($_SERVER['HTTP_HOST'])
  • INSTALL/includes/autoload.php (line 25): isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])
  • Includes/fatal_errors.php (line 3): isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])
  • nuked.php (lines 58, 64, 124, 294, 861): Added isset checks for $nuked, $user, $_REQUEST arrays
  • themes/Impact_Nk/theme.php (lines 108, 115, 158, 172, 264): Added isset checks for $complet, $module_aff_unique, $block arrays
  • Includes/blocks/block_login.php (lines 17, 52): Added isset checks for $blok, $user arrays
  • Includes/blocks/block_menu.php (line 28): Added isset check for $user[1]
  • themes/Impact_Nk/blocks/test.php (lines 10-14): Added isset checks for $nb, $user arrays
  • modules/Stats/blok.php (line 65): Initialized $counter = 0
  • modules/News/index.php (line 42): Added isset check for $_REQUEST['p'] and type casting
  • nuked.php (line 915): Added isset check for $_GET['file']

8. get_class() on Null (PHP 8.0)

Problem: get_class() throws TypeError when called on null.

Files Modified:

  • INSTALL/includes/class/process.class.php (line 953)
    • Added null check: if ($this->_view !== null && get_class($this->_view) == 'view')

9. isset() on Expression (PHP 8.0)

Problem: Cannot use isset() on the result of an expression.

Files Modified:

  • Includes/fatal_errors.php (lines 9, 21)
    • Created temporary variables before using in define():
      $errno_val = isset($errno) ? $errno : '';
      $errstr_val = isset($errstr) ? $errstr : '';
      $errline_val = isset($errline) ? $errline : '';
      $errfile_val = isset($errfile) ? $errfile : '';
    • Used variables in ERROR_SQL definition instead of direct isset() calls

10. session_gc() Function Conflict (PHP 8.0)

Problem: PHP 8.0 has built-in session_gc() function, causing redeclaration error.

Files Modified:

  • nuked.php (line 213)
    • Renamed function: session_gc()nk_session_gc()
    • Updated handler registration: session_set_save_handler(..., 'nk_session_gc')
    • Added TMPSES_TABLE constant checks in all session handler functions

11. JavaScript i18n Loading Issues

Problem: i18n JavaScript object not loading, causing form submission failures.

Files Modified:

  • INSTALL/media/js/setConfig.js
    • Added fallback i18n object with all required translation keys
    • Added window.i18n global variable setup
  • INSTALL/media/js/runProcess.js
    • Added fallback i18n object and language variable
  • INSTALL/views/fullPage.php
    • Added cache-busting query string: ?v=<?php echo time() ?>

12. Installer MySQL Extension Check

Problem: Installer checks for mysql extension which doesn't exist in PHP 8.0.

Files Modified:

  • INSTALL/includes/class/process.class.php (lines 705-720)
    • Updated requirements check to detect mysql_connect() function (from compatibility layer) instead of extension

13. Theme and Language Safety Checks

Files Modified:

  • index.php (lines 89-90)
    • Added safety checks before using $theme and $language:
      if (!isset($theme)) $theme = isset($nuked['theme']) ? $nuked['theme'] : 'Impact_Nk';
      if (!isset($language)) $language = isset($nuked['langue']) ? $nuked['langue'] : 'english';

14. microtime() Non-Numeric Value Warning

Problem: microtime() returns string, causing non-numeric value warnings.

Files Modified:

  • index.php (line 58)
    • Changed microtime() to microtime(true) to return float
    • Fixed calculation: $mtime_end = microtime(true); $mtime = $mtime_end - $mtime;
    • Prevents "Warning: A non-numeric value encountered" on homepage

15. Undefined Constant "titre"

Problem: $block[titre] should be $block['titre'] (missing quotes).

Files Modified:

  • themes/Impact_Nk/theme.php (line 264)
    • Changed: $block[titre]$block['titre']

16. Admin Panel PHP 8.0 Compatibility Fixes

Problem: Multiple admin pages showing undefined array key warnings and fatal errors.

Critical Fix - Reserved Keyword:

  • modules/Wars/admin.php (line 108)
    • FATAL ERROR: match() is a reserved keyword in PHP 8.0+
    • Solution: Renamed function match()nk_match()
    • Updated function call in switch case (line 821)
    • All references updated to use new function name

Admin Core Files:

  • modules/Admin/phpinfo.php (line 30)

    • Added isset($_REQUEST['what']) check before accessing array key
  • modules/Admin/user.php (lines 519, 526, 535, 567-590, 595-629)

    • Fixed undefined $_REQUEST['query'] with isset check and variable assignment
    • Fixed undefined $_REQUEST['orderby'] with isset check and default value
    • Fixed undefined $_REQUEST['p'] with isset check and type casting to int
    • Added proper default values for pagination and sorting
    • Fixed all orderby display checks in HTML output
  • modules/Admin/setting.php (lines 385-386)

    • Fixed undefined $_REQUEST['stats_share'] with isset check
    • Fixed undefined $_REQUEST['inscription_avert'] with isset check
    • Added default values when keys are not set
  • modules/Admin/modules.php (line 166)

    • Removed undefined $nom variable from header display
    • Variable was used but never defined in main() function scope
  • themes/Impact_Nk/admin.php (line 364)

    • Fixed undefined $_REQUEST['sub'] with isset check and default value
    • Added: $sub = isset($_REQUEST['sub']) ? $_REQUEST['sub'] : 'index';
  • Includes/nkStats.php (lines 39, 80)

    • Fixed undefined $server_ip variable (line 39)
      • Added: $server_ip_check = (strlen($nuked['server_ip'])>0) ? "set" : "";
      • Updated reference to use $server_ip_check
    • Fixed undefined $timediff variable (line 80)
      • Added: $timediff = isset($timediff) ? $timediff : 0; before use

Module Admin Files (Bulk Fixes via sed):

  • modules/Comment/admin.php (line 107)

    • Fixed $_REQUEST['p'] with isset check: if (!isset($_REQUEST['p']) || !$_REQUEST['p'])
  • modules/Download/admin.php (lines 533, 559-584)

    • Fixed $_REQUEST['p'] with isset check and type casting
    • Fixed multiple $_REQUEST['orderby'] occurrences with isset checks
  • modules/Gallery/admin.php (lines 339, 364-402)

    • Fixed $_REQUEST['p'] with isset check and type casting
    • Fixed multiple $_REQUEST['orderby'] occurrences with isset checks
  • modules/Guestbook/admin.php (line 118)

    • Fixed $_REQUEST['p'] with isset check
  • modules/News/admin.php (lines 29, 54-87, 569-583)

    • Fixed $_REQUEST['p'] with isset check and type casting
    • Fixed multiple $_REQUEST['orderby'] occurrences with isset checks
    • Critical Fix: News category INSERT query (line 570)
      • Removed nid field from INSERT (auto_increment field should not be specified)
      • Changed from: INSERT INTO ... (nid, titre, ...) VALUES ('', ...)
      • Changed to: INSERT INTO ... (titre, ...) VALUES (...)
      • Added error checking with mysql_error() and mysql_affected_rows() verification
      • Prevents silent INSERT failures that showed success but didn't actually insert data
  • modules/Sections/admin.php (lines 28, 53-93)

    • Fixed $_REQUEST['p'] with isset check and type casting
    • Fixed multiple $_REQUEST['orderby'] occurrences with isset checks
  • modules/Textbox/admin.php (line 120)

    • Fixed $_REQUEST['p'] with isset check
  • modules/Links/admin.php (lines 238, 264-284)

    • Fixed $_REQUEST['p'] with isset check and type casting
    • Fixed multiple $_REQUEST['orderby'] occurrences with isset checks

17. Theme Display and User Module Fixes

Problem: Multiple undefined array key warnings in theme display and user profile functionality.

Theme Files:

  • themes/Impact_Nk/theme.php (lines 108, 115, 158, 172, 264, 275, 283, 301, 307)
    • Fixed undefined array key "User" and "News" in $complet and $module_aff_unique arrays
    • Added isset checks for $_REQUEST['file'], $complet[$_REQUEST['file']], $module_aff_unique[$_REQUEST['file']], and $_REQUEST['page']
    • Fixed undefined constant "titre" on line 264: Changed $block[titre] to $block['titre']
    • Applied fixes to top(), opentable(), and closetable() functions

User Module Files:

  • modules/User/index.php (lines 2029, 1473-1490, 1386-1399, 1530-1534)
    • Fixed undefined array keys in update_pref() function call: Added isset checks with default empty strings for all $_REQUEST parameters
    • Fixed file upload handling: Added isset checks for $_FILES['fichiernom']['name'] and $_FILES['fichiernom']['size']
    • Added is_uploaded_file() validation before move_uploaded_file()
    • Critical Fix: Avatar synchronization - Added code to update USER_TABLE.avatar when uploading via preferences page (was only updating USER_DETAIL_TABLE.photo, but account page displays from USER_TABLE.avatar)

Pattern Applied:

  • All array key accesses use isset checks with default values
  • File uploads validated with is_uploaded_file() before processing
  • Database synchronization between related tables when needed

Comprehensive Admin Module isset() Checks (January 15, 2026):

  • Fixed all admin module switch statements to use isset() checks for all $_REQUEST parameters
  • 18 modules fixed: News, Links, Gallery, Download, Sections, Survey, Comment, Textbox, Wars, Forum, Guestbook, Server, Admin/smilies, Recruit, Contact, Calendar, Defy, Irc
  • Pattern applied: All $_REQUEST['param'] accesses changed to isset($_REQUEST['param']) ? $_REQUEST['param'] : ''
  • Prevents "Undefined array key" warnings when admin forms are submitted without all expected parameters
  • Files modified: 18 admin.php files, 488 insertions, 122 deletions

Additional Admin Panel Fixes:

  • modules/Comment/admin.php (line 238)

    • Fixed undefined variable $cid in module_com() function
    • Removed unnecessary hidden input field (leftover from edit_com() function)
  • modules/Forum/admin.php (line 938)

    • Fixed undefined variable $checked2 when forum_rank_team is not "on"
    • Initialized $checked1 = "" and $checked2 = "" at start of main_pref() function
    • Both variables now always defined before use

18. Members Module PHP 8.0 Compatibility Fixes (January 15, 2026)

Problem: Multiple PHP 8.0 compatibility issues in Members module.

Files Modified:

  • modules/Members/index.php (lines 29, 32, 42, 56, 74, 174, 180-184, 401-412)
    • Undefined array key "letter": Added isset() check and stored in $letter variable
    • Undefined array key "p": Added isset() check with type casting: $p = isset($_REQUEST['p']) ? (int)$_REQUEST['p'] : 1;
    • Fatal error: each() function: Replaced while (list(, $lettre) = each($alpha)) with foreach ($alpha as $lettre)
      • each() was removed in PHP 8.0
      • Added missing $counter++ increment
    • Switch statement: Added isset() checks for all $_REQUEST parameters
    • SQL security: Added mysql_real_escape_string() for letter filtering

19. Undefined Variable $j (Row Counter) Fixes (January 15, 2026)

Problem: Variable $j used for alternating row colors without initialization, causing "Undefined variable" warnings.

Files Modified:

  • modules/Members/index.php (line 90)

    • Initialized $j = 0; before while loop
  • modules/User/index.php (line 94)

    • Initialized $j = 0; before while loop
  • modules/Comment/index.php (line 146)

    • Initialized $j = 0; before while loop
  • modules/Stats/index.php (line 134)

    • Added if (!isset($j)) $j = 0; check (used in loop that may be called multiple times)
  • modules/Team/index.php (line 76)

    • Initialized $j = 0; before while loop
  • modules/Wars/index.php (lines 82, 266, 366)

    • Initialized $j = 0; before each while loop (3 locations)
  • modules/Guestbook/index.php (line 217)

    • Initialized $j = 0; before while loop
  • modules/Textbox/index.php (line 56)

    • Initialized $j = 0; before while loop
  • modules/Server/index.php (lines 34, 378)

    • Initialized $j = 0; before while loop and foreach loop (2 locations)

Pattern Applied:

  • Initialize $j = 0; immediately before the loop that uses it

  • For loops that may be called multiple times, use if (!isset($j)) $j = 0;

  • modules/Wars/admin.php (lines 108, 143, 146)

    • Fixed undefined variable $status used in "add" branch (only defined in "edit" branch)
    • Fixed undefined array key $_REQUEST['nbr'] without isset check
    • Initialized $status = 0 and $nbr = 0 at start of nk_match() function
    • Added isset check: $nbr = isset($_REQUEST['nbr']) ? (int)$_REQUEST['nbr'] : 0;

Pattern Applied:

  • All $_REQUEST['p'] checks: if (!isset($_REQUEST['p']) || !$_REQUEST['p']) or isset($_REQUEST['p']) ? (int)$_REQUEST['p'] : 1
  • All $_REQUEST['orderby'] checks: isset($_REQUEST['orderby']) ? $_REQUEST['orderby'] : ''
  • Type casting for pagination: (int)$_REQUEST['p'] to prevent non-numeric warnings
  • Default values provided for all undefined array keys
  • Variables initialized at function start when used in multiple code paths

20. Forum Module Frontend PHP 8.0 Compatibility Fixes (January 15, 2026)

Problem: Multiple PHP 8.0 compatibility issues in Forum module frontend pages causing undefined array key warnings and functional bugs.

Files Modified:

Forum/main.php:

  • Fixed undefined array key "cat" (line 67)
    • Added isset() check: $cat = isset($_REQUEST['cat']) ? (int)$_REQUEST['cat'] : 0;
    • Used mysql_real_escape_string() for SQL queries and urlencode() for URLs
    • Initialized $cat_check variable with proper escaping

Forum/search.php:

  • Fixed multiple undefined array keys: "do", "id_forum", "query", "autor", "into", "searchtype", "limit", "date_max", "op", "p"
    • Initialized all parameters with isset() checks at function start
    • Added type casting for numeric values: (int)$_REQUEST['p']
    • Used local variables consistently with proper SQL escaping and URL encoding
    • Fixed pagination logic for $_REQUEST['p']

Forum/viewforum.php:

  • Fixed undefined array keys: "date_max", "p" (line 36, 42, 53)
    • Initialized $date_max and $forum_id from $_REQUEST with isset() and type casting
    • Used variables consistently in SQL queries and URL construction
    • Fixed pagination: $p = isset($_GET['p']) ? (int)$_GET['p'] : 1;

Forum/post.php:

  • Fixed multiple undefined array keys and variables: "do", "thread_id", "mess_id", "$ftexte", "$emailnotify", "$annonce", "$usersig", "$e_txt", "$e_titre", "$author"
    • Initialized all $_REQUEST parameters ($do, $forum_id, $thread_id, $mess_id) with isset() checks
    • Initialized all potentially undefined variables to default empty/zero values
    • Replaced all direct $_REQUEST accesses with local variables
    • Added SQL escaping (mysql_real_escape_string()) and HTML escaping (htmlspecialchars()) for output

Forum/index.php:

  • Fixed undefined array keys: "emailnotify", "annonce", "survey", "survey_field" (and their _reply, _edit, _check variants)
    • Initialized all variables with isset() checks and default values before use in post, edit, and reply functions
    • Critical Fix - AUTO_INCREMENT: Removed id from INSERT statements for FORUM_THREADS_TABLE, FORUM_MESSAGES_TABLE, FORUM_POLL_TABLE, and FORUM_OPTIONS_TABLE to allow MySQL to auto-increment
    • Critical Fix - Integer Default Values: Changed default values for closed and view columns from '' to '0' in FORUM_THREADS_TABLE INSERT statement
    • Critical Fix - Thread ID Retrieval: Improved thread ID retrieval after insertion:
      • Prioritized mysql_insert_id() with fallbacks using SELECT MAX(id) with specific conditions (forum/author) and general (most recent for forum)
      • Added error handling if thread_id remains 0
    • Critical Fix - Redirect URL: Corrected redirect URLs after posting to use reliably retrieved $idmax (as $thread_id_redirect) instead of $_REQUEST['thread_id'], preventing thread_id=0 in URL
    • Added SQL escaping for all string values being inserted into database
    • Fixed $_REQUEST['survey_field'] access in add_poll() to use local variable and urlencode()

Forum/viewtopic.php:

  • Fixed multiple undefined variable and array key issues:
    • Array offset on null (lines 58, 59, 62, 72): Added is_array() checks before accessing $user_visit array keys, initialized $tid and $fid to empty strings
    • Undefined variables $prev and $next (line 119): Initialized both to empty strings before conditional blocks, added proper null checks for mysql_fetch_array() results
    • Undefined array key "highlight" (lines 259, 493): Added isset() check and stored in $highlight variable, used consistently throughout
    • Undefined variable $tmpcnt (line 284): Added if (!isset($tmpcnt)) $tmpcnt = 0; before first use, changed increment logic
    • Undefined array key "p" (lines 415, 446): Used initialized $p variable consistently with proper URL encoding
    • Undefined variable $attach_file (line 415): Added if (!isset($attach_file)) $attach_file = ''; before use
    • Fixed all $_REQUEST accesses to use local variables with proper escaping
    • Added proper URL encoding for all URL parameters

Pattern Applied:

  • All $_REQUEST parameters initialized with isset() checks at function start
  • Type casting for numeric values: (int)$_REQUEST['param']
  • SQL escaping: mysql_real_escape_string() for all database queries
  • HTML escaping: htmlspecialchars() for all HTML output
  • URL encoding: urlencode() for all URL parameters
  • AUTO_INCREMENT fields: Omit from INSERT column lists, let MySQL handle
  • Integer defaults: Use '0' instead of '' for integer columns

21. Search Module Frontend PHP 8.0 Compatibility Fixes (January 15, 2026)

Problem: Multiple undefined array key warnings in Search module frontend.

Files Modified:

  • modules/Search/index.php (lines 41, 43, 80, 193)
    • Undefined variables $checked1 through $checked6: Initialized all to empty strings ('') at start of index() function
    • Undefined array key "module" in loop: Fixed $_REQUEST['module'] access in foreach loop by introducing local variable $module_check with isset() check
    • Undefined array keys in mod_search(): Explicitly initialized $module, $main, $autor, $limit, $searchtype with isset() checks within switch statement case "mod_search" before passing to mod_search()
    • Used local variables consistently in URL construction (urlencode()) and SQL queries (mysql_real_escape_string())

Pattern Applied:

  • Initialize conditionally assigned variables to default values before conditional blocks
  • Use local variables with proper escaping for all database and URL operations

22. Additional Frontend Module PHP 8.0 Compatibility Fixes (January 15, 2026)

Problem: Multiple undefined array key warnings in various frontend modules.

Files Modified:

Team/index.php:

  • Fixed undefined array keys: "cid", "game", "op"
    • Added isset() checks for $_REQUEST['cid'] and $_REQUEST['game']
    • Initialized $game variable and handled all $_REQUEST['game'] accesses with isset() checks, type casting, and URL encoding
    • Updated switch statement for $_REQUEST['op'] with isset() check

Server/index.php:

  • Fixed undefined array key: "op"
    • Updated switch statement for $_REQUEST['op'] with isset() check

Textbox/index.php:

  • Fixed undefined array key: "p", "op"
    • Fixed pagination logic by initializing $p with isset() and type casting
    • Updated switch statement for $_REQUEST['op'] with isset() check

Guestbook/index.php:

  • Fixed undefined array key: "p", "op"
    • Fixed pagination logic by initializing $p with isset() and type casting
    • Updated switch statement for $_REQUEST['op'] with isset() check

Wars/index.php:

  • Fixed undefined array keys: "p", "p2", "p3", "tid", "orderby", "op"
    • Fixed pagination logic by initializing $p, $p2, $p3 with isset() and type casting in multiple locations
    • Initialized $tid for $_REQUEST['tid'] accesses, used mysql_real_escape_string() for SQL, and urlencode() for URLs
    • Initialized $orderby for $_REQUEST['orderby'] accesses, used it in logic, and urlencode() for URLs
    • Updated switch statement for $_REQUEST['op'] with isset() check

Comment/index.php:

  • Fixed undefined array key: "op"
    • Updated switch statement for $_REQUEST['op'] with isset() check
    • Added isset() checks for all $_REQUEST parameters passed to functions like del_comment, modif_comment, com_index, post_com, view_com, post_comment, edit_comment

Stats/top.php:

  • Fixed undefined variables: $j, $j1, $j2, $j3, $j4
    • Initialized all row counter variables to 0 before their respective loops for alternating row colors

Defy/index.php:

  • Fixed deprecated each() function (line 110)
    • Replaced each() with foreach loop for iterating arrays
    • each() was removed in PHP 8.0

User/index.php:

  • Fixed microtime() non-numeric value warning
    • Changed srand((double)microtime() * 1000000); to srand((double)microtime(true) * 1000000); to ensure microtime() returns a float

Includes/nkSessions.php:

  • Fixed microtime() non-numeric value warning
    • Changed microtime() to microtime(true) to return float instead of string
    • Updated calculation: $microtime_float = microtime(true); $sec = floor($microtime_float); $usec = ($microtime_float - $sec);
  • Fixed array offset on null warning (January 19, 2026)
    • Added isset() checks and null checks before accessing $row array offsets (lines 55-58)
    • Prevents "Trying to access array offset on value of type null" warnings when database queries return no results
    • Pattern: if ($row && isset($row['date']) && isset($row['ip']) && ...) instead of if ($row['date'] > ...)

Includes/nkCaptcha.php:

  • Fixed microtime() non-numeric value warning
    • Changed md5(uniqid(microtime(), true)); to md5(uniqid(microtime(true), true)); to ensure microtime() returns a float

Pattern Applied:

  • All $_REQUEST parameters checked with isset() before use
  • Type casting for numeric values: (int)$_REQUEST['param']
  • SQL escaping: mysql_real_escape_string() for database queries
  • URL encoding: urlencode() for URL parameters
  • Initialize loop counters before use
  • Replace deprecated each() with foreach
  • Use microtime(true) to return float instead of string

Files Modified Summary

Core Files (5 files)

  • index.php - mysqli_compat include, error handling, theme/language safety checks, microtime fixes, user array checks
  • globals.php - Fixed magic quotes, QUERY_STRING check
  • nuked.php - Fixed strftime, utf8_encode, session_gc conflict, user array checks, GET array checks
  • Includes/mysqli_compat.php - NEW: Complete MySQLi compatibility layer
  • Includes/fatal_errors.php - Fixed isset() on expressions, undefined variables

Installer Files (8 files)

  • INSTALL/index.php - Added mysqli_compat include, HTTP_HOST check
  • INSTALL/includes/autoload.php - Fixed HTTP_ACCEPT_LANGUAGE check
  • INSTALL/includes/class/process.class.php - Fixed get_class() on null, MySQL check, parameter order, curly braces
  • INSTALL/includes/class/dbTable.class.php - Fixed parameter order
  • INSTALL/tables/*.php - Updated function calls (28 files)
  • INSTALL/media/js/setConfig.js - Added i18n fallback
  • INSTALL/media/js/runProcess.js - Added i18n and language fallback
  • INSTALL/views/fullPage.php - Added cache-busting

Theme & Block Files (6 files)

  • themes/Impact_Nk/theme.php - Fixed array key checks, titre constant
  • themes/Impact_Nk/blocks/test.php - Fixed array key checks
  • Includes/blocks/block_login.php - Fixed array key checks, explode() fixes
  • Includes/blocks/block_menu.php - Fixed user array checks
  • modules/Stats/blok.php - Fixed counter initialization
  • modules/News/index.php - Fixed REQUEST array checks, type casting

Admin Panel Files (18+ files)

  • modules/Wars/admin.php - Fixed match() reserved keyword (FATAL ERROR), undefined variables ($status, $nbr), REQUEST array checks
  • modules/Admin/phpinfo.php - Fixed REQUEST array checks
  • modules/Admin/user.php - Fixed REQUEST array checks, orderby handling, pagination
  • modules/Admin/setting.php - Fixed REQUEST array checks
  • modules/Admin/modules.php - Fixed undefined variable
  • themes/Impact_Nk/admin.php - Fixed REQUEST array checks
  • Includes/nkStats.php - Fixed undefined variables ($server_ip, $timediff)
  • modules/Comment/admin.php - Fixed pagination, undefined variable ($cid)
  • modules/Download/admin.php - Fixed pagination and sorting
  • modules/Gallery/admin.php - Fixed pagination and sorting
  • modules/Guestbook/admin.php - Fixed pagination
  • modules/News/admin.php - Fixed pagination and sorting
  • modules/Sections/admin.php - Fixed pagination and sorting
  • modules/Textbox/admin.php - Fixed pagination
  • modules/Links/admin.php - Fixed pagination and sorting
  • modules/Forum/admin.php - Fixed undefined variables ($checked1, $checked2)

Theme and User Module Files (2 files)

  • themes/Impact_Nk/theme.php - Fixed undefined array keys (User, News), undefined constant (titre), all display functions
  • modules/User/index.php - Fixed undefined array keys, file upload handling, avatar synchronization between tables

Frontend Module Files (18 files):

  • modules/Forum/main.php - Fixed undefined array key "cat"
  • modules/Forum/search.php - Fixed multiple undefined array keys (do, id_forum, query, autor, into, searchtype, limit, date_max, op, p)
  • modules/Forum/viewforum.php - Fixed undefined array keys (date_max, p)
  • modules/Forum/post.php - Fixed multiple undefined array keys and variables
  • modules/Forum/index.php - Fixed undefined array keys, AUTO_INCREMENT issues, thread ID retrieval, redirect URLs
  • modules/Forum/viewtopic.php - Fixed multiple undefined variables and array keys (prev, next, highlight, tmpcnt, p, attach_file, user_visit array access)
  • modules/Search/index.php - Fixed undefined variables ($checked1-6) and array keys (module, autor, limit, searchtype)
  • modules/Team/index.php - Fixed undefined array keys (cid, game, op)
  • modules/Server/index.php - Fixed undefined array key "op"
  • modules/Textbox/index.php - Fixed undefined array keys (p, op)
  • modules/Guestbook/index.php - Fixed undefined array keys (p, op)
  • modules/Wars/index.php - Fixed undefined array keys (p, p2, p3, tid, orderby, op)
  • modules/Comment/index.php - Fixed undefined array key "op" and function parameters
  • modules/Stats/top.php - Fixed undefined variables ($j, $j1, $j2, $j3, $j4)
  • modules/Defy/index.php - Fixed deprecated each() function
  • modules/User/index.php - Fixed microtime() non-numeric value warning
  • Includes/nkSessions.php - Fixed microtime() non-numeric value warning
  • Includes/nkCaptcha.php - Fixed microtime() non-numeric value warning

Total Files Modified: 94+ files (updated from 76+)

Recent Additions (January 15, 2026):

  • Members module: Fixed each(), undefined array keys, and $j variable
  • 9 frontend modules: Fixed undefined $j variable for row coloring
  • Forum module frontend: Complete PHP 8.0 compatibility fixes (6 files)
  • Search module: Fixed undefined variables and array keys
  • 8 additional frontend modules: Fixed undefined array keys and deprecated functions
  • 3 Includes files: Fixed microtime() non-numeric value warnings


Testing Commands

Important: Always use php8.0 command to match the website's PHP version:

# Test with PHP 8.0 (matches website)
sudo -u www-data php8.0 /path/to/file.php

# Check PHP version
php8.0 -v

# Syntax check
php8.0 -l /path/to/file.php

Note: The default php command uses PHP 8.4, which may show different behavior than PHP 8.0 used by the website.


Troubleshooting

If website shows 500 error:

  1. Check PHP error logs: /var/log/php8.0-fpm.log
  2. Enable error display temporarily in index.php
  3. Check nginx error logs: /var/log/nginx/error.log
  4. Verify database connection in conf.inc.php
  5. Check file permissions

If installer doesn't work:

  1. Verify mysqli_compat.php is included
  2. Check PHP version matches (8.0)
  3. Verify database credentials
  4. Check nginx configuration for INSTALL directory

Common PHP 8.0 Issues:

  • Undefined array keys: Add isset() checks
  • Function redeclaration: Use function_exists() or rename
  • Deprecated functions: Use compatibility layer or alternatives
  • Type errors: Add null checks before type-dependent operations
  • Non-numeric values: Use microtime(true) for float values

References



Post-Migration Bug Fixes (January 16, 2026)

This section documents all bugs discovered and fixed during testing after the initial migration.

Fix #1: Comment Module - Comment Submission Issues

Issue: Comments were not being saved to the database and admin session was being cleared when submitting comments.

Root Causes:

  1. Admin session was being cleared when accessing non-Admin modules (index.php line 125-131)
  2. AJAX requests were outputting HTML headers instead of JSON
  3. Missing titre parameter in AJAX request
  4. Auto-increment id field was being set to empty string in INSERT statement

Fixes Applied:

1. Admin Session Preservation

File: index.php (line 125-131)

  • Problem: Code cleared admin session when accessing any non-Admin module
  • Fix: Added exception for AJAX comment submissions:
&& (! ($_REQUEST['file'] == 'Comment' && isset($_REQUEST['ajax']) && $_REQUEST['ajax'] == '1'))

2. AJAX Response Format

File: modules/Comment/index.php

  • Problem: AJAX requests were outputting HTML headers, breaking JSON parsing
  • Fix: Added proper JSON headers and separated AJAX/non-AJAX logic:
    • Added header('Content-Type: application/json') for AJAX responses
    • Only output HTML headers for non-AJAX requests
    • Improved error handling with JSON responses

3. Missing Parameters

File: modules/Comment/index.php (line 143)

  • Problem: titre (title) parameter was not being sent in AJAX request
  • Fix: Added titre to AJAX send data:
var titre = document.querySelector('input[name="titre"]') ? document.querySelector('input[name="titre"]').value : '';
OAjax.send("texte="+encodeURIComponent(editor_txt)+"&pseudo="+pseudo+"&module="+module+"&im_id="+im_id+"&titre="+encodeURIComponent(titre)+"&ajax=1"+captchaData);

4. Auto-Increment ID Field

File: modules/Comment/index.php (line 519)

  • Problem: INSERT statement was trying to insert empty string '' for auto-increment id column
  • Fix: Removed id field from INSERT statement:
    • Before: INSERT INTO ... (id, module, ...) VALUES ('', 'news', ...)
    • After: INSERT INTO ... (module, ...) VALUES ('news', ...)

5. Improved Error Handling

File: modules/Comment/index.php

  • Added proper access level checking with error messages
  • Improved verification error handling
  • Added database error checking and reporting
  • Better captcha validation error handling

6. Verification Function Improvements

File: modules/Comment/index.php (function verification())

  • Added error checking for missing comment module configuration
  • Added error checking for non-existent items
  • Improved error messages

Result: ✅ Comments now save correctly to database and admin session is preserved during comment submission.


Fix #2-6: Comprehensive PHP 8.0 Compatibility Fixes (January 16, 2026)

After the initial migration and Comment module fixes, a comprehensive codebase audit identified and fixed 87+ additional PHP 8.0 compatibility issues across 50+ files.

Audit Scope: 84+ PHP files scanned
Total Issues Found: ~200+ potential issues
Issues Fixed: 87+ critical and high-priority issues
Files Modified: 50+ files
Deployment Status: ✅ All fixes deployed to live site

Issue Categories Fixed:

  • ✅ Auto-increment ID fields: 28 instances
  • ✅ Direct $_REQUEST in SQL: 6 instances
  • ✅ Deprecated functions: 2 instances (each(), create_function())
  • ✅ Direct strftime() calls: 28 instances
  • ✅ strlen() on non-strings: 23+ instances
  • ✅ MySQL/mysqli compatibility: Verified working

Remaining Lower Priority Issues:

  • ⚠️ Direct array access: 421+ instances of $user[] / $nuked[] without isset() (Many protected by earlier checks - lower priority)
  • 🟢 String offset curly braces: 23 instances (Third-party libraries - low priority)
  • 🟢 Error handling: Some mysql_query() calls could benefit from explicit error handling (improves debugging but won't break functionality)

Note: For detailed technical information about these fixes, see the "All PHP 8.0 Compatibility Fixes Applied" section above. This section provides a summary of the audit-based fixes.

2.1. Auto-Increment ID Field Issues (28 instances) ✅ FIXED

Problem: INSERT statements attempting to insert empty string '' for auto-increment id columns. MySQL 8.0+ is stricter and rejects this.

Solution: Removed id field from all INSERT statements, allowing MySQL to auto-generate the value.

Files Fixed (26+ files):

  • Includes/nkSessions.php - Session creation
  • nuked.php - Visitor stats
  • modules/Textbox/submit.php - Shoutbox messages
  • modules/Guestbook/index.php - Guestbook entries
  • modules/Contact/index.php - Contact messages
  • modules/Recruit/index.php - Recruitment
  • modules/Defy/index.php - Defy submission
  • modules/User/index.php (4 instances) - User registration, game preferences
  • modules/Irc/admin.php - IRC awards
  • modules/Calendar/admin.php - Calendar events
  • modules/Admin/smilies.php - Smilies
  • modules/Admin/games.php - Games
  • modules/Admin/user.php (3 instances) - Banned users, teams, team ranks
  • modules/Admin/block.php - Blocks
  • modules/Defy/admin.php - Wars
  • modules/Wars/admin.php - War files
  • modules/Links/admin.php - Links
  • modules/Server/admin.php - Servers
  • modules/Forum/admin.php (3 instances) - Forum categories, forums, ranks
  • modules/Forum/index.php - Forum poll options
  • modules/Sections/admin.php - Sections
  • modules/Survey/admin.php - Surveys
  • modules/Gallery/admin.php - Gallery items
  • modules/Suggest/index.php - Suggestions
  • modules/Suggest/modules/News.php - Suggested news
  • modules/Suggest/modules/Links.php - Suggested links
  • modules/Vote/index.php - Vote submissions

Example Fix:

// BEFORE (will fail in MySQL 8.0+):
$sql = mysql_query("INSERT INTO " . TABLE . " ( `id` , `field1` ) VALUES ( '' , '" . $value . "' )");

// AFTER (correct):
$sql = mysql_query("INSERT INTO " . TABLE . " ( `field1` ) VALUES ( '" . $value . "' )");

2.2. Deprecated Functions Removed in PHP 8.0 (2 instances) ✅ FIXED

2.2.1. each() Function

File: modules/Admin/class/iam_backup.php (line 239)
Problem: each() was removed in PHP 8.0
Fix: Replaced with foreach loop

// BEFORE:
while(list($x, $columns) = @each($index)) {
    // ...
}

// AFTER:
foreach($index as $x => $columns) {
    // ...
}
2.2.2. create_function() Function

File: modules/Server/includes/gameSpyQ.php (line 73)
Problem: create_function() was removed in PHP 8.0
Fix: Replaced with anonymous function

// BEFORE:
$removeLastChar = create_function('$x', 'return substr($x, 0, -1);');

// AFTER:
$removeLastChar = function($x) { return substr($x, 0, -1); };

2.3. SQL Injection Risks (6 instances) ✅ FIXED

Problem: Direct $_REQUEST variable interpolation in SQL queries without proper escaping.

Files Fixed:

  • modules/News/index.php (7 instances) - Category and news ID queries
  • modules/Userbox/index.php (1 instance) - User ID query

Solution: Extract variables, validate with intval() for numeric values, and escape with mysql_real_escape_string().

Example Fix:

// BEFORE (risky):
$where = "WHERE cat = '{$_REQUEST['cat_id']}' AND $day >= date";

// AFTER (safe):
$cat_id = isset($_REQUEST['cat_id']) ? intval($_REQUEST['cat_id']) : 0;
$where = "WHERE cat = '" . mysql_real_escape_string($cat_id) . "' AND $day >= date";

2.4. Direct strftime() Calls (28 instances) ✅ FIXED

Problem: strftime() was deprecated in PHP 8.1 and will be removed in PHP 9.0. A compatibility function nk_strftime() already exists in nuked.php.

Solution: Replaced all direct strftime() calls with nk_strftime().

Files Fixed (9 files):

  • modules/Forum/viewtopic.php (5 calls)
  • modules/Forum/viewforum.php (5 calls)
  • modules/Forum/main.php (5 calls)
  • modules/Calendar/admin.php (4 calls)
  • modules/Recruit/admin.php (1 call)
  • modules/Admin/setting.php (1 call)
  • modules/News/index.php (1 call)
  • modules/Stats/visits.php (5 calls)
  • modules/Sections/blok.php (1 call)

Example Fix:

// BEFORE:
$date = strftime("%H:%M", $row['date']);

// AFTER:
$date = nk_strftime("%H:%M", $row['date']);

2.5. strlen() Type Safety (23+ instances) ✅ FIXED

Problem: In PHP 8.0, strlen() throws a TypeError if called on non-string values (null, arrays, objects, etc.).

Solution: Added type checking before calling strlen() using is_string() checks or type casting.

Files Fixed (13+ files):

  • modules/Comment/index.php
  • modules/User/index.php (3 instances)
  • modules/Textbox/index.php (3 instances)
  • modules/Forum/viewforum.php (2 instances)
  • modules/Forum/search.php (3 instances)
  • modules/Search/index.php (2 instances)
  • modules/Guestbook/index.php
  • modules/News/admin.php
  • modules/Irc/admin.php
  • modules/Contact/admin.php
  • modules/Sections/admin.php
  • modules/Links/admin.php
  • modules/Stats/top.php (4 instances)
  • modules/Stats/visits.php (4 instances)
  • modules/Userbox/index.php (2 instances)

Example Fix:

// BEFORE (risky):
if (strlen($titre) > 40) { ... }

// AFTER (safe):
$titre = is_string($titre) ? $titre : (string)$titre;
if (strlen($titre) > 40) { ... }

2.6. MySQL/mysqli Compatibility ✅ VERIFIED

Status: The MySQLi compatibility layer (Includes/mysqli_compat.php) is working correctly:

  • All mysql_* functions are wrapped to use mysqli_* equivalents
  • mysql_real_escape_string() properly uses mysqli_real_escape_string() when connection exists
  • Connection management via global $nk_mysqli_link is functioning correctly
  • No additional fixes needed for database compatibility


Fix #7-11: Post-Migration Testing Bug Fixes (January 16, 2026 - Continued)

During systematic testing, several additional issues were discovered and fixed:

7. Contact Module - Notification Not Clearing After Message Deletion

Issue: When a contact message was deleted, the notification in the admin panel remained visible even though the message was gone.

Root Cause: The notification system creates a type '1' notification when a contact message is received, but this notification was not deleted when the last contact message was removed.

Fix Applied: File: modules/Contact/admin.php (function del())

  • Added check to count remaining contact messages after deletion
  • If no messages remain, delete all type '1' notifications (contact notifications)
  • This ensures the notification disappears when the last contact message is deleted

Code:

// Check if there are any contact messages left
$sql_check = mysql_query('SELECT COUNT(*) FROM ' . CONTACT_TABLE);
$count = mysql_result($sql_check, 0);

// If no messages left, delete the contact notification (type 1)
if ($count == 0) {
    mysql_query('DELETE FROM ' . $nuked['prefix'] . '_notification WHERE type = \'1\'');
}

Result: ✅ Notifications now properly clear when all contact messages are deleted.


8. Survey Module - Undefined Variable $j

Issue: Warning: Undefined variable $j on lines 227 and 229 when viewing survey list.

Root Cause: Variable $j was used for alternating row colors but was not initialized before the while loop.

Fix Applied: File: modules/Survey/index.php (function index_sondage())

  • Initialize $j = 0 before the while loop that processes survey results

Code:

$sql = mysql_query('SELECT sid, titre, date FROM ' . SURVEY_TABLE . ' ORDER BY date DESC');
$j = 0; // Initialize row counter for alternating colors
while (list($poll_id, $titre, $date) = mysql_fetch_array($sql)) {
    // ...
}

Result: ✅ No more undefined variable warnings.


9. User Module - Parse Error: Unexpected "else"

Issue: Parse error: syntax error, unexpected token "else" on line 1276 when editing user account.

Root Cause: During the strlen() type safety fix, a type check was added that broke the if-else structure. The line $nick = is_string($nick) ? $nick : (string)$nick; was placed between an if and else if, creating a syntax error.

Fix Applied: File: modules/User/index.php (around line 1275)

  • Moved the type check before the if statement to maintain proper if-else structure

Code:

// BEFORE (broken):
if (!$nick || ($nick == "") || (preg_match("`[\$\^\(\)'\"?%#<>,;:]`", $nick))){
    // ...
}
$nick = is_string($nick) ? $nick : (string)$nick;
else if (strlen($nick) > 30){ // ERROR: else without if

// AFTER (fixed):
$nick = is_string($nick) ? $nick : (string)$nick;
if (!$nick || ($nick == "") || (preg_match("`[\$\^\(\)'\"?%#<>,;:]`", $nick))){
    // ...
}
else if (strlen($nick) > 30){ // Correct structure

Result: ✅ Parse error resolved, user account editing works correctly.


10. Search Module - Multiple Undefined Variables

Issues:

  • Warning: Undefined variable $z on lines 168 and 170
  • Warning: Undefined array key "p" on line 153
  • Warning: Undefined variable $string in modules/Search/rubriques/Forum.php on line 64

Root Causes:

  1. Variable $z used for alternating row colors but not initialized
  2. $_REQUEST['p'] accessed without isset() check
  3. Variable $string used in Forum.php but should be $main (search term)

Fixes Applied:

File: modules/Search/index.php

  • Initialize $z = 0 before the for loop
  • Add isset() check for $_REQUEST['p']

File: modules/Search/rubriques/Forum.php

  • Replace $string with $main (the actual search term variable)
  • Add safety check: $search_string = isset($main) ? $main : '';

Code:

// modules/Search/index.php
if (!isset($_REQUEST['p']) || !$_REQUEST['p']) $_REQUEST['p'] = 1;
// ...
$z = 0; // Initialize row counter for alternating colors
for($a = $start;$a < $end;$a++){
    if ($z == 0){
        // ...
    }
}

// modules/Search/rubriques/Forum.php
$search_string = isset($main) ? $main : '';
$link_post = "index.php?file=Forum&amp;page=viewtopic&amp;forum_id=" . $fid . "&amp;thread_id=" . $tid . "&amp;highlight=" . urlencode($search_string). "#" . $mid;

Result: ✅ All undefined variable warnings resolved, search functionality works correctly.


11. Userbox Module - Undefined Variables $title and $reply

Issue: Warning: Undefined variable $title and Undefined variable $reply on lines 65 and 66 when posting a message.

Root Cause: Variables $title and $reply were only set conditionally (if $_REQUEST['titre'] or $_REQUEST['message'] exist) but were used in the form output regardless.

Fix Applied: File: modules/Userbox/index.php (function post_message())

  • Initialize both variables to empty strings at the start of the function

Code:

$title = ''; // Initialize title variable
$reply = ''; // Initialize reply variable

if (!empty($_REQUEST['titre'])){
    // Set $title
}
if (!empty($_REQUEST['message'])){
    // Set $reply
}
// Now safe to use $title and $reply in form output

Result: ✅ No more undefined variable warnings, userbox message posting works correctly.



12. User Module - Undefined Array Key "nuked_user_theme"

Issue: Warning: Undefined array key "nuked_user_theme" when accessing theme change page.

Root Cause: Variable $cookie_theme might not be set, or the cookie might not exist, causing $_COOKIE[$cookie_theme] to access an undefined array key.

Fix Applied: File: modules/User/index.php (function change_theme(), line 1853)

  • Added isset() checks for both $cookie_theme and $_COOKIE[$cookie_theme]
  • Default to empty string if either is not set

Code:

// BEFORE (risky):
$cookietheme = $_COOKIE[$cookie_theme];

// AFTER (safe):
$cookietheme = isset($cookie_theme) && isset($_COOKIE[$cookie_theme]) ? $_COOKIE[$cookie_theme] : '';

Result: ✅ No more undefined array key warnings when changing themes.


13. Contact Module - Improved Notification Clearing

Issue: Contact notification persisted after deleting contact messages (reported again during testing).

Root Cause: The previous fix only deleted notifications when count reached 0, but notifications could become out of sync if multiple messages existed.

Fix Applied: File: modules/Contact/admin.php (function del())

  • Always delete all type '1' notifications when any contact message is deleted
  • Recreate the notification only if messages still exist
  • This ensures notifications are always synchronized with actual messages

Code:

// Delete all contact notifications (type 1) - they will be recreated if messages exist
mysql_query('DELETE FROM ' . $nuked['prefix'] . '_notification WHERE type = \'1\'');

// If messages still exist, recreate the notification
if ($count > 0) {
    $time = time();
    mysql_query("INSERT INTO ". $nuked['prefix'] ."_notification  (`date` , `type` , `texte`)  VALUES ('".$time."', '1', '"._NOTCON.": [<a href=\"index.php?file=Contact&page=admin\">lien</a>].')");
}

Result: ✅ Notifications now properly sync with contact messages - deleted when no messages, recreated when messages exist.


14. Contact Module - Undefined Array Key "nom"

Issue: Warning: Undefined array key "nom" when sending contact messages.

Root Cause: When a user is logged in, the form might not include the nom field (it uses $user[2] instead), but the code tried to access $_REQUEST['nom'] without checking.

Fix Applied: File: modules/Contact/index.php (function sendmail(), line 93)

  • Added isset() check for $_REQUEST['nom'] before accessing it
  • Added isset() check for $user[2] before using it

Code:

// BEFORE (risky):
$nom = trim($_REQUEST['nom']);
if($user) $nom = $user[2];

// AFTER (safe):
$nom = isset($_REQUEST['nom']) ? trim($_REQUEST['nom']) : '';
if($user && isset($user[2])) $nom = $user[2];

Result: ✅ No more undefined array key warnings when sending contact messages.


15. Core HTML Filter - Undefined Array Keys in Regex Matches

Issues:

  • Warning: Undefined array key 3 in nuked.php on line 719 (appears twice)
  • Warning: Undefined array key 4 in nuked.php on line 757 (appears 4 times)

Root Cause: The HTML filtering functions (secu_args() and secu_html()) use regex patterns that may not always capture all expected groups. When certain HTML tag patterns are processed, some array indices may not exist.

Fixes Applied:

File: nuked.php (function secu_args(), line 719)

  • Added isset() check for $matches[3] before accessing it
  • This checks if a tag is self-closing (<tag />)

File: nuked.php (function secu_html(), line 757)

  • Added isset() checks for $Tags[$i][3] and $Tags[$i][4] before accessing them
  • Extracted values to variables with defaults to avoid repeated checks
  • Added isset() check for $Tags[$i][1] before using it

Code:

// nuked.php line 719:
// BEFORE (risky):
if ($matches[3] == '/'){

// AFTER (safe):
if (isset($matches[3]) && $matches[3] == '/'){

// nuked.php line 757:
// BEFORE (risky):
$TagName = $Tags[$i][3] == ''?$Tags[$i][2].$Tags[$i][4]:$Tags[$i][2];
if ($Tags[$i][1] == '/'){

// AFTER (safe):
$tag3 = isset($Tags[$i][3]) ? $Tags[$i][3] : '';
$tag4 = isset($Tags[$i][4]) ? $Tags[$i][4] : '';
$TagName = $tag3 == '' ? (isset($Tags[$i][2]) ? $Tags[$i][2] : '') . $tag4 : (isset($Tags[$i][2]) ? $Tags[$i][2] : '');
if (isset($Tags[$i][1]) && $Tags[$i][1] == '/'){

Result: ✅ No more undefined array key warnings in HTML filtering functions.


Fix #16: Comprehensive Security Audit Fixes (January 16, 2026)

After completing the PHP 8.0 migration and initial testing, a comprehensive security audit was performed to identify and fix critical security vulnerabilities that existed in the original PHP 5.x codebase.

Audit Scope: Complete line-by-line security review of all source code
Total Issues Found: 50+ vulnerabilities across multiple severity levels
Critical Issues Fixed: 5 instances
High-Risk Issues Fixed: 30+ instances
Files Modified: 14 files
Deployment Status: ✅ All fixes deployed to live site

16.1. Remote Code Execution (RCE) via eval() - CRITICAL ✅ FIXED

Problem: Multiple files used eval() with user-controlled or potentially user-controlled input, allowing remote code execution.

Files Fixed (4 files):

  • UPLOAD/nuked.php - Language file loading (function translate())
  • UPLOAD/Includes/blocks/block_module.php - Module block loading
  • UPLOAD/Includes/blocks/block_center.php - Center block loading (2 instances)
  • UPLOAD/modules/Server/includes/gsQuery.php - Protocol class instantiation

Solution: Replaced all eval() calls with direct include() or factory patterns after implementing:

  • Whitelist validation for module/file names
  • Path validation using realpath() and strpos() to prevent directory traversal
  • File existence and readability checks
  • Document root verification

Result: ✅ All eval() vulnerabilities eliminated, preventing remote code execution.


16.2. Command Execution via system() - CRITICAL ✅ FIXED

Problem: system() calls allowed command injection if file paths were user-controlled.

File Fixed: UPLOAD/modules/Forum/index.php (lines 157, 264, 1081)
Issue: system("del $filesys") used for file deletion, vulnerable to command injection
Fix: Removed all system() calls - unlink() already handles file deletion safely

Result: ✅ Command injection vulnerability eliminated.


16.3. SQL Injection Vulnerabilities - HIGH ✅ FIXED

Problem: Multiple SQL queries used $_REQUEST variables directly without proper escaping.

Files Fixed (7 files):

  • modules/Userbox/index.php - Applied mysql_real_escape_string() to $_REQUEST['mid']
  • modules/User/index.php - Applied escaping to $_REQUEST['user_theme'], $_REQUEST['user_langue'], $_REQUEST['id_user']
  • modules/Suggest/index.php - Applied escaping to $_REQUEST['module']
  • modules/Forum/index.php - Applied escaping to 30+ $_REQUEST variables
  • modules/Forum/viewtopic.php - Applied type casting to forum_id and thread_id
  • modules/Stats/visits.php - Applied type casting to date parameters

Pattern Applied:

// BEFORE (VULNERABLE):
$sql = mysql_query("SELECT * FROM " . TABLE . " WHERE id = '" . $_REQUEST['id'] . "'");

// AFTER (SECURE):
$id_escaped = (int)$_REQUEST['id']; // For numeric values
// OR
$id_escaped = mysql_real_escape_string($_REQUEST['id']); // For string values
$sql = mysql_query("SELECT * FROM " . TABLE . " WHERE id = '" . $id_escaped . "'");

Result: ✅ 30+ SQL injection vulnerabilities fixed.


16.4. Local/Remote File Inclusion (LFI/RFI) - CRITICAL ✅ FIXED

Problem: User input directly used in include()/require() statements without validation.

Files Fixed (3 files):

  • index.php - Module file inclusion with whitelist validation and path checking
  • modules/Suggest/index.php - Suggest module inclusion with whitelist
  • modules/Search/index.php - Search rubrique inclusion with whitelist

Solution: Implemented whitelist validation and path checking:

  • Created whitelists of allowed modules/files
  • Used realpath() to resolve full paths
  • Verified files are within expected directories and document root
  • Fallback to 404 module if validation fails

Result: ✅ All file inclusion vulnerabilities fixed.


16.5. Session Security - HIGH ✅ FIXED

Problem: Session cookies were set without HttpOnly, Secure, or SameSite flags, making them vulnerable to XSS and man-in-the-middle attacks.

Files Fixed (2 files):

16.5.1. Includes/nkSessions.php - Session Cookie Security

Fix: Added secure cookie flags:

  • HttpOnly: true - Prevents JavaScript access to cookies (XSS protection)
  • Secure: $is_https - Only send cookies over HTTPS (conditional on connection)
  • Applied to both session cookies ($cookie_session, $cookie_userid)
16.5.2. modules/User/index.php - Theme/Language Cookies and Logout

Fixes:

  • Added Secure flag to theme and language cookies
  • Fixed logout function to properly clear cookies with same parameters used when setting them
  • Set cookies with expiration in the past (time() - 3600)
  • Added exit() after header redirect

Result: ✅ Session cookies now secure, logout function works correctly.


16.6. Archives Module - Undefined Variables ✅ FIXED

File: UPLOAD/modules/Archives/index.php
Fixes:

  • Added isset() check for $_REQUEST['p']
  • Added isset() check for $_REQUEST['orderby']
  • Initialized $j = 0 before loop

Result: ✅ All undefined variable warnings resolved.


Security Fix Summary

Critical Vulnerabilities Fixed:

  • ✅ 4 eval() RCE vulnerabilities → Replaced with safe include() after validation
  • ✅ 3 system() command execution vulnerabilities → Removed, using unlink() instead
  • ✅ 3 LFI/RFI vulnerabilities → Fixed with whitelist validation and path checking

High-Risk Vulnerabilities Fixed:

  • ✅ 30+ SQL injection vulnerabilities → Applied mysql_real_escape_string() and type casting
  • ✅ Session security issues → Added HttpOnly, Secure, SameSite flags to cookies
  • ✅ Logout function → Fixed cookie clearing with proper parameters

Files Modified: 14 files

  • UPLOAD/nuked.php
  • UPLOAD/index.php
  • UPLOAD/Includes/blocks/block_module.php
  • UPLOAD/Includes/blocks/block_center.php
  • UPLOAD/Includes/nkSessions.php
  • UPLOAD/modules/Server/includes/gsQuery.php
  • UPLOAD/modules/Forum/index.php
  • UPLOAD/modules/Forum/viewtopic.php
  • UPLOAD/modules/User/index.php
  • UPLOAD/modules/Userbox/index.php
  • UPLOAD/modules/Suggest/index.php
  • UPLOAD/modules/Search/index.php
  • UPLOAD/modules/Stats/visits.php
  • UPLOAD/modules/Archives/index.php

16.7. Cross-Site Scripting (XSS) Vulnerabilities - HIGH ✅ FIXED

Problem: Multiple instances where $_REQUEST variables were directly output in HTML without proper encoding, allowing XSS attacks.

Files Fixed (9 files, 20+ instances):

16.7.1. modules/Userbox/index.php (2 fixes)
  • Line 51: $_REQUEST['message'] directly in HTML output
  • Line 61: $_REQUEST['for'] in hidden form field
  • Fix: Applied nkHtmlEntities() encoding to both parameters
16.7.2. modules/Admin/user.php (1 fix)
  • Line 697: $_REQUEST['query'] directly in HTML output
  • Fix: Applied nkHtmlEntities() encoding with isset() check
16.7.3. themes/Impact_Nk/theme.php (2 fixes)
  • Lines 278, 286: $_REQUEST['file'] directly in HTML headings
  • Fix: Applied nkHtmlEntities() encoding with isset() checks
16.7.4. modules/Textbox/index.php (1 fix)
  • Lines 183-184: $_REQUEST['textarea'] in JavaScript function calls
  • Fix: Applied addslashes() for JavaScript string escaping
16.7.5. modules/Wars/admin.php (1 fix)
  • Line 304: $_REQUEST['game'] in hidden form field
  • Fix: Applied nkHtmlEntities() encoding
16.7.6. modules/Forum/index.php (5 fixes)
  • Multiple lines: $_REQUEST['forum_id'] and $_REQUEST['thread_id'] in hidden form fields
  • Fix: Applied nkHtmlEntities() encoding to all instances
16.7.7. modules/Sections/index.php (1 fix)
  • Line 289: $_REQUEST['p'] (page number) in HTML output
  • Fix: Applied nkHtmlEntities() encoding
16.7.8. modules/Stats/visits.php (2 fixes)
  • Line 127: Date parameters ($_REQUEST['oday'], $_REQUEST['omonth'], $_REQUEST['oyear']) in JavaScript URL
  • Fix: Applied addslashes() for JavaScript string escaping
  • Also fixed: Nested ternary operators for PHP 8.0 compatibility (3 instances)
16.7.9. modules/Admin/menu.php (3 fixes)
  • Lines 339-342: $_REQUEST['title'] and $_REQUEST['color'] in HTML formatting
  • Lines 822-823: $_REQUEST['color'] in form fields (2 instances)
  • Fix: Applied nkHtmlEntities() encoding to all instances

Pattern Applied:

// BEFORE (VULNERABLE):
echo "<input value=\"" . $_REQUEST['param'] . "\" />";
echo "<h2>" . $_REQUEST['file'] . "</h2>";

// AFTER (SECURE):
$param_encoded = isset($_REQUEST['param']) ? nkHtmlEntities($_REQUEST['param'], ENT_QUOTES) : '';
echo "<input value=\"" . $param_encoded . "\" />";
$file_encoded = isset($_REQUEST['file']) ? nkHtmlEntities($_REQUEST['file'], ENT_QUOTES) : '';
echo "<h2>" . $file_encoded . "</h2>";

// For JavaScript contexts:
$js_param = isset($_REQUEST['param']) ? addslashes($_REQUEST['param']) : '';
echo "javascript:function('" . $js_param . "')";

Result: ✅ 20+ XSS vulnerabilities fixed, all user input now properly encoded.


16.8. Additional Undefined Array Key Fixes ✅ FIXED

Problem: Additional undefined array key warnings discovered during XSS fix testing.

Files Fixed (3 files):

16.8.1. modules/Forum/index.php (7 fixes)
  • Multiple lines: $_REQUEST['confirm'] accessed without isset() checks
  • Fix: Added isset() checks before all $_REQUEST['confirm'] comparisons
16.8.2. modules/Sections/index.php (4 fixes)
  • Line 364: $_REQUEST['p'] without isset() check
  • Lines 370, 373, 376: $_REQUEST['orderby'] without isset() checks
  • Line 541: $_REQUEST['sid'] and $_REQUEST['nb_subcat'] without isset() checks
  • Fix: Added isset() checks for all parameters
16.8.3. modules/Suggest/modules/Sections.php (4 fixes)
  • Lines 25, 26, 61, 97: Array offset access on non-array value (int)
  • Fix: Added is_array() and isset() checks before accessing $content array elements
  • Also fixed: Added isset() check for $_REQUEST['page'] on line 95

Result: ✅ All undefined array key warnings resolved.


Fix #13: nkSessions.php Array Access Safety (January 19, 2026)

Problem: nkSessions.php accessed $row array offsets without checking if $row is not null, causing "Trying to access array offset on value of type null" warnings in PHP 8.0 when database queries return no results.

File: Includes/nkSessions.php (lines 55-58)

Solution: Added isset() checks and null checks before accessing array offsets.

Example Fix:

// BEFORE (PHP 8.0 warnings):
$row = mysql_fetch_assoc($sql);
if ($row['date'] > $time - $timesession && $row['ip'] != $user_ip)
    $secu_user = 0;
if ($secu_user  == 1) {
    $last_used = $row['last_used'];

// AFTER (PHP 8.0 compatible):
$row = mysql_fetch_assoc($sql);
// Fix: Check if $row is not null before accessing array offsets (PHP 8.0 compatibility)
if ($row && isset($row['date']) && isset($row['ip']) && $row['date'] > $time - $timesession && $row['ip'] != $user_ip)
    $secu_user = 0;
if ($secu_user  == 1 && $row && isset($row['last_used'])) {
    $last_used = $row['last_used'];

Result: ✅ No more "array offset on null" warnings in session management.


Remaining Security Considerations:

  • ⚠️ CSRF protection: No tokens implemented yet - recommended for future enhancement
  • ⚠️ Password hashing: Still uses SHA1/MD5 - migration to password_hash() recommended for future enhancement

23. Search Module - Undefined Array Key 1 ($user[1]) (January 20, 2026)

Problem: Warning: Undefined array key 1 in modules/Search/index.php on line 142.

Root Cause: The code was accessing $user[1] directly without checking if the user was logged in. In PHP 8.0+, accessing an undefined array key or index on null/non-array triggers a warning.

Fix Applied: Files Modified:

  • modules/Search/index.php
  • modules/Search/blok.php

Changes:

  • Replaced all user[1] direct accesses with the global $visiteur variable, which is safely initialized in index.php.
  • Initialized $i = 0 before module listing loops to prevent "Undefined variable" warnings.
  • Initialized $tab results array in mod_search() to prevent "Undefined variable" warnings when no results are found.
  • Added $visiteur to global declarations in index(), mod_search(), and blok.php.

Result: ✅ Resolved "Undefined array key 1" warnings and other uninitialized variable issues in the Search module.

24. Survey Module - Undefined Array Keys (January 21, 2026)

Problem 1: Warning: Undefined array key "error" in modules/Survey/index.php. Problem 2: Warning: Undefined array key "nuked_user_pool_1" in modules/Survey/index.php.

Fixes Applied:

  • File: modules/Survey/index.php
  • Error fix: Added isset($_REQUEST['error']) checks in vote_message() function (line 108).
  • Cookie fix: Added isset() check for cookie access in verif_check() function (line 59).

25. Stats Module - Encoding Issues (January 21, 2026)

Problem: Stats block specifically displaying "�" replacement characters instead of bullet points.

Fix Applied:

  • File: modules/Stats/blok.php
  • Fix: Replaced hardcoded "�" (replacement character) artifacts with standard HTML entity &bull;.


26. Security & Deprecation Fixes (March 2026)

This phase of the audit targeted resolving remaining high-severity vulnerabilities and PHP 8.0 deprecations across the main and custom branches.

Issue Categories Fixed:

  • Command Injection (RCE): Removed dangerous @system() call in modules/Forum/index.php
  • SQL Injection (SQLi): Fixed 23 instances of $_REQUEST parameters passed directly to mysql_query() across 8 modules (Forum, Calendar, Vote, Admin, User, Wars, Stats) by adding (int) typecasting or mysql_real_escape_string().
  • Cross-Site Scripting (XSS): Fixed 13 instances across 6 modules (Gallery, Links, Download, Sections, Suggest, Forum) where $_REQUEST inputs were being output directly to HTML attributes or URLs. Applied nkHtmlEntities() to sanitize the variables before output.
  • PHP 8.0 Deprecation (each()): Replaced the final 8 lingering instances of while(list() = each()) with foreach loops across 5 core modules (Admin/smilies, Links, User, Recruit, Wars).

Files Modified:

  • modules/Forum/index.php
  • modules/Forum/viewtopic.php
  • modules/Forum/viewforum.php
  • modules/Calendar/index.php
  • modules/Vote/admin.php
  • modules/Admin/notification.php
  • modules/Admin/menu.php
  • modules/User/index.php
  • modules/Wars/admin.php
  • modules/Stats/visits.php
  • modules/Gallery/index.php
  • modules/Links/index.php
  • modules/Download/index.php
  • modules/Sections/index.php
  • modules/Suggest/modules/*.php (5 files)
  • themes/Impact_Nk/theme.php
  • modules/Admin/smilies.php
  • modules/Recruit/index.php

Summary

Migration Status:COMPLETE - Website and Admin Panel fully functional on PHP 8.0
Total Fixes Applied: 155+ issues across 66+ files
Codebase Scanned: 84+ PHP files
Last Updated: January 21, 2026

Fix Categories:

  1. Initial Migration Fixes (22 fixes): MySQLi compatibility, deprecated functions, undefined variables, etc.
  2. Comprehensive Audit Fixes (87+ fixes): Auto-increment IDs, SQL injection, strftime(), strlen(), deprecated functions
  3. Testing Bug Fixes (19 fixes): Comment module, Contact notifications, Survey, User, Search (v1), Userbox, HTML filter, Search (v2 - user level), Survey (error keys), Stats (encoding)
  4. Security Audit Fixes (26+ fixes): RCE via eval(), command execution via system(), SQL injection, LFI/RFI, session security
  5. Post-Deployment Fixes (1 fix): nkSessions.php array access safety (January 19, 2026)

Issue Statistics:

  • Total Issues Found: ~254+ potential issues
  • Critical/High Priority Fixed: 117+ issues (88 compatibility + 26 security + 3 bug fixes)
  • Files Modified: 66+ files (50 compatibility + 14 security + 2 bug fixes)
  • Remaining Lower Priority: ~100+ issues (XSS in some outputs, CSRF tokens, password hashing migration - can be addressed as needed)

Testing Status:

  • ✅ Core functionality (homepage, admin panel, user auth)
  • ✅ News module (full CRUD operations)
  • ✅ Comment module (AJAX submission, admin management)
  • ✅ Contact module (send, view, delete, notifications)
  • ✅ Survey module (list display, voting, errors)
  • ✅ User module (profile edit, theme change)
  • ✅ Search module (search functionality)
  • ✅ Userbox module (messaging)
  • ✅ Stats module (display encoding)
  • ⏳ Additional modules pending systematic testing

For detailed testing checklist, see TESTING.md.