# EasyStream Conflict Resolution Guide ## Overview This document identifies and provides solutions for conflicts between legacy code and new modern code in EasyStream. **Last Updated:** January 2025 --- ## Table of Contents 1. [Session Variable Conflicts](#session-variable-conflicts) 2. [Authentication Class Conflicts](#authentication-class-conflicts) 3. [Database Query Conflicts](#database-query-conflicts) 4. [Frontend JavaScript Conflicts](#frontend-javascript-conflicts) 5. [API Response Format Conflicts](#api-response-format-conflicts) 6. [Migration Action Plan](#migration-action-plan) --- ## 1. Session Variable Conflicts ### Problem Multiple session variable names are used inconsistently: - `$_SESSION['USER_ID']` (uppercase) - `$_SESSION['usr_id']` (lowercase) - `$_SESSION['user_id']` (lowercase with underscore) This causes bugs where authentication checks fail randomly. ### Current Impact **Files affected:** 26+ files **Example conflicts:** ```php // api/videos.php - Checks both! if (!$userId && isset($_SESSION['USER_ID'])) { $userId = $_SESSION['USER_ID']; } elseif (!$userId && isset($_SESSION['usr_id'])) { $userId = $_SESSION['usr_id']; } // f_modules/m_frontend/m_acct/account.php - Uses different one $membership_check = ($_SESSION["USER_ID"] > 0) ? VLogin::checkSubscription() : null; ``` ### Solution **Standardize on ONE session variable: `$_SESSION['USER_ID']`** #### Step 1: Create Session Helper Function **File:** `f_core/f_functions/functions.session.php` ```php 0) { return (int) $_SESSION['USER_ID']; } // Check legacy variants (for migration period) if (isset($_SESSION['usr_id']) && $_SESSION['usr_id'] > 0) { // Migrate to new standard $_SESSION['USER_ID'] = (int) $_SESSION['usr_id']; unset($_SESSION['usr_id']); return (int) $_SESSION['USER_ID']; } if (isset($_SESSION['user_id']) && $_SESSION['user_id'] > 0) { // Migrate to new standard $_SESSION['USER_ID'] = (int) $_SESSION['user_id']; unset($_SESSION['user_id']); return (int) $_SESSION['USER_ID']; } return 0; } /** * Set current user ID in session * * @param int $userId User ID to set */ function setCurrentUserId($userId) { $_SESSION['USER_ID'] = (int) $userId; // Clean up legacy session variables unset($_SESSION['usr_id']); unset($_SESSION['user_id']); } /** * Check if user is logged in * * @return bool */ function isUserLoggedIn() { return getCurrentUserId() > 0; } /** * Clear user session */ function clearUserSession() { unset($_SESSION['USER_ID']); unset($_SESSION['usr_id']); unset($_SESSION['user_id']); } ``` #### Step 2: Update VAuth to Use Standard **File:** `f_core/f_classes/class.auth.php` Add to VAuth class: ```php /** * Get current user ID * @return int */ public static function getCurrentUserId() { return getCurrentUserId(); // Use helper function } /** * Set user ID after login * @param int $userId */ private function setUserId($userId) { setCurrentUserId($userId); } ``` #### Step 3: Update All API Endpoints Replace this pattern: ```php // OLD - checking multiple variables if (!$userId && isset($_SESSION['USER_ID'])) { $userId = $_SESSION['USER_ID']; } elseif (!$userId && isset($_SESSION['usr_id'])) { $userId = $_SESSION['usr_id']; } ``` With: ```php // NEW - use helper function if (!$userId) { $userId = getCurrentUserId(); } ``` #### Step 4: Update All Module Files **Files to update:** - `f_modules/m_frontend/m_acct/account.php` - `f_modules/m_frontend/templatebuilder.php` - `f_modules/m_frontend/templatebuilder_ajax.php` - `f_modules/m_frontend/m_player/embed.php` - `f_modules/m_frontend/m_notif/notifications_bell.php` **Before:** ```php $user_id = isset($_SESSION['USER_ID']) ? (int)$_SESSION['USER_ID'] : 0; ``` **After:** ```php $user_id = getCurrentUserId(); ``` --- ## 2. Authentication Class Conflicts ### Problem **Multiple authentication classes exist:** 1. `VLogin` - Old, deprecated, still referenced in `account.php` 2. `VSession` - Redundant with VAuth 3. `VAuth` - Modern, should be the only one used ### Current Impact **File:** `f_modules/m_frontend/m_acct/account.php` ```php // Line 37 - Uses OLD VLogin class! $membership_check = ($_SESSION["USER_ID"] > 0) ? VLogin::checkSubscription() : null; ``` This will FAIL if VLogin class is removed. ### Solution #### Step 1: Check if VLogin Class Exists ```bash find . -name "class.login.php" -type f ``` **Result:** No `class.login.php` found - VLogin doesn't exist! This means `account.php` line 37 will throw a fatal error. #### Step 2: Fix account.php **File:** `f_modules/m_frontend/m_acct/account.php` **Before:** ```php $membership_check = ($cfg["paid_memberships"] == 1 and $_SESSION["USER_ID"] > 0) ? VLogin::checkSubscription() : null; ``` **After:** ```php // Use VAuth or VMembership class instead require_once $cfg['classes_dir'] . '/class.membership.php'; $membership_check = ($cfg["paid_memberships"] == 1 && getCurrentUserId() > 0) ? VMembership::checkSubscription(getCurrentUserId()) : null; ``` #### Step 3: Search and Replace All VLogin References ```bash # Find all VLogin references grep -r "VLogin" --include="*.php" f_modules/ # Replace with VAuth # For each file found, update to use VAuth::getInstance() ``` --- ## 3. Database Query Conflicts ### Problem **Multiple patterns for database queries:** 1. **Old direct ADOdb calls:** ```php $db = $database->db_connect(); $result = $db->Execute("SELECT ..."); ``` 2. **VDatabase wrapper (correct):** ```php $db = VDatabase::getInstance(); $result = $db->execute("SELECT ...", $params); ``` 3. **Old procedural style:** ```php $result = mysql_query("SELECT ..."); ``` ### Solution **Standardize on VDatabase singleton pattern** #### Search and Replace Pattern **Find:** ```php $database->db_connect() $db->Execute() $db->GetRow() ``` **Replace with:** ```php $db = VDatabase::getInstance(); $db->execute() $db->singleRow() ``` #### Example Fix **Before:** ```php function getUser($userId) { global $database; $db = $database->db_connect(); $sql = "SELECT * FROM db_users WHERE usr_id = " . $userId; // SQL injection! $result = $db->Execute($sql); return $result->FetchRow(); } ``` **After:** ```php function getUser($userId) { $db = VDatabase::getInstance(); $sql = "SELECT * FROM db_users WHERE usr_id = ?"; $result = $db->execute($sql, [$userId]); return $result && $result->RecordCount() > 0 ? $result->fields : null; } ``` --- ## 4. Frontend JavaScript Conflicts ### Problem **Three different AJAX patterns:** 1. **jQuery $.post (legacy):** ```javascript jQuery.post(url, data, function(result) { ... }); ``` 2. **jQuery $.ajax (legacy):** ```javascript jQuery.ajax({ url: url, method: 'POST', data: data }); ``` 3. **Modern fetch via api-helper (new):** ```javascript await api.post(url, data); ``` ### Current Impact - **Page weight:** jQuery adds 87KB - **Maintenance:** Three patterns to maintain - **Consistency:** Different error handling for each ### Solution **Migrate all to api-helper.js** #### Migration Example 1: Browse Videos **File:** `f_scripts/fe/js/browse.init.js` **Before:** ```javascript jQuery(".more-button").click(function () { var page = parseInt(jQuery(this).attr("rel-page")); var url = _rel + "?p=0&m=" + idnr + "&sort=" + type + "&page=" + page; jQuery("#list ul").mask(""); jQuery.get(url, function(result) { jQuery("#list ul").append(result).unmask(); jQuery(".more-button").attr("rel-page", page + 1); }); }); ``` **After:** ```javascript document.addEventListener('click', async (e) => { const moreBtn = e.target.closest('.more-button'); if (!moreBtn) return; const page = parseInt(moreBtn.dataset.page); try { showLoading(moreBtn); const result = await api.getVideos({ page: page, sort: currentSort, category: currentCategory }); if (result.success) { appendVideos(result.data.videos); moreBtn.dataset.page = page + 1; // Hide button if no more pages if (page >= result.data.pagination.pages) { moreBtn.style.display = 'none'; } } } catch (error) { api.handleError(error); } finally { hideLoading(moreBtn); } }); function appendVideos(videos) { const list = document.getElementById('video-list'); videos.forEach(video => { const item = createVideoElement(video); list.appendChild(item); }); } ``` #### Migration Example 2: Watch Later **File:** `f_scripts/fe/js/browse.init.js` **Before:** ```javascript jQuery(".watch_later_wrap").click(function () { var file_key = jQuery(this).attr("rel-key"); var _this = jQuery(this); jQuery.post(url, {"fileid[0]": file_key}, function(result) { _this.find(".icon-clock") .removeClass("icon-clock") .addClass("icon-check"); }); }); ``` **After:** ```javascript document.addEventListener('click', async (e) => { const watchBtn = e.target.closest('.watch-later-btn'); if (!watchBtn) return; const fileKey = watchBtn.dataset.fileKey; try { const result = await api.toggleWatchLater(fileKey); if (result.success) { const icon = watchBtn.querySelector('.icon'); if (result.data.action === 'added') { icon.classList.remove('icon-clock'); icon.classList.add('icon-check'); watchBtn.title = 'In Watch List'; } else { icon.classList.remove('icon-check'); icon.classList.add('icon-clock'); watchBtn.title = 'Watch Later'; } } } catch (error) { api.handleError(error); } }); ``` --- ## 5. API Response Format Conflicts ### Problem **Inconsistent response formats:** 1. **New API endpoints (standardized):** ```json { "success": true, "data": { ... }, "error": null } ``` 2. **Old endpoints (inconsistent):** ```json { "status": "ok", "result": { ... } } ``` OR just raw data: ```json { "usr_id": 1, "usr_name": "john" } ``` ### Solution **Update all old endpoints to use standard format** #### Standard Response Helper **File:** `f_core/f_functions/functions.api.php` ```php true, 'data' => $data, 'error' => null ], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); exit; } /** * Send error response * * @param string $message Error message * @param int $statusCode HTTP status code * @param array $details Additional error details */ function sendApiError($message, $statusCode = 400, $details = null) { http_response_code($statusCode); header('Content-Type: application/json'); $response = [ 'success' => false, 'data' => null, 'error' => $message ]; if ($details) { $response['details'] = $details; } echo json_encode($response, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); exit; } /** * Validate API request method * * @param string|array $allowedMethods Allowed HTTP method(s) * @throws Exception if method not allowed */ function validateApiMethod($allowedMethods) { $allowedMethods = (array) $allowedMethods; $currentMethod = $_SERVER['REQUEST_METHOD']; if (!in_array($currentMethod, $allowedMethods)) { sendApiError( 'Method not allowed. Allowed: ' . implode(', ', $allowedMethods), 405 ); } } ``` #### Update Old API Endpoints **Example:** `api/privacy.php` **Before:** ```php // Returns raw data, no standard format echo json_encode($result); ``` **After:** ```php require_once __DIR__ . '/../f_core/f_functions/functions.api.php'; try { // ... existing code ... sendApiSuccess([ 'privacy_settings' => $result ]); } catch (Exception $e) { sendApiError($e->getMessage(), 500); } ``` --- ## 6. Migration Action Plan ### Critical Fixes (Do First - High Impact) #### Fix 1: Create Session Helper Functions **File to create:** `f_core/f_functions/functions.session.php` **Priority:** CRITICAL - Affects authentication everywhere **Time:** 30 minutes **Steps:** 1. Create the file with helper functions (code provided above) 2. Include in `f_core/config.core.php` 3. Test that `getCurrentUserId()` works **Test:** ```php // Add to any page temporarily echo "User ID: " . getCurrentUserId(); ``` #### Fix 2: Update API Endpoints to Use Helper **Files to update:** - `api/videos.php` - `api/user.php` - `api/comments.php` - `api/subscriptions.php` **Priority:** HIGH - Prevents session bugs **Time:** 1 hour **Pattern to replace:** ```php // Find this: if (!$userId && isset($_SESSION['USER_ID'])) { $userId = $_SESSION['USER_ID']; } elseif (!$userId && isset($_SESSION['usr_id'])) { $userId = $_SESSION['usr_id']; } // Replace with: if (!$userId) { $userId = getCurrentUserId(); } ``` #### Fix 3: Fix VLogin Reference in account.php **File:** `f_modules/m_frontend/m_acct/account.php` **Priority:** CRITICAL - Currently broken! **Time:** 15 minutes **Line 37 fix:** ```php // Before: $membership_check = ($_SESSION["USER_ID"] > 0) ? VLogin::checkSubscription() : null; // After: $membership_check = ($cfg["paid_memberships"] == 1 && getCurrentUserId() > 0) ? VMembership::checkSubscription(getCurrentUserId()) : null; ``` ### Medium Priority Fixes #### Fix 4: Standardize Database Queries **Pattern:** Search for `$database->db_connect()` and replace with `VDatabase::getInstance()` **Priority:** MEDIUM - Performance improvement **Time:** 2-3 hours **Command:** ```bash grep -r "db_connect" --include="*.php" f_modules/ ``` #### Fix 5: Migrate jQuery AJAX in browse.init.js **File:** `f_scripts/fe/js/browse.init.js` **Priority:** MEDIUM - Performance improvement **Time:** 3-4 hours **See examples in section 4 above** ### Low Priority (Can wait) #### Fix 6: Create API Response Helper **File to create:** `f_core/f_functions/functions.api.php` **Priority:** LOW - Nice to have **Time:** 1 hour #### Fix 7: Update Old API Endpoints **Files:** `api/privacy.php`, `api/telegram.php`, etc. **Priority:** LOW - These endpoints still work **Time:** 2-3 hours --- ## Testing Checklist After each fix, test: ``` Authentication: ☐ Login works ☐ Session persists after page reload ☐ Logout clears session ☐ Protected pages redirect to login API Endpoints: ☐ Videos list loads ☐ Comments load and post ☐ Subscribe/unsubscribe works ☐ User profile loads Frontend: ☐ Browse videos page works ☐ Load more pagination works ☐ Watch later toggle works ☐ No JavaScript console errors ``` --- ## Rollback Plan If something breaks: 1. **Backup before changes:** ```bash git add . git commit -m "Before conflict resolution" ``` 2. **If issues occur:** ```bash git revert HEAD ``` 3. **Test specific fix in isolation:** ```bash git checkout -b test-session-fix # Apply only session fix # Test thoroughly # If good, merge to main ``` --- ## Priority Order 1. ✅ **Session Helper Functions** - Do this FIRST (CRITICAL) 2. ✅ **Update API Endpoints** - Fix session access (HIGH) 3. ✅ **Fix account.php VLogin** - Currently broken (CRITICAL) 4. ⏸️ **Standardize Database Queries** - Performance (MEDIUM) 5. ⏸️ **Migrate jQuery AJAX** - Performance (MEDIUM) 6. ⏸️ **API Response Helpers** - Nice to have (LOW) --- ## Estimated Timeline - **Critical fixes (1-3):** 2-3 hours - **Medium fixes (4-5):** 1 week - **Low priority (6-7):** 1-2 weeks **Total: 2-3 weeks for complete resolution** --- ## Next Steps 1. Create `f_core/f_functions/functions.session.php` 2. Update `f_core/config.core.php` to include it 3. Update all API endpoints to use `getCurrentUserId()` 4. Fix `f_modules/m_frontend/m_acct/account.php` 5. Test authentication thoroughly 6. Proceed to medium priority fixes --- **Document Created:** January 2025 **Status:** Ready for Implementation