first commit

This commit is contained in:
2025-08-02 16:30:27 +02:00
commit 23646bfcee
14851 changed files with 1750626 additions and 0 deletions

View 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');
}
}

View 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;
}
}

View 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)
{
}
}

View 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>

View 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)
{
}
}

View 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>