[ Avaa Bypassed ]




Upload:

Command:

hmhc3928@3.147.85.238: ~ $
<?php

namespace MailPoet\Models;

if (!defined('ABSPATH')) exit;


use MailPoet\DI\ContainerWrapper;
use MailPoet\Settings\SettingsController;
use MailPoet\Util\Helpers;
use MailPoet\Util\Security;
use MailPoet\WP\Functions as WPFunctions;

/**
 * @property int $id
 * @property string $email
 * @property string $firstName
 * @property string $lastName
 * @property string $status
 * @property string|null $subscribedIp
 * @property string|null $confirmedIp
 * @property string|null $confirmedAt
 * @property string|null $lastSubscribedAt
 * @property string|null $deletedAt
 * @property string|null $source
 * @property string|null $linkToken
 * @property int $countConfirmations
 * @property int $wpUserId
 * @property array $segments
 * @property array $subscriptions
 * @property string|null $unconfirmedData
 * @property int $isWoocommerceUser
 */

class Subscriber extends Model {
  public static $_table = MP_SUBSCRIBERS_TABLE; // phpcs:ignore PSR2.Classes.PropertyDeclaration

  const STATUS_SUBSCRIBED = 'subscribed';
  const STATUS_UNSUBSCRIBED = 'unsubscribed';
  const STATUS_UNCONFIRMED = 'unconfirmed';
  const STATUS_BOUNCED = 'bounced';
  const STATUS_INACTIVE = 'inactive';

  const OBSOLETE_LINK_TOKEN_LENGTH = 6;
  const LINK_TOKEN_LENGTH = 32;

  /** @var string|bool */
  public $token;

  public function __construct() {
    parent::__construct();

    $this->addValidations('email', [
      'required' => WPFunctions::get()->__('Please enter your email address', 'mailpoet'),
      'validEmail' => WPFunctions::get()->__('Your email address is invalid!', 'mailpoet'),
    ]);
  }

  public static function findOne($id = false) {
    if (is_int($id) || (string)(int)$id === $id) {
      return parent::findOne($id);
    } else if (strlen(trim($id)) > 0) {
      return parent::where('email', $id)->findOne();
    }
    return false;
  }

  public function segments() {
    return $this->has_many_through(
      __NAMESPACE__ . '\Segment',
      __NAMESPACE__ . '\SubscriberSegment',
      'subscriber_id',
      'segment_id'
    )
    ->where(MP_SUBSCRIBER_SEGMENT_TABLE . '.status', self::STATUS_SUBSCRIBED);
  }

  public function save() {
    // convert email to lowercase format
    $this->email = strtolower($this->email);
    return parent::save();
  }

  public function delete() {
    // WP Users cannot be deleted
    if (!$this->isWPUser() && !$this->isWooCommerceUser()) {
      // delete all relations to segments
      SubscriberSegment::deleteSubscriptions($this);
      // delete all relations to custom fields
      SubscriberCustomField::deleteSubscriberRelations($this);
      return parent::delete();
    }
    return null;
  }

  public function trash() {
    // WP Users cannot be trashed
    if ($this->isWPUser() || $this->isWooCommerceUser()) {
      return false;
    } else {
      return parent::trash();
    }
  }

  public function isWPUser() {
    return (bool)$this->wpUserId;
  }

  public function isWooCommerceUser() {
    return (bool)$this->isWoocommerceUser;
  }

  /**
   * @deprecated Use the version in \MailPoet\Subscribers\SubscribersRepository::getCurrentWPUser
   */
  public static function getCurrentWPUser() {
    trigger_error('Calling Subscriber::getCurrentWPUser() is deprecated and will be removed. Use MailPoet\Subscribers\SubscribersRepository::getCurrentWPUser(). ', E_USER_DEPRECATED);
    $wpUser = WPFunctions::get()->wpGetCurrentUser();
    if (empty($wpUser->ID)) {
      return false; // Don't look up a subscriber for guests
    }
    return self::where('wp_user_id', $wpUser->ID)->findOne();
  }

  public static function filterOutReservedColumns(array $subscriberData) {
    $reservedColumns = [
      'id',
      'wp_user_id',
      'is_woocommerce_user',
      'status',
      'subscribed_ip',
      'confirmed_ip',
      'confirmed_at',
      'created_at',
      'updated_at',
      'deleted_at',
      'unconfirmed_data',
    ];
    $subscriberData = array_diff_key(
      $subscriberData,
      array_flip($reservedColumns)
    );
    return $subscriberData;
  }

  public static function search($orm, $search = '') {
    if (strlen(trim($search)) === 0) {
      return $orm;
    }

    return $orm->where_raw(
      '(`email` LIKE ? OR `first_name` LIKE ? OR `last_name` LIKE ?)',
      ['%' . $search . '%', '%' . $search . '%', '%' . $search . '%']
    );
  }

  public static function filters($data = []) {
    $group = (!empty($data['group'])) ? $data['group'] : 'all';

    $segments = Segment::orderByAsc('name')
      ->whereNull('deleted_at')
      ->whereIn('type', Segment::getSegmentTypes())
      ->findMany();
    $segmentList = [];
    $segmentList[] = [
      'label' => WPFunctions::get()->__('All Lists', 'mailpoet'),
      'value' => '',
    ];

    $subscribersWithoutSegment = self::filter('withoutSegments')
      ->whereNull('deleted_at')
      ->count();
    $subscribersWithoutSegmentLabel = sprintf(
      __('Subscribers without a list (%s)', 'mailpoet'),
      number_format($subscribersWithoutSegment)
    );

    $segmentList[] = [
      'label' => $subscribersWithoutSegmentLabel,
      'value' => 'none',
    ];

    foreach ($segments as $segment) {
      $subscribersCount = 0;
      $subscribers = $segment->subscribers()
        ->filter('groupBy', $group);
      if ($subscribers) {
        $subscribersCount = $subscribers->count();
      }

      $label = sprintf(
        '%s (%s)',
        $segment->name,
        number_format($subscribersCount)
      );

      $segmentList[] = [
        'label' => $label,
        'value' => $segment->id(),
      ];
    }

    $filters = [
      'segment' => $segmentList,
    ];

    return $filters;
  }

  public static function filterBy($orm, $filters = null) {
    if (empty($filters)) {
      return $orm;
    }
    foreach ($filters as $key => $value) {
      if ($key === 'segment') {
        if ($value === 'none') {
          return self::filter('withoutSegments');
        } else {
          $segment = Segment::findOne($value);
          if ($segment instanceof Segment) {
            return $segment->subscribers();
          }
        }
      }
    }
    return $orm;
  }

  public static function groupBy($orm, $group = null) {
    if ($group === 'trash') {
      return $orm->whereNotNull('deleted_at');
    } else if ($group === 'all') {
      return $orm->whereNull('deleted_at');
    } else {
      return $orm->filter($group);
    }
  }

  public static function filterWithCustomFields($orm) {
    $orm = $orm->select(MP_SUBSCRIBERS_TABLE . '.*');
    $customFields = CustomField::findArray();
    foreach ($customFields as $customField) {
      $orm = $orm->select_expr(
        'IFNULL(GROUP_CONCAT(CASE WHEN ' .
        MP_CUSTOM_FIELDS_TABLE . '.id=' . $customField['id'] . ' THEN ' .
        MP_SUBSCRIBER_CUSTOM_FIELD_TABLE . '.value END), NULL) as "' . $customField['name'] . '"');
    }
    $orm = $orm
      ->leftOuterJoin(
        MP_SUBSCRIBER_CUSTOM_FIELD_TABLE,
        [
          MP_SUBSCRIBERS_TABLE . '.id',
          '=',
          MP_SUBSCRIBER_CUSTOM_FIELD_TABLE . '.subscriber_id',
        ]
      )
      ->leftOuterJoin(
        MP_CUSTOM_FIELDS_TABLE,
        [
          MP_CUSTOM_FIELDS_TABLE . '.id',
          '=',
          MP_SUBSCRIBER_CUSTOM_FIELD_TABLE . '.custom_field_id',
        ]
      )
      ->groupBy(MP_SUBSCRIBERS_TABLE . '.id');
    return $orm;
  }

  /**
   * @deprecated
   */
  public static function filterWithCustomFieldsForExport($orm) {
    $orm = $orm->select(MP_SUBSCRIBERS_TABLE . '.*');
    $customFields = CustomField::findArray();
    foreach ($customFields as $customField) {
      $orm = $orm->selectExpr(
        'MAX(CASE WHEN ' .
        MP_CUSTOM_FIELDS_TABLE . '.id=' . $customField['id'] . ' THEN ' .
        MP_SUBSCRIBER_CUSTOM_FIELD_TABLE . '.value END) as "' . $customField['id'] . '"'
      );
    }
    $orm = $orm
      ->leftOuterJoin(
        MP_SUBSCRIBER_CUSTOM_FIELD_TABLE,
        [
          MP_SUBSCRIBERS_TABLE . '.id', '=',
          MP_SUBSCRIBER_CUSTOM_FIELD_TABLE . '.subscriber_id',
        ]
      )
      ->leftOuterJoin(
        MP_CUSTOM_FIELDS_TABLE,
        [
          MP_CUSTOM_FIELDS_TABLE . '.id','=',
          MP_SUBSCRIBER_CUSTOM_FIELD_TABLE . '.custom_field_id',
        ]
      );
    return $orm;
  }

  public static function getSubscribedInSegments($segmentIds) {
    $subscribers = SubscriberSegment::tableAlias('relation')
      ->whereIn('relation.segment_id', $segmentIds)
      ->where('relation.status', 'subscribed')
      ->join(
        MP_SUBSCRIBERS_TABLE,
        'subscribers.id = relation.subscriber_id',
        'subscribers'
      )
      ->select('subscribers.id')
      ->whereNull('subscribers.deleted_at')
      ->where('subscribers.status', 'subscribed')
      ->distinct();
    return $subscribers;
  }

  /**
   * @param string $customerEmail
   * @return bool|Subscriber
   */
  public static function getWooCommerceSegmentSubscriber($customerEmail) {
    $wcSegment = Segment::getWooCommerceSegment();
    return Subscriber::tableAlias('subscribers')
      ->select('subscribers.*')
      ->where('subscribers.email', $customerEmail)
      ->join(
        MP_SUBSCRIBER_SEGMENT_TABLE,
        'relation.subscriber_id = subscribers.id',
        'relation'
      )
      ->where('relation.segment_id', $wcSegment->id)
      ->where('relation.status', Subscriber::STATUS_SUBSCRIBED)
      ->whereIn('subscribers.status', [Subscriber::STATUS_SUBSCRIBED, Subscriber::STATUS_UNCONFIRMED])
      ->where('subscribers.is_woocommerce_user', 1)
      ->findOne();
  }

  public function customFields() {
    return $this->hasManyThrough(
      __NAMESPACE__ . '\CustomField',
      __NAMESPACE__ . '\SubscriberCustomField',
      'subscriber_id',
      'custom_field_id'
    )->select_expr(MP_SUBSCRIBER_CUSTOM_FIELD_TABLE . '.value');
  }

  public static function createOrUpdate($data = []) {
    $subscriber = false;
    if (is_array($data) && !empty($data)) {
      $data = WPFunctions::get()->stripslashesDeep($data);
    }

    if (isset($data['id']) && (int)$data['id'] > 0) {
      $subscriber = self::findOne((int)$data['id']);
      unset($data['id']);
    }

    if ($subscriber === false && !empty($data['email'])) {
      $subscriber = self::where('email', $data['email'])->findOne();
      if ($subscriber !== false) {
        unset($data['email']);
      }
    }

    // segments
    $segmentIds = false;
    if (array_key_exists('segments', $data)) {
      $segmentIds = (array)$data['segments'];
      unset($data['segments']);
    }

    // if new subscriber, make sure that required fields are set
    if (!$subscriber) {
      $data = self::setRequiredFieldsDefaultValues($data);
    }

    // get custom fields
    list($data, $customFields) = self::extractCustomFieldsFromFromObject($data);

    // wipe any unconfirmed data at this point
    $data['unconfirmed_data'] = null;

    $oldStatus = false;
    $newStatus = false;

    if ($subscriber === false) {
      $subscriber = self::create();
      $subscriber->hydrate($data);
    } else {
      $oldStatus = $subscriber->status;
      $subscriber->set($data);
      $newStatus = $subscriber->status;
    }

    // Update last_subscribed_at when status changes to subscribed
    if ($oldStatus !== self::STATUS_SUBSCRIBED && $subscriber->status === self::STATUS_SUBSCRIBED) {
      $subscriber->set('last_subscribed_at', WPFunctions::get()->currentTime('mysql'));
    }

    if ($subscriber->save()) {
      if (!empty($customFields)) {
        $subscriber->saveCustomFields($customFields);
      }

      // check for status change
      if (
          ($oldStatus === self::STATUS_SUBSCRIBED)
          &&
          ($newStatus === self::STATUS_UNSUBSCRIBED)
      ) {
        // make sure we unsubscribe the user from all segments
        SubscriberSegment::unsubscribeFromSegments($subscriber);
      } else {
        if ($segmentIds !== false) {
          SubscriberSegment::resetSubscriptions($subscriber, $segmentIds);
        }
      }
    }
    return $subscriber;
  }

  public function withCustomFields() {
    $customFields = CustomField::select('id')->findArray();
    if (empty($customFields)) return $this;

    $customFieldIds = array_column($customFields, 'id');
    $relations = SubscriberCustomField::select('custom_field_id')
      ->select('value')
      ->whereIn('custom_field_id', $customFieldIds)
      ->where('subscriber_id', $this->id())
      ->findMany();
    foreach ($relations as $relation) {
      $this->{'cf_' . $relation->customFieldId} = $relation->value;
    }

    return $this;
  }

  public function withSegments() {
    $this->segments = $this->segments()->findArray();
    return $this;
  }

  public function withSubscriptions() {
    $this->subscriptions = SubscriberSegment::where('subscriber_id', $this->id())
      ->findArray();
    return $this;
  }

  public function getCustomField($customFieldId, $default = null) {
    $customField = SubscriberCustomField::select('value')
      ->where('custom_field_id', $customFieldId)
      ->where('subscriber_id', $this->id())
      ->findOne();

    if ($customField instanceof SubscriberCustomField) {
      return $customField->value;
    } else {
      return $default;
    }
  }

  public function saveCustomFields($customFieldsData = []) {
    // get custom field ids
    $customFieldIds = array_keys($customFieldsData);

    // get custom fields
    $customFields = CustomField::whereIdIn($customFieldIds)->findMany();

    foreach ($customFields as $customField) {
      $value = (isset($customFieldsData[$customField->id])
        ? $customFieldsData[$customField->id]
        : null
      );
      // format value
      $value = $customField->formatValue($value);

      $this->setCustomField($customField->id, $value);
    }
  }

  public function setCustomField($customFieldId, $value) {
    return SubscriberCustomField::createOrUpdate([
      'subscriber_id' => $this->id(),
      'custom_field_id' => $customFieldId,
      'value' => $value,
    ]);
  }

  public function setUnconfirmedData(array $subscriberData) {
    $subscriberData = self::filterOutReservedColumns($subscriberData);
    $encoded = json_encode($subscriberData);
    if (is_string($encoded)) {
      $this->unconfirmedData = $encoded;
    }
  }

  public function getUnconfirmedData() {
    if (!empty($this->unconfirmedData)) {
      $subscriberData = json_decode($this->unconfirmedData, true);
      $subscriberData = self::filterOutReservedColumns((array)$subscriberData);
      return $subscriberData;
    }
    return null;
  }

  /**
   * @deprecated Use MailPoet\Util\License\Features\Subscribers::getSubscribersCount or \MailPoet\Subscribers\SubscribersRepository::getTotalSubscribers
   */
  public static function getTotalSubscribers() {
    return self::whereIn('status', [
      self::STATUS_SUBSCRIBED,
      self::STATUS_UNCONFIRMED,
      self::STATUS_INACTIVE,
    ])
    ->whereNull('deleted_at')
    ->count();
  }

  public static function getInactiveSubscribersCount() {
    return self::where('status', self::STATUS_INACTIVE)
    ->whereNull('deleted_at')
    ->count();
  }

  public static function subscribed($orm) {
    return $orm
      ->whereNull('deleted_at')
      ->where('status', self::STATUS_SUBSCRIBED);
  }

  public static function unsubscribed($orm) {
    return $orm
      ->whereNull('deleted_at')
      ->where('status', self::STATUS_UNSUBSCRIBED);
  }

  public static function unconfirmed($orm) {
    return $orm
      ->whereNull('deleted_at')
      ->where('status', self::STATUS_UNCONFIRMED);
  }

  public static function bounced($orm) {
    return $orm
      ->whereNull('deleted_at')
      ->where('status', self::STATUS_BOUNCED);
  }

  public static function inactive($orm) {
    return $orm
      ->whereNull('deleted_at')
      ->where('status', self::STATUS_INACTIVE);
  }

  public static function withoutSegments($orm) {
    return $orm->select(MP_SUBSCRIBERS_TABLE . '.*')
      ->whereRaw(
        MP_SUBSCRIBERS_TABLE . '.id NOT IN (
          SELECT `subscriber_id`
          FROM ' . MP_SUBSCRIBER_SEGMENT_TABLE . '
          WHERE `status` = "' . self::STATUS_SUBSCRIBED . '" AND `segment_id` IN (
            SELECT `id` FROM ' . MP_SEGMENTS_TABLE . ' WHERE `deleted_at` IS NULL
          )
        )'
      );
  }

  public static function createMultiple($columns, $values) {
    return self::rawExecute(
      'INSERT INTO `' . self::$_table . '` ' .
      '(' . implode(', ', $columns) . ') ' .
      'VALUES ' . rtrim(
        str_repeat(
          '(' . rtrim(str_repeat('?,', count($columns)), ',') . ')' . ', ',
          count($values)
        ),
        ', '
      ),
      Helpers::flattenArray($values)
    );
  }

  public static function updateMultiple($columns, $subscribers, $updatedAt = false) {
    $ignoreColumnsOnUpdate = [
      'wp_user_id',
      'is_woocommerce_user',
      'email',
      'created_at',
      'last_subscribed_at',
    ];
    // check if there is anything to update after excluding ignored columns
    if (!array_diff($columns, $ignoreColumnsOnUpdate)) return;
    $subscribers = array_map('array_values', $subscribers);
    $emailPosition = array_search('email', $columns);
    $sql =
      function($type) use (
        $columns,
        $subscribers,
        $emailPosition,
        $ignoreColumnsOnUpdate
      ) {
        return array_filter(
          array_map(function($columnPosition, $columnName) use (
            $type,
            $subscribers,
            $emailPosition,
            $ignoreColumnsOnUpdate
          ) {
            if (in_array($columnName, $ignoreColumnsOnUpdate)) return;
            $query = array_map(
              function($subscriber) use ($type, $columnPosition, $emailPosition) {
                return ($type === 'values') ?
                  [
                    $subscriber[$emailPosition],
                    $subscriber[$columnPosition],
                  ] :
                  'WHEN email = ? THEN ?';
              }, $subscribers);
            return ($type === 'values') ?
              Helpers::flattenArray($query) :
              $columnName . '= (CASE ' . implode(' ', $query) . ' END)';
          }, array_keys($columns), $columns)
        );
      };
    return self::rawExecute(
      'UPDATE `' . self::$_table . '` ' .
      'SET ' . implode(', ', $sql('statement')) . ' ' .
      (($updatedAt) ? ', updated_at = "' . $updatedAt . '" ' : '') .
      ', unconfirmed_data = NULL ' .
      'WHERE email IN ' .
      '(' . rtrim(str_repeat('?,', count($subscribers)), ',') . ')',
      array_merge(
        Helpers::flattenArray($sql('values')),
        array_column($subscribers, $emailPosition)
      )
    );
  }

  public static function findSubscribersInSegments(array $subscribersIds, array $segmentsIds) {
    return self::getSubscribedInSegments($segmentsIds)
      ->whereIn('subscribers.id', $subscribersIds)
      ->select('subscribers.*');
  }

  public static function extractSubscribersIds(array $subscribers) {
    return array_filter(
      array_map(function($subscriber) {
        return (!empty($subscriber->id)) ? $subscriber->id : false;
      }, $subscribers)
    );
  }

  public static function setRequiredFieldsDefaultValues($data) {
    $settings = SettingsController::getInstance();
    $requiredFieldDefaultValues = [
      'first_name' => '',
      'last_name' => '',
      'unsubscribe_token' => Security::generateUnsubscribeToken(self::class),
      'link_token' => Security::generateRandomString(self::LINK_TOKEN_LENGTH),
      'status' => (!$settings->get('signup_confirmation.enabled')) ? self::STATUS_SUBSCRIBED : self::STATUS_UNCONFIRMED,
    ];
    foreach ($requiredFieldDefaultValues as $field => $value) {
      if (!isset($data[$field])) {
        $data[$field] = $value;
      }
    }
    return $data;
  }

  public static function extractCustomFieldsFromFromObject($data) {
    $customFields = [];
    foreach ($data as $key => $value) {
      if (strpos($key, 'cf_') === 0) {
        $customFields[(int)substr($key, 3)] = $value;
        unset($data[$key]);
      }
    }
    return [$data, $customFields];
  }

  public function getAllSegmentNamesWithStatus() {
    return Segment::tableAlias('segment')
      ->select('name')
      ->select('subscriber_segment.segment_id', 'segment_id')
      ->select('subscriber_segment.status', 'status')
      ->select('subscriber_segment.updated_at', 'updated_at')
      ->join(
        SubscriberSegment::$_table,
        ['subscriber_segment.segment_id', '=', 'segment.id'],
        'subscriber_segment'
      )
      ->where('subscriber_segment.subscriber_id', $this->id)
      ->orderByAsc('name')
      ->findArray();
  }

  /**
   * This method is here only for BC fix of 3rd party plugin integration.
   * @see https://kb.mailpoet.com/article/195-add-subscribers-through-your-own-form-or-plugin
   * @deprecated
   */
  public static function subscribe($subscriberData = [], $segmentIds = []) {
    trigger_error('Calling Subscriber::subscribe() is deprecated and will be removed. Use MailPoet\API\MP\v1\API instead. ', E_USER_DEPRECATED);
    $service = ContainerWrapper::getInstance()->get(\MailPoet\Subscribers\SubscriberActions::class);
    return $service->subscribe($subscriberData, $segmentIds);
  }
}

Filemanager

Name Type Size Permission Actions
CustomField.php File 3.79 KB 0644
DynamicSegment.php File 4.05 KB 0644
DynamicSegmentFilter.php File 1.35 KB 0644
Form.php File 4.02 KB 0644
MappingToExternalEntities.php File 378 B 0644
Model.php File 13.58 KB 0644
ModelValidator.php File 2.44 KB 0644
Newsletter.php File 15.14 KB 0644
NewsletterLink.php File 530 B 0644
NewsletterOption.php File 670 B 0644
NewsletterOptionField.php File 939 B 0644
NewsletterSegment.php File 312 B 0644
ScheduledTask.php File 6.58 KB 0644
ScheduledTaskSubscriber.php File 5.31 KB 0644
Segment.php File 10.89 KB 0644
SendingQueue.php File 4.31 KB 0644
StatisticsClicks.php File 1.08 KB 0644
StatisticsForms.php File 1.85 KB 0644
StatisticsNewsletters.php File 1.61 KB 0644
StatisticsOpens.php File 807 B 0644
StatisticsUnsubscribes.php File 821 B 0644
StatisticsWooCommercePurchases.php File 1.5 KB 0644
Subscriber.php File 20.83 KB 0644
SubscriberCustomField.php File 2.5 KB 0644
SubscriberIP.php File 1.12 KB 0644
SubscriberSegment.php File 5.2 KB 0644
index.php File 0 B 0644