Converted queries in:
- functions.php:
* getTripCount() - Hardcoded query
* getAvailableSpaces() - Two queries using $trip_id parameter (HIGH PRIORITY)
- blog.php:
* Main blog list query - Hardcoded 'published' status
- course_details.php:
* Driver training courses query - Hardcoded course type
- driver_training.php:
* Future driver training dates query - Hardcoded course type
- events.php:
* Upcoming events query - Hardcoded date comparison
- index.php:
* Featured trips query - Hardcoded published status
All queries now use proper parameter binding via prepared statements.
Next: Convert remaining 15+ safe hardcoded queries for consistency.
Changed countRecentFailedAttempts() to use MySQL DATE_SUB(NOW(), INTERVAL ? MINUTE)
instead of PHP-calculated cutoff time. This ensures consistent datetime comparison
on the database server without timezone mismatches between PHP and MySQL.
This fixes the issue where the AND attempted_at condition was filtering out all
recent attempts due to timestamp comparison inconsistencies.
The countRecentFailedAttempts() function was requiring BOTH email AND ip_address to match, which caused failed attempts from different IPs to not count together. This prevented account lockout from working properly.
Changed to count failed attempts by email only. IP address is still recorded for audit purposes but doesn't affect the failed attempt count.
This ensures:
- Failed attempts accumulate correctly regardless of IP changes
- Accounts lock after 5 failed attempts within 15 minutes
- Prevents attackers from bypassing by changing IP