captcha.php 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. <?php
  2. /**
  3. * Simple Captcha System for Comment Forms
  4. */
  5. class Captcha {
  6. private static $sessionKey = 'captcha_code';
  7. /**
  8. * Generate a simple math captcha
  9. */
  10. public static function generate() {
  11. // Start session if not already started
  12. if (session_status() === PHP_SESSION_NONE) {
  13. session_start();
  14. }
  15. // Generate random numbers
  16. $num1 = rand(1, 10);
  17. $num2 = rand(1, 10);
  18. $operators = ['+', '-'];
  19. $operator = $operators[array_rand($operators)];
  20. // Calculate answer
  21. if ($operator === '+') {
  22. $answer = $num1 + $num2;
  23. } else {
  24. $answer = $num1 - $num2;
  25. }
  26. // Store answer in session
  27. $_SESSION[self::$sessionKey] = $answer;
  28. // Return the question
  29. return [
  30. 'question' => "$num1 $operator $num2 = ?",
  31. 'num1' => $num1,
  32. 'num2' => $num2,
  33. 'operator' => $operator
  34. ];
  35. }
  36. /**
  37. * Verify captcha answer
  38. */
  39. public static function verify($answer) {
  40. // Start session if not already started
  41. if (session_status() === PHP_SESSION_NONE) {
  42. session_start();
  43. }
  44. // Check if captcha exists in session
  45. if (!isset($_SESSION[self::$sessionKey])) {
  46. return false;
  47. }
  48. // Verify answer
  49. $isValid = (int)$answer === $_SESSION[self::$sessionKey];
  50. // Clear captcha after verification
  51. unset($_SESSION[self::$sessionKey]);
  52. return $isValid;
  53. }
  54. /**
  55. * Get HTML for captcha display
  56. */
  57. public static function getHtml() {
  58. $captcha = self::generate();
  59. ob_start();
  60. ?>
  61. <div class="captcha-container">
  62. <div class="captcha-question">
  63. <span class="captcha-numbers"><?php echo $captcha['num1']; ?></span>
  64. <span class="captcha-operator"><?php echo $captcha['operator']; ?></span>
  65. <span class="captcha-numbers"><?php echo $captcha['num2']; ?></span>
  66. <span class="captcha-equals">=</span>
  67. <input type="number" name="captcha_answer" class="captcha-input" required
  68. placeholder="?" min="-20" max="20" autocomplete="off">
  69. </div>
  70. <small class="captcha-help"><?php echo t('captcha_help'); ?></small>
  71. </div>
  72. <?php
  73. return ob_get_clean();
  74. }
  75. /**
  76. * Get captcha for AJAX requests
  77. */
  78. public static function getAjaxCaptcha() {
  79. $captcha = self::generate();
  80. return [
  81. 'question' => $captcha['question'],
  82. 'num1' => $captcha['num1'],
  83. 'num2' => $captcha['num2'],
  84. 'operator' => $captcha['operator']
  85. ];
  86. }
  87. /**
  88. * Refresh captcha (for AJAX)
  89. */
  90. public static function refresh() {
  91. return self::generate();
  92. }
  93. /**
  94. * Check if captcha is required for current user
  95. */
  96. public static function isRequired() {
  97. // Check if user is logged in as admin
  98. if (session_status() === PHP_SESSION_NONE) {
  99. session_start();
  100. }
  101. if (isset($_SESSION['user_id']) && isset($_SESSION['user_role'])) {
  102. return $_SESSION['user_role'] !== 'admin';
  103. }
  104. return true; // Captcha required for non-admin users
  105. }
  106. }