Нет описания

Throttling.php 2.9KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. <?php
  2. namespace MailPoet\Subscription;
  3. if (!defined('ABSPATH')) exit;
  4. use MailPoet\Entities\SubscriberIPEntity;
  5. use MailPoet\Subscribers\SubscriberIPsRepository;
  6. use MailPoet\Util\Helpers;
  7. use MailPoet\WP\Functions as WPFunctions;
  8. class Throttling {
  9. /** @var SubscriberIPsRepository */
  10. private $subscriberIPsRepository;
  11. /** @var WPFunctions */
  12. private $wp;
  13. public function __construct(
  14. SubscriberIPsRepository $subscriberIPsRepository,
  15. WPFunctions $wp
  16. ) {
  17. $this->wp = $wp;
  18. $this->subscriberIPsRepository = $subscriberIPsRepository;
  19. }
  20. public function throttle() {
  21. $subscriptionLimitEnabled = $this->wp->applyFilters('mailpoet_subscription_limit_enabled', true);
  22. $subscriptionLimitWindow = (int)$this->wp->applyFilters('mailpoet_subscription_limit_window', DAY_IN_SECONDS);
  23. $subscriptionLimitBase = (int)$this->wp->applyFilters('mailpoet_subscription_limit_base', MINUTE_IN_SECONDS);
  24. $subscriberIp = Helpers::getIP();
  25. if ($subscriptionLimitEnabled && !$this->isUserExemptFromThrottling()) {
  26. if (!empty($subscriberIp)) {
  27. $subscriptionCount = $this->subscriberIPsRepository->getCountByIPAndCreatedAtAfterTimeInSeconds($subscriberIp, $subscriptionLimitWindow);
  28. if ($subscriptionCount > 0) {
  29. $timeout = $subscriptionLimitBase * pow(2, $subscriptionCount - 1);
  30. $existingUser = $this->subscriberIPsRepository->findOneByIPAndCreatedAtAfterTimeInSeconds($subscriberIp, $timeout);
  31. if (!empty($existingUser)) {
  32. return $timeout;
  33. }
  34. }
  35. }
  36. }
  37. if ($subscriberIp !== null) {
  38. $ip = new SubscriberIPEntity($subscriberIp);
  39. $existingIp = $this->subscriberIPsRepository->findOneBy(['ip' => $ip->getIP(), 'createdAt' => $ip->getCreatedAt()]);
  40. if (!$existingIp) {
  41. $this->subscriberIPsRepository->persist($ip);
  42. $this->subscriberIPsRepository->flush();
  43. }
  44. }
  45. $this->purge();
  46. return false;
  47. }
  48. public function purge(): void {
  49. $interval = $this->wp->applyFilters('mailpoet_subscription_purge_window', MONTH_IN_SECONDS);
  50. $this->subscriberIPsRepository->deleteCreatedAtBeforeTimeInSeconds($interval);
  51. }
  52. public function secondsToTimeString($seconds): string {
  53. $hrs = floor($seconds / 3600);
  54. $min = floor($seconds % 3600 / 60);
  55. $sec = $seconds % 3600 % 60;
  56. $result = [
  57. 'hours' => $hrs ? sprintf(__('%d hours', 'mailpoet'), $hrs) : '',
  58. 'minutes' => $min ? sprintf(__('%d minutes', 'mailpoet'), $min) : '',
  59. 'seconds' => $sec ? sprintf(__('%d seconds', 'mailpoet'), $sec) : '',
  60. ];
  61. return join(' ', array_filter($result));
  62. }
  63. private function isUserExemptFromThrottling(): bool {
  64. if (!$this->wp->isUserLoggedIn()) {
  65. return false;
  66. }
  67. $user = $this->wp->wpGetCurrentUser();
  68. $roles = $this->wp->applyFilters('mailpoet_subscription_throttling_exclude_roles', ['administrator', 'editor']);
  69. return !empty(array_intersect($roles, (array)$user->roles));
  70. }
  71. }