first commit
This commit is contained in:
49
bundles/KupShop/UserBundle/Util/PhoneNumberValidator.php
Normal file
49
bundles/KupShop/UserBundle/Util/PhoneNumberValidator.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace KupShop\UserBundle\Util;
|
||||
|
||||
use KupShop\KupShopBundle\Util\System\CurlUtil;
|
||||
use KupShop\UserBundle\Dto\PhoneNumberValidationResult;
|
||||
use KupShop\UserBundle\Exception\PhoneValidationException;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\ExceptionInterface;
|
||||
|
||||
class PhoneNumberValidator
|
||||
{
|
||||
protected string $host;
|
||||
|
||||
public function __construct(
|
||||
protected CurlUtil $curlUtil,
|
||||
protected LoggerInterface $logger,
|
||||
) {
|
||||
$this->host = isRunningOnCluster() ? 'http://phonenumber-validator.services' : 'http://phonenumber-validator.wpjshop.cz';
|
||||
}
|
||||
|
||||
public function validate(string $phoneNumber, string $region = 'CZ'): PhoneNumberValidationResult
|
||||
{
|
||||
$payload = [
|
||||
'phone_number' => $phoneNumber,
|
||||
'region' => $region,
|
||||
];
|
||||
|
||||
try {
|
||||
$response = $this->curlUtil
|
||||
->getClient(['Content-Type' => 'application/json'])
|
||||
->request('POST', $this->host.'/validate', [
|
||||
'body' => json_encode($payload),
|
||||
])
|
||||
->toArray();
|
||||
} catch (ExceptionInterface $e) {
|
||||
$this->logger->notice('Phone validation error', ['error' => $e->getMessage()]);
|
||||
throw new PhoneValidationException('Validation failed');
|
||||
}
|
||||
|
||||
if ($response['valid'] === true) {
|
||||
return new PhoneNumberValidationResult($response['db_format'], $response['international_format'], $response['national_format']);
|
||||
}
|
||||
|
||||
throw new PhoneValidationException('Phone number is not valid');
|
||||
}
|
||||
}
|
||||
130
bundles/KupShop/UserBundle/Util/UserConsent.php
Normal file
130
bundles/KupShop/UserBundle/Util/UserConsent.php
Normal file
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
|
||||
namespace KupShop\UserBundle\Util;
|
||||
|
||||
use KupShop\IncomakerBundle\Util\IncomakerUtil;
|
||||
use KupShop\KupShopBundle\Email\NewsletterSubscribeEmail;
|
||||
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||
use KupShop\MailerLiteBundle\MailerLite;
|
||||
use KupShop\UserBundle\Event\UserNewsletterEvent;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
||||
use Symfony\Contracts\Service\Attribute\Required;
|
||||
|
||||
class UserConsent
|
||||
{
|
||||
protected $mailerlite;
|
||||
protected $incomaker;
|
||||
|
||||
#[Required]
|
||||
public EventDispatcherInterface $eventDispatcher;
|
||||
|
||||
/** @var SessionInterface */
|
||||
private $session;
|
||||
|
||||
/**
|
||||
* @required
|
||||
*/
|
||||
public function setSession(SessionInterface $session): void
|
||||
{
|
||||
$this->session = $session;
|
||||
}
|
||||
|
||||
/**
|
||||
* @required
|
||||
*/
|
||||
public function setMailerlite(?MailerLite $mailerlite)
|
||||
{
|
||||
$this->mailerlite = $mailerlite;
|
||||
}
|
||||
|
||||
/**
|
||||
* @required
|
||||
*/
|
||||
public function setIncomaker(?IncomakerUtil $incomakerUtil)
|
||||
{
|
||||
$this->incomaker = $incomakerUtil;
|
||||
}
|
||||
|
||||
public function updateNewsletter($userId, $newsletter = 'N', $new_user = true, $confirmed = false)
|
||||
{
|
||||
$user = \User::createFromId($userId);
|
||||
|
||||
if ($new_user && $this->incomaker) {
|
||||
$this->incomaker->addUser($user, $newsletter);
|
||||
}
|
||||
|
||||
if (($newsletter == 'Y') && ($user->get_news == 'N') && !$confirmed) {
|
||||
if (is_null($user->date_subscribe)) {
|
||||
return $this->sendConfirmationEmail($user->email);
|
||||
}
|
||||
}
|
||||
|
||||
$get_news = $user->get_news;
|
||||
if ($new_user || ($get_news != $newsletter)) {
|
||||
$qb = sqlQueryBuilder()->update('users')
|
||||
->set('get_news', ':news')->setParameter('news', $newsletter)
|
||||
->set('date_updated', 'NOW()')
|
||||
->where('id = :id')->setParameter('id', $userId);
|
||||
if ($newsletter == 'Y') {
|
||||
$qb->set('date_subscribe', 'NOW()');
|
||||
}
|
||||
if ($newsletter == 'N') {
|
||||
$qb->set('date_unsubscribe', 'NOW()');
|
||||
}
|
||||
|
||||
$this->eventDispatcher->dispatch(
|
||||
new UserNewsletterEvent($user->email),
|
||||
$newsletter == 'Y' ? UserNewsletterEvent::SUBSCRIBED : UserNewsletterEvent::UNSUBSCRIBED
|
||||
);
|
||||
$qb->execute();
|
||||
}
|
||||
|
||||
$result = true;
|
||||
|
||||
if ($newsletter == 'N') {
|
||||
if ($new_user || ($get_news == $newsletter)) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
if (findModule(\Modules::MAILERLITE)) {
|
||||
if ($this->mailerlite->error) {
|
||||
$result = false;
|
||||
} else {
|
||||
$mailerlite_update = $this->mailerlite->updateUser($user, $newsletter);
|
||||
$result = $mailerlite_update;
|
||||
}
|
||||
}
|
||||
|
||||
if (findModule(\Modules::INCOMAKER)) {
|
||||
if ($new_user || ($get_news != $newsletter)) {
|
||||
$incomaker_update = $this->incomaker->updateUser($user, $newsletter);
|
||||
$result &= $incomaker_update;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function sendConfirmationEmail($email)
|
||||
{
|
||||
$today = new \DateTime();
|
||||
$today = $today->format('d.m.Y');
|
||||
$code = md5($email.'-'.$today);
|
||||
|
||||
$emailService = ServiceContainer::getService(NewsletterSubscribeEmail::class);
|
||||
$message = $emailService->getEmail([
|
||||
'OVEROVACI_ADRESA' => path('kupshop_content_newsletter_subscribe', ['code' => $code, 'email' => $email], 0),
|
||||
'EMAIL_UZIVATELE' => $email,
|
||||
]);
|
||||
$message['to'] = $email;
|
||||
$emailService->sendEmail($message);
|
||||
|
||||
if (!isAdministration()) {
|
||||
addUserMessage(translate('emailSuccessSent', 'newsletter'), 'success');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
101
bundles/KupShop/UserBundle/Util/UserExporter.php
Normal file
101
bundles/KupShop/UserBundle/Util/UserExporter.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
namespace KupShop\UserBundle\Util;
|
||||
|
||||
use Query\Operator;
|
||||
|
||||
class UserExporter
|
||||
{
|
||||
public function exportUsers($IDs)
|
||||
{
|
||||
$xml = new \SimpleXMLElement('<?xml version="1.0" encoding="utf-8"?> <USERS/>');
|
||||
|
||||
// TODO: TMP: #15311
|
||||
$emails = [];
|
||||
|
||||
foreach ($this->getUsers($IDs) as $user) {
|
||||
if (!filter_var($user['email'], FILTER_VALIDATE_EMAIL)) {
|
||||
continue;
|
||||
}
|
||||
$emails[$user['email']] = $user['pohoda_id'] ?? '-';
|
||||
$this->addUserToXML($xml, $user);
|
||||
}
|
||||
|
||||
getLogger()->notice('Pohoda:Users export: '.print_r($emails, true));
|
||||
|
||||
return $xml->asXML();
|
||||
}
|
||||
|
||||
protected function addUserToXML(\SimpleXMLElement &$xml, $user)
|
||||
{
|
||||
$baseElement = $xml->addChild('USER');
|
||||
$baseElement->ID = $user['id'];
|
||||
$baseElement->EMAIL = $user['email'];
|
||||
$baseElement->CURRENCY = $user['currency'];
|
||||
|
||||
$groupsElement = $baseElement->addChild('GROUPS');
|
||||
$groups = $this->getGroups($user['id']);
|
||||
foreach ($groups as $group) {
|
||||
$groupElement = $groupsElement->addChild('GROUP');
|
||||
$groupElement->ID = $group['id_group'];
|
||||
}
|
||||
|
||||
$invoiceElement = $baseElement->addChild('INVOICE');
|
||||
$invoiceElement->NAME = $user['name'];
|
||||
$invoiceElement->SURNAME = $user['surname'];
|
||||
$invoiceElement->COMPANY = $user['firm'];
|
||||
$invoiceElement->ADDRESS = $user['street'];
|
||||
$invoiceElement->CITY = $user['city'];
|
||||
$invoiceElement->ZIP = $user['zip'];
|
||||
$invoiceElement->COUNTRY = $user['country'];
|
||||
$invoiceElement->ICO = $user['ico'];
|
||||
$invoiceElement->DIC = $user['dic'];
|
||||
$invoiceElement->PHONE = $user['phone'];
|
||||
$invoiceElement->ADDRESS2 = $user['custom_address'];
|
||||
$invoiceElement->STATE = $user['state'];
|
||||
|
||||
$deliveryElement = $baseElement->addChild('DELIVERY');
|
||||
$deliveryElement->NAME = $user['delivery_name'];
|
||||
$deliveryElement->SURNAME = $user['delivery_surname'];
|
||||
$deliveryElement->COMPANY = $user['delivery_firm'];
|
||||
$deliveryElement->ADDRESS = $user['delivery_street'];
|
||||
$deliveryElement->CITY = $user['delivery_city'];
|
||||
$deliveryElement->ZIP = $user['delivery_zip'];
|
||||
$deliveryElement->COUNTRY = $user['delivery_country'];
|
||||
$deliveryElement->PHONE = $user['delivery_phone'];
|
||||
$deliveryElement->ADDRESS2 = $user['delivery_custom_address'];
|
||||
$deliveryElement->STATE = $user['delivery_state'];
|
||||
|
||||
$dateElement = $baseElement->addChild('DATE');
|
||||
$dateElement->REG = $user['date_reg'];
|
||||
$dateElement->SUBSCRIBE = $user['date_subscribe'];
|
||||
$dateElement->UNSUBSCRIBE = $user['date_unsubscribe'];
|
||||
|
||||
$this->addAdditionalFields($baseElement, $user);
|
||||
}
|
||||
|
||||
private function getGroups($userId)
|
||||
{
|
||||
return sqlQueryBuilder()
|
||||
->select('*')
|
||||
->from('users_groups_relations')
|
||||
->andWhere(Operator::equals(['id_user' => $userId]))
|
||||
->execute()
|
||||
->fetchAll();
|
||||
}
|
||||
|
||||
protected function getUsers($IDs)
|
||||
{
|
||||
return sqlQueryBuilder()
|
||||
->select('*')
|
||||
->from('users')
|
||||
->andWhere(Operator::inStringArray($IDs, 'id'))
|
||||
->sendToMaster()
|
||||
->execute()
|
||||
->fetchAll();
|
||||
}
|
||||
|
||||
protected function addAdditionalFields(&$baseElement, $user)
|
||||
{
|
||||
}
|
||||
}
|
||||
42
bundles/KupShop/UserBundle/Util/UserExporterDoc.xml
Normal file
42
bundles/KupShop/UserBundle/Util/UserExporterDoc.xml
Normal file
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<USERS>
|
||||
<USER>
|
||||
<ID>2</ID> <!-- Id uživatele -->
|
||||
<EMAIL>wpj@wpj.cz</EMAIL>
|
||||
<CURRENCY>CZK</CURRENCY>
|
||||
|
||||
<INVOICE>
|
||||
<NAME>WpjName</NAME>
|
||||
<SURNAME>WpjSurname</SURNAME>
|
||||
<COMPANY>wpj s. r. o.</COMPANY>
|
||||
<ADDRESS>Fügnerova 1288</ADDRESS>
|
||||
<CITY>Vrchlabí</CITY>
|
||||
<ZIP>54301</ZIP>
|
||||
<COUNTRY>CZ</COUNTRY>
|
||||
<ICO>77885544</ICO>
|
||||
<DIC>CZ2775665</DIC>
|
||||
<PHONE>+420775131478</PHONE>
|
||||
<ADDRESS2>custom address</ADDRESS2> <!-- Upřesnění adresy (není vyplněné vždy) -->
|
||||
<STATE>stát/region</STATE> <!-- Stát/region (není vyplněné vždy) -->
|
||||
</INVOICE>
|
||||
|
||||
<DELIVERY>
|
||||
<NAME>WpjDeliveryName</NAME>
|
||||
<SURNAME>WpjDeliverySurname</SURNAME>
|
||||
<COMPANY>wpj s.r.o.</COMPANY>
|
||||
<ADDRESS>TeSt tEsT 55</ADDRESS>
|
||||
<CITY>Vrchlabí</CITY>
|
||||
<ZIP>50000</ZIP>
|
||||
<COUNTRY>CZ</COUNTRY>
|
||||
<PHONE>+420123456789</PHONE>
|
||||
<ADDRESS2>custom address delivery</ADDRESS2> <!-- Upřesnění adresy (není vyplněné vždy) -->
|
||||
<STATE>stát/region</STATE> <!-- Stát/region (není vyplněné vždy) -->
|
||||
</DELIVERY>
|
||||
|
||||
<DATE>
|
||||
<REG>2020-03-18 08:53:57</REG>
|
||||
<SUBSCRIBE>2015-02-16 00:00:00</SUBSCRIBE>
|
||||
<UNSUBSCRIBE>2018-02-16 00:00:00</UNSUBSCRIBE>
|
||||
</DATE>
|
||||
</USER>
|
||||
</USERS>
|
||||
163
bundles/KupShop/UserBundle/Util/UserImporter.php
Normal file
163
bundles/KupShop/UserBundle/Util/UserImporter.php
Normal file
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
namespace KupShop\UserBundle\Util;
|
||||
|
||||
use KupShop\KupShopBundle\Util\StringUtil;
|
||||
use Query\Operator;
|
||||
|
||||
class UserImporter
|
||||
{
|
||||
protected $mainIdentifier = 'id';
|
||||
|
||||
/**
|
||||
* @param $xml string | \DomDocument
|
||||
*/
|
||||
public function importUsers($xml)
|
||||
{
|
||||
if ($xml instanceof \DOMDocument) {
|
||||
$users = simplexml_import_dom($xml);
|
||||
} else {
|
||||
$users = simplexml_load_string($xml);
|
||||
}
|
||||
|
||||
$usersArray = [];
|
||||
foreach ($users as $user) {
|
||||
if (!filter_var(trim(strval($user->EMAIL)), FILTER_VALIDATE_EMAIL)) {
|
||||
continue;
|
||||
}
|
||||
$userArray = $this->importUser($user);
|
||||
$usersArray[trim(StringUtil::normalize($userArray['email']))] = $userArray;
|
||||
}
|
||||
|
||||
$existingUsers = $this->getExistingUsers($usersArray);
|
||||
|
||||
foreach ($usersArray as $localUser) {
|
||||
if (!empty($localUser['groups']->GROUP)) {
|
||||
foreach ($localUser['groups']->GROUP as $group) {
|
||||
$params = [
|
||||
'group_id' => (string) $group->ID,
|
||||
'email' => $localUser['email'],
|
||||
];
|
||||
if ((string) $group->VALUE == 'true') {
|
||||
sqlQuery('INSERT IGNORE INTO users_groups_relations (id_group, id_user)
|
||||
SELECT :group_id, id
|
||||
FROM users
|
||||
WHERE email = :email', $params);
|
||||
} else {
|
||||
sqlQuery(
|
||||
'DELETE FROM users_groups_relations
|
||||
WHERE id_group = :group_id
|
||||
AND id_user = (SELECT id FROM users WHERE email=:email )', $params);
|
||||
}
|
||||
}
|
||||
}
|
||||
unset($localUser['groups']);
|
||||
|
||||
$this->processUser($localUser, $existingUsers);
|
||||
}
|
||||
}
|
||||
|
||||
public function importUser($user)
|
||||
{
|
||||
$userArray = [
|
||||
// INVOICE
|
||||
'name' => strval($user->INVOICE->NAME),
|
||||
'surname' => strval($user->INVOICE->SURNAME),
|
||||
'firm' => strval($user->INVOICE->COMPANY),
|
||||
'street' => strval($user->INVOICE->ADDRESS),
|
||||
'city' => strval($user->INVOICE->CITY),
|
||||
'zip' => strval($user->INVOICE->ZIP),
|
||||
'country' => strval($user->INVOICE->COUNTRY),
|
||||
'email' => trim(strval($user->EMAIL)),
|
||||
'ico' => strval($user->INVOICE->ICO),
|
||||
'dic' => strval($user->INVOICE->DIC),
|
||||
'phone' => strval($user->INVOICE->PHONE),
|
||||
'custom_address' => strval($user->INVOICE->ADDRESS2),
|
||||
'state' => strval($user->INVOICE->STATE),
|
||||
|
||||
// DELIVERY
|
||||
'delivery_name' => strval($user->DELIVERY->NAME),
|
||||
'delivery_surname' => strval($user->DELIVERY->SURNAME),
|
||||
'delivery_firm' => strval($user->DELIVERY->COMPANY),
|
||||
'delivery_street' => strval($user->DELIVERY->ADDRESS),
|
||||
'delivery_city' => strval($user->DELIVERY->CITY),
|
||||
'delivery_zip' => strval($user->DELIVERY->ZIP),
|
||||
'delivery_country' => strval($user->DELIVERY->COUNTRY),
|
||||
'delivery_phone' => strval($user->DELIVERY->PHONE),
|
||||
'delivery_custom_address' => strval($user->DELIVERY->ADDRESS2),
|
||||
'delivery_state' => strval($user->DELIVERY->STATE),
|
||||
|
||||
// DATE
|
||||
'date_reg' => strval($user->DATE->REG),
|
||||
'date_subscribe' => strval($user->DATE->SUBSCRIBE),
|
||||
'date_unsubscribe' => strval($user->DATE->UNSUBSCRIBE),
|
||||
'groups' => $user->GROUPS,
|
||||
];
|
||||
|
||||
$this->addAdditionalFields($userArray, $user);
|
||||
|
||||
return $userArray;
|
||||
}
|
||||
|
||||
protected function getExistingUsers($usersArray)
|
||||
{
|
||||
$identifierArray = array_column($usersArray, $this->mainIdentifier);
|
||||
$emailsArray = array_column($usersArray, 'email');
|
||||
|
||||
$myUsers = $this->selectExistingUsers($emailsArray, $identifierArray);
|
||||
|
||||
$convertedUsers = [];
|
||||
foreach ($myUsers as $user) {
|
||||
$convertedUsers[trim(StringUtil::normalize($user['email']))] = $user[$this->mainIdentifier];
|
||||
}
|
||||
|
||||
return $convertedUsers;
|
||||
}
|
||||
|
||||
protected function selectExistingUsers($emailsArray, $identifierArray)
|
||||
{
|
||||
return sqlQueryBuilder()
|
||||
->select($this->mainIdentifier.',email')
|
||||
->from('users')
|
||||
->andWhere(Operator::orX(Operator::inStringArray($emailsArray, 'email'), Operator::inIntArray($identifierArray, $this->mainIdentifier)))
|
||||
->execute()
|
||||
->fetchAll();
|
||||
}
|
||||
|
||||
protected function addAdditionalFields(&$userArray, \SimpleXMLElement $user)
|
||||
{
|
||||
}
|
||||
|
||||
protected function insertUserAction($userId)
|
||||
{
|
||||
}
|
||||
|
||||
protected function processUser(array $localUser, array $existingUsers): void
|
||||
{
|
||||
if (array_key_exists(trim(StringUtil::normalize($localUser['email'])), $existingUsers)) {
|
||||
sqlQueryBuilder()
|
||||
->update('users')
|
||||
->directValues($localUser)
|
||||
->andWhere(Operator::equals(['email' => $localUser['email']]))
|
||||
->execute();
|
||||
} elseif (array_key_exists($this->mainIdentifier, $localUser) && in_array($localUser[$this->mainIdentifier], $existingUsers)) {
|
||||
sqlQueryBuilder()
|
||||
->update('users')
|
||||
->directValues($localUser)
|
||||
->andWhere(Operator::equals([$this->mainIdentifier => $localUser[$this->mainIdentifier]]))
|
||||
->execute();
|
||||
} else {
|
||||
$this->beforeInsertUserAction($localUser);
|
||||
sqlQueryBuilder()
|
||||
->insert('users')
|
||||
->directValues($localUser)
|
||||
->execute();
|
||||
$userId = sqlInsertId();
|
||||
$this->insertUserAction($userId);
|
||||
}
|
||||
}
|
||||
|
||||
protected function beforeInsertUserAction($userRow)
|
||||
{
|
||||
}
|
||||
}
|
||||
50
bundles/KupShop/UserBundle/Util/UserImporterDoc.xml
Normal file
50
bundles/KupShop/UserBundle/Util/UserImporterDoc.xml
Normal file
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<USERS>
|
||||
<USER>
|
||||
<!-- Id uživatele -->
|
||||
<!--
|
||||
LZE POUZIT POUZE V PRIPADNE PRAZDNE DATABAZE UZIVATELU.
|
||||
JINAK DOJDE K AKTUALIZACI PODLE ID, TZN. MUZE PREPSAT UPLNE CIZI KONTAKT.
|
||||
<ID>1</ID>
|
||||
-->
|
||||
|
||||
<!-- Data uživatele -->
|
||||
<EMAIL>wpj@wpj.cz</EMAIL>
|
||||
|
||||
<INVOICE>
|
||||
<NAME>Test</NAME>
|
||||
<SURNAME>Wpj</SURNAME>
|
||||
<COMPANY>wpj s.r.o.</COMPANY>
|
||||
<ADDRESS>Ulice 12</ADDRESS>
|
||||
<CITY>Mesto</CITY>
|
||||
<ZIP>54321</ZIP>
|
||||
<COUNTRY>CZ</COUNTRY>
|
||||
<ICO>12345678</ICO>
|
||||
<DIC>CZ12345678</DIC>
|
||||
<PHONE>777 777 777</PHONE>
|
||||
<ADDRESS2>Firma wpj s.r.o.</ADDRESS2> <!-- Upřesnění adresy (není vyplněné vždy) -->
|
||||
<STATE>Stát/region</STATE> <!-- Stát/region (není vyplněné vždy) -->
|
||||
</INVOICE>
|
||||
|
||||
<!-- Dodací adresa -->
|
||||
<DELIVERY>
|
||||
<NAME>Test</NAME>
|
||||
<SURNAME>Wpj</SURNAME>
|
||||
<COMPANY>wpj s.r.o.</COMPANY>
|
||||
<ADDRESS>Ulice 12</ADDRESS>
|
||||
<CITY>Mesto</CITY>
|
||||
<ZIP>12345</ZIP>
|
||||
<COUNTRY>CZ</COUNTRY>
|
||||
<PHONE>777 777 777</PHONE>
|
||||
<ADDRESS2>Firma wpj s.r.o.</ADDRESS2> <!-- Upřesnění adresy (není vyplněné vždy) -->
|
||||
<STATE>Královehradecká kraj</STATE> <!-- Stát/region (není vyplněné vždy) -->
|
||||
</DELIVERY>
|
||||
|
||||
<!-- Datum -->
|
||||
<DATE>
|
||||
<REG>2020-05-25 13:58:22</REG>
|
||||
<SUBSCRIBE>2020-05-25 13:58:23</SUBSCRIBE>
|
||||
<UNSUBSCRIBE>2020-05-25 13:58:24</UNSUBSCRIBE>
|
||||
</DATE>
|
||||
</USER>
|
||||
</USERS>
|
||||
Reference in New Issue
Block a user