View source
<?php
namespace Drupal\simplenews\Entity;
use Drupal\Core\Entity\ContentEntityBase;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\simplenews\SubscriberInterface;
use Drupal\user\Entity\User;
use Drupal\user\UserInterface;
class Subscriber extends ContentEntityBase implements SubscriberInterface {
protected static $syncing;
public function getMessage() {
return $this
->get('message')->value;
}
public function setMessage($message) {
$this
->set('message', $message);
}
public function getStatus() {
return $this
->get('status')->value == SubscriberInterface::ACTIVE;
}
public function setStatus($status) {
$this
->set('status', $status ? SubscriberInterface::ACTIVE : SubscriberInterface::INACTIVE);
}
public function getMail() {
return $this
->get('mail')->value;
}
public function setMail($mail) {
$this
->set('mail', $mail);
}
public function getUserId() {
return $this
->get('uid')->target_id;
}
public function getUser() {
$uid = $this
->getUserId();
if ($uid && ($user = User::load($uid))) {
return $user;
}
elseif ($mail = $this
->getMail()) {
return user_load_by_mail($mail) ?: NULL;
}
else {
return NULL;
}
}
public function getLangcode() {
return $this
->get('langcode')->value;
}
public function setLangcode($langcode) {
$this
->set('langcode', $langcode);
}
public function fillFromAccount(AccountInterface $account) {
if (static::$syncing) {
return $this;
}
static::$syncing = TRUE;
$this
->set('uid', $account
->id());
$this
->setMail($account
->getEmail());
$this
->setLangcode($account
->getPreferredLangcode());
$this
->setStatus($account
->isActive());
foreach ($this
->getUserSharedFields($account) as $field_name) {
$this
->set($field_name, $account
->get($field_name)
->getValue());
}
static::$syncing = FALSE;
return $this;
}
public function copyToAccount(AccountInterface $account) {
if (!static::$syncing && ($fields = $this
->getUserSharedFields($account))) {
static::$syncing = TRUE;
foreach ($fields as $field_name) {
$account
->set($field_name, $this
->get($field_name)
->getValue());
}
if (!$account
->isNew()) {
$account
->save();
}
static::$syncing = FALSE;
}
}
public function getChanges() {
return unserialize($this
->get('changes')->value);
}
public function setChanges($changes) {
$this
->set('changes', serialize($changes));
}
public function isSubscribed($newsletter_id) {
foreach ($this->subscriptions as $item) {
if ($item->target_id == $newsletter_id) {
return $item->status == SIMPLENEWS_SUBSCRIPTION_STATUS_SUBSCRIBED;
}
}
return FALSE;
}
public function isUnsubscribed($newsletter_id) {
foreach ($this->subscriptions as $item) {
if ($item->target_id == $newsletter_id) {
return $item->status == SIMPLENEWS_SUBSCRIPTION_STATUS_UNSUBSCRIBED;
}
}
return FALSE;
}
public function getSubscription($newsletter_id) {
foreach ($this->subscriptions as $item) {
if ($item->target_id == $newsletter_id) {
return $item;
}
}
return FALSE;
}
public function getSubscribedNewsletterIds() {
$ids = [];
foreach ($this->subscriptions as $item) {
if ($item->status == SIMPLENEWS_SUBSCRIPTION_STATUS_SUBSCRIBED) {
$ids[] = $item->target_id;
}
}
return $ids;
}
public function subscribe($newsletter_id, $status = SIMPLENEWS_SUBSCRIPTION_STATUS_SUBSCRIBED, $source = 'unknown', $timestamp = REQUEST_TIME) {
if ($subscription = $this
->getSubscription($newsletter_id)) {
$subscription->status = $status;
}
else {
$data = [
'target_id' => $newsletter_id,
'status' => $status,
'source' => $source,
'timestamp' => $timestamp,
];
$this->subscriptions
->appendItem($data);
}
if ($status == SIMPLENEWS_SUBSCRIPTION_STATUS_SUBSCRIBED) {
\Drupal::moduleHandler()
->invokeAll('simplenews_subscribe', [
$this,
$newsletter_id,
]);
}
}
public function unsubscribe($newsletter_id, $source = 'unknown', $timestamp = REQUEST_TIME) {
if ($subscription = $this
->getSubscription($newsletter_id)) {
$subscription->status = SIMPLENEWS_SUBSCRIPTION_STATUS_UNSUBSCRIBED;
}
else {
$data = [
'target_id' => $newsletter_id,
'status' => SIMPLENEWS_SUBSCRIPTION_STATUS_UNSUBSCRIBED,
'source' => $source,
'timestamp' => $timestamp,
];
$this->subscriptions
->appendItem($data);
}
\Drupal::service('simplenews.spool_storage')
->deleteMails([
'snid' => $this
->id(),
'newsletter_id' => $newsletter_id,
]);
\Drupal::moduleHandler()
->invokeAll('simplenews_unsubscribe', [
$this,
$newsletter_id,
]);
}
public function postSave(EntityStorageInterface $storage, $update = TRUE) {
parent::postSave($storage, $update);
if ($user = $this
->getUser()) {
$this
->copyToAccount($user);
}
}
public function postCreate(EntityStorageInterface $storage) {
parent::postCreate($storage);
if ($user = $this
->getUser()) {
$this
->fillFromAccount($user);
}
}
protected function getUserSharedFields(UserInterface $user) {
$field_names = [];
if (\Drupal::config('simplenews.settings')
->get('subscriber.sync_fields')) {
foreach ($this
->getFieldDefinitions() as $field_definition) {
$field_name = $field_definition
->getName();
$user_field = $user
->getFieldDefinition($field_name);
if ($field_definition
->getTargetBundle() && isset($user_field) && $user_field
->getType() == $field_definition
->getType()) {
$field_names[] = $field_name;
}
}
}
return $field_names;
}
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
$fields['id'] = BaseFieldDefinition::create('integer')
->setLabel(t('Subscriber ID'))
->setDescription(t('Primary key: Unique subscriber ID.'))
->setReadOnly(TRUE)
->setSetting('unsigned', TRUE);
$fields['uuid'] = BaseFieldDefinition::create('uuid')
->setLabel(t('UUID'))
->setDescription(t('The subscriber UUID.'))
->setReadOnly(TRUE);
$fields['status'] = BaseFieldDefinition::create('boolean')
->setLabel(t('Status'))
->setDescription(t('Boolean indicating the status of the subscriber.'))
->setDefaultValue(TRUE);
$fields['mail'] = BaseFieldDefinition::create('email')
->setLabel(t('Email'))
->setDescription(t("The subscriber's email address."))
->setSetting('default_value', '')
->setRequired(TRUE)
->setDisplayOptions('form', [
'type' => 'email_default',
'settings' => [],
])
->setDisplayConfigurable('form', TRUE);
$fields['uid'] = BaseFieldDefinition::create('entity_reference')
->setLabel(t('User'))
->setDescription(t('The corresponding user.'))
->setSetting('target_type', 'user')
->setSetting('handler', 'default');
$fields['langcode'] = BaseFieldDefinition::create('language')
->setLabel(t('Language'))
->setDescription(t("The subscriber's preferred language."));
$fields['changes'] = BaseFieldDefinition::create('string_long')
->setLabel(t('Changes'))
->setDescription(t('Contains the requested subscription changes.'));
$fields['created'] = BaseFieldDefinition::create('created')
->setLabel(t('Created'))
->setDescription(t('The time that the subscriber was created.'));
$fields['subscriptions'] = BaseFieldDefinition::create('simplenews_subscription')
->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED)
->setLabel(t('Subscriptions'))
->setSetting('target_type', 'simplenews_newsletter')
->setDisplayOptions('form', [
'type' => 'simplenews_subscription_select',
'weight' => '0',
'settings' => [],
'third_party_settings' => [],
]);
return $fields;
}
public static function loadByMail($mail, $create = FALSE, $default_langcode = NULL) {
$subscriber = FALSE;
if ($mail) {
$subscribers = \Drupal::entityTypeManager()
->getStorage('simplenews_subscriber')
->loadByProperties([
'mail' => $mail,
]);
$subscriber = reset($subscribers);
}
if ($create && !$subscriber) {
$subscriber = static::create([
'mail' => $mail,
]);
if ($default_langcode) {
$subscriber
->setLangcode($default_langcode);
}
}
return $subscriber;
}
public static function loadByUid($uid, $create = FALSE) {
$subscriber = FALSE;
if ($uid) {
$subscribers = \Drupal::entityTypeManager()
->getStorage('simplenews_subscriber')
->loadByProperties([
'uid' => $uid,
]);
$subscriber = reset($subscribers);
}
if ($create && !$subscriber) {
$subscriber = static::create([
'uid' => $uid,
]);
}
return $subscriber;
}
}