Nessuna descrizione

Captcha.php 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. <?php
  2. namespace MailPoet\Subscription;
  3. if (!defined('ABSPATH')) exit;
  4. use MailPoet\Models\Subscriber;
  5. use MailPoet\Subscribers\SubscriberIPsRepository;
  6. use MailPoet\Util\Helpers;
  7. use MailPoet\WP\Functions as WPFunctions;
  8. use MailPoetVendor\Gregwar\Captcha\CaptchaBuilder;
  9. class Captcha {
  10. const TYPE_BUILTIN = 'built-in';
  11. const TYPE_RECAPTCHA = 'recaptcha';
  12. const TYPE_DISABLED = null;
  13. /** @var WPFunctions */
  14. private $wp;
  15. /** @var CaptchaSession */
  16. private $captchaSession;
  17. /** @var SubscriberIPsRepository */
  18. private $subscriberIPsRepository;
  19. public function __construct(
  20. SubscriberIPsRepository $subscriberIPsRepository,
  21. WPFunctions $wp = null,
  22. CaptchaSession $captchaSession = null
  23. ) {
  24. if ($wp === null) {
  25. $wp = new WPFunctions;
  26. }
  27. if ($captchaSession === null) {
  28. $captchaSession = new CaptchaSession($wp);
  29. }
  30. $this->wp = $wp;
  31. $this->captchaSession = $captchaSession;
  32. $this->subscriberIPsRepository = $subscriberIPsRepository;
  33. }
  34. public function isSupported() {
  35. return extension_loaded('gd') && function_exists('imagettftext');
  36. }
  37. public function isRequired($subscriberEmail = null) {
  38. if ($this->isUserExemptFromCaptcha()) {
  39. return false;
  40. }
  41. $subscriptionCaptchaRecipientLimit = $this->wp->applyFilters('mailpoet_subscription_captcha_recipient_limit', 0);
  42. if ($subscriptionCaptchaRecipientLimit === 0) {
  43. return true;
  44. }
  45. // Check limits per recipient if enabled
  46. if ($subscriberEmail) {
  47. $subscriber = Subscriber::where('email', $subscriberEmail)->findOne();
  48. if ($subscriber instanceof Subscriber
  49. && $subscriber->countConfirmations >= $subscriptionCaptchaRecipientLimit
  50. ) {
  51. return true;
  52. }
  53. }
  54. // Check limits per IP address
  55. $subscriptionCaptchaWindow = $this->wp->applyFilters('mailpoet_subscription_captcha_window', MONTH_IN_SECONDS);
  56. $subscriberIp = Helpers::getIP();
  57. if (empty($subscriberIp)) {
  58. return false;
  59. }
  60. $subscriptionCount = $this->subscriberIPsRepository->getCountByIPAndCreatedAtAfterTimeInSeconds(
  61. $subscriberIp,
  62. (int)$subscriptionCaptchaWindow
  63. );
  64. if ($subscriptionCount > 0) {
  65. return true;
  66. }
  67. return false;
  68. }
  69. private function isUserExemptFromCaptcha() {
  70. if (!$this->wp->isUserLoggedIn()) {
  71. return false;
  72. }
  73. $user = $this->wp->wpGetCurrentUser();
  74. $roles = $this->wp->applyFilters('mailpoet_subscription_captcha_exclude_roles', ['administrator', 'editor']);
  75. return !empty(array_intersect($roles, (array)$user->roles));
  76. }
  77. public function renderImage($width = null, $height = null, $sessionId = null, $return = false) {
  78. if (!$this->isSupported()) {
  79. return false;
  80. }
  81. $fontNumbers = array_merge(range(0, 3), [5]); // skip font #4
  82. $fontNumber = $fontNumbers[mt_rand(0, count($fontNumbers) - 1)];
  83. $reflector = new \ReflectionClass(CaptchaBuilder::class);
  84. $captchaDirectory = dirname((string)$reflector->getFileName());
  85. $font = $captchaDirectory . '/Font/captcha' . $fontNumber . '.ttf';
  86. $builder = CaptchaBuilder::create()
  87. ->setBackgroundColor(255, 255, 255)
  88. ->setTextColor(1, 1, 1)
  89. ->setMaxBehindLines(0)
  90. ->build($width ?: 220, $height ?: 60, $font);
  91. $this->captchaSession->init($sessionId);
  92. $this->captchaSession->setCaptchaHash($builder->getPhrase());
  93. if ($return) {
  94. return $builder->get();
  95. }
  96. header("Expires: Sat, 01 Jan 2019 01:00:00 GMT"); // time in the past
  97. header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
  98. header("Cache-Control: no-store, no-cache, must-revalidate");
  99. header("Cache-Control: post-check=0, pre-check=0", false);
  100. header("Pragma: no-cache");
  101. header('X-Cache-Enabled: False');
  102. header('X-LiteSpeed-Cache-Control: no-cache');
  103. header('Content-Type: image/jpeg');
  104. $builder->output();
  105. exit;
  106. }
  107. }