Files
kupshop/admin/users.php
2025-08-02 16:30:27 +02:00

395 lines
14 KiB
PHP

<?php
$main_class = 'Users';
use KupShop\KupShopBundle\Context\ContextManager;
use KupShop\KupShopBundle\Context\DomainContext;
use KupShop\KupShopBundle\Context\LanguageContext;
use KupShop\KupShopBundle\Email\PasswordResetAdminEmail;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\Contexts;
use KupShop\UserBundle\Exception\PhoneValidationException;
use Query\Operator;
class Users extends Window
{
protected $nameField = 'email';
protected $required = [
'email' => true,
];
public function get_vars()
{
$ID = $this->getID();
$acn = $this->getAction();
$vars = parent::get_vars();
$pageVars = getVal('body', $vars);
$pageVars['delivery_type'] = DeliveryType::getAll(true);
$pageVars['data']['data'] = $pageVars['data']['custom_data'] ?? null;
$this->unserializeCustomData($pageVars['data']);
if (findModule(Modules::PRICELISTS)) {
$qbPriceLists = sqlQueryBuilder()
->select('id, name')
->from('pricelists');
foreach ($qbPriceLists->execute() as $item) {
$pageVars['priceLists'][$item['id']] = $item;
}
}
if (!empty($pageVars['data']['date_reg'])) {
$datediff = time() - strtotime(substr($pageVars['data']['date_reg'], 0, 10));
$pageVars['data']['date_reg_days'] = floor($datediff / (60 * 60 * 24));
} else {
$pageVars['data']['date_reg_days'] = '0';
}
if (findModule(Modules::PRODUCTS_FAVORITES)) {
$pageVars['favorites'] = returnSQLResult('SELECT COUNT(*)
FROM products_favorites
WHERE id_user='.intval($ID));
} elseif (findModule(Modules::SHOPPING_LIST)) {
$id_list = sqlQueryBuilder()->select('id')
->from('shopping_list')
->andWhere(Operator::equals(['id_user' => $ID, 'label' => 'favorites']))
->execute()->fetchOne();
if ($id_list) {
$pageVars['favorites'] = sqlQueryBuilder()->select('COUNT(id)')
->from('shopping_list_products')
->andWhere(Operator::equals(['id_shopping_list' => $id_list]))
->execute()->fetchOne();
}
}
$SQL = sqlQuery('SELECT COUNT(*) AS pocet, SUM(total_price*currency_rate) AS cena_celkem
FROM '.getTableName('orders').'
WHERE id_user='.intval($ID).' AND status_storno=0 ');
foreach ($SQL as $row) {
$pageVars['orders']['pocet'] = $row['pocet'];
if ($row['cena_celkem'] > 0) {
$pageVars['orders']['average_price'] = $row['cena_celkem'] / $row['pocet'];
}
}
$pageVars['cena_celkem'] = returnSQLResult('SELECT SUM(total_price*currency_rate) AS cena_celkem
FROM '.getTableName('orders').'
WHERE id_user='.intval($ID)." AND status_storno=0
AND YEAR(date_created) = '".date('Y')."'");
$pageVars['lastYearOrdersPrice'] = sqlQueryBuilder()->select('SUM(total_price*currency_rate)')
->from('orders')
->where('id_user=:id_user AND date_created > DATE_SUB( NOW(), INTERVAL 1 YEAR) AND status_storno=0')
->setParameter('id_user', $ID)
->execute()->fetchColumn();
$pageVars['sales'] = $this->getSalesStats();
if (findModule(\Modules::WATCHDOG)) {
$pageVars['countWatchdogProducts'] = sqlQueryBuilder()->select('COUNT(id_user)')
->from('products_watchdog')
->where('id_user=:id_user')
->setParameter('id_user', $ID)
->execute()->fetchColumn();
}
$pageVars['allOrdersPrice'] = sqlQueryBuilder()->select('SUM(total_price*currency_rate)')
->from('orders')
->where('id_user=:id_user')
->andWhere('status_storno!=1')
->setParameter('id_user', $ID)
->execute()->fetchColumn();
$languageContext = Contexts::get(LanguageContext::class);
$pageVars['languages'] = $languageContext->getAll();
if (findModule(Modules::PRICE_LEVELS)) {
$user_price_level = sqlQueryBuilder()->select('id_price_level')
->from('users_dealer_price_level')
->andWhere(Operator::equals(['id_user' => $ID]))
->execute()->fetchOne();
$pageVars['data']['dealer_price_level'] = $user_price_level ?: 0;
}
if ($acn == 'add') {
$pageVars['data']['date_reg'] = date('Y-m-d');
$pageVars['data']['figure'] = 'Y';
$pageVars['data']['get_news'] = 'N';
$pageVars['data']['dealer_price_level'] = 0;
}
if ($acn == 'edit') {
// Users
$SQL = sqlQuery('SELECT id_group
FROM '.getTableName('users_groups_relations')."
WHERE id_user='".$ID."'");
$user_groups = [];
while ($row = sqlFetchArray($SQL)) {
$user_groups[$row['id_group']] = [
'checked' => 1,
];
}
$SQL = sqlQuery('SELECT id, name
FROM '.getTableName('users_groups'));
foreach ($SQL as $row) {
$user_groups[$row['id']] = array_merge(getVal($row['id'], $user_groups, []), $row);
}
$pageVars['user_groups'] = $user_groups;
}
$vars['body'] = $pageVars;
return $vars;
}
public function getData()
{
$data = parent::getData();
if (getVal('Submit')) {
if (($data['id_language'] ?? false) === 'null') {
$data['id_language'] = null;
}
if (empty($data['dealer_price_level'])) {
$data['dealer_price_level'] = 0;
}
if (findModule(\Modules::XML_FEEDS_B2B, \Modules::SUB_SECURE)) {
if (!empty($data['feed_activated']) && $data['feed_activated'] == 'Y') {
if (empty($data['feed_token'])) {
$data['feed_token'] = $this->generateToken(15);
}
if ($data['feed_in_store'] == 'Y') {
$data['feed_in_store'] = '1';
} else {
$data['feed_in_store'] = '0';
}
} else {
$data['feed_token'] = '';
$data['feed_in_store'] = $data['feed_in_store'] == 'Y' ? '1' : '0';
}
}
if (empty($data['gender'])) {
$data['gender'] = null;
}
if (empty($data['id_pricelist'])) {
$data['id_pricelist'] = null;
}
$data['date_updated'] = (new DateTime())->format('Y-m-d H:i:s');
if ($data['feed_activated'] && findModule(\Modules::XML_FEEDS_B2B, \Modules::SUB_FEED_IDS)
&& !isset($data['custom_data']['b2b_feeds'])
) {
$data['custom_data']['b2b_feeds'] = [];
}
$data['data'] = $this->getObject()['custom_data'] ?? null;
$this->unserializeCustomData($data);
$data['data'] = array_merge($data['data'], $data['custom_data'] ?? []);
$this->serializeCustomData($data);
$data['custom_data'] = $data['data'];
if ($data['figure'] == 'Y' && empty($data['date_reg'])) {
$data['date_reg'] = (new DateTime())->format('Y-m-d H:i:s');
}
if ($data['birthdate'] ?? false) {
$data['birthdate'] = $this->prepareDate($data['birthdate']);
}
if (($data['phone'] ?? false) && findModule(\Modules::USERS, \Modules::SUB_USERS_PHONE_LOGIN)) {
$data['phone'] = $this->validatePhoneNumber($data);
}
}
return $data;
}
public function getSQLFields($data = null, $fields = null, $defaults = null, $types = null)
{
$sqlField = parent::getSQLFields($data, $fields, $defaults, $types);
if (isset($sqlField['get_news'])) {
unset($sqlField['get_news']);
// get_news and dates (subscribe/unsubscribe) are updated with UserConsent service
}
return $sqlField;
}
public function handleUpdate()
{
$SQL = parent::handleUpdate();
if ($SQL) {
$data = $this->getData();
$ID = $this->getID();
if (!empty($data['email'])) {
sqlQuery('DELETE FROM '.getTableName('users').' WHERE email = :email AND figure=\'N\' AND id != :id', ['email' => $data['email'], 'id' => $this->getID()]);
}
if (!empty($data['password']) && !empty($data['figure']) && $data['figure'] == 'Y') {
if (empty($ID)) {
$ID = sqlInsertID();
}
$user = User::createFromId($ID);
$user->updatePassword($data['password']);
}
// dealerske slevy
if (findModule(Modules::PRICE_LEVELS)) {
sqlQueryBuilder()->delete('users_dealer_price_level')
->andWhere(Operator::equals(['id_user' => $ID]))->execute();
if ($data['dealer_price_level'] > 0) {
sqlQueryBuilder()->insert('users_dealer_price_level')
->directValues(['id_user' => $ID, 'id_price_level' => $data['dealer_price_level']])
->execute();
}
}
// ############################################
// # ZARAZENI UZIVATELE DO SKUPINY
$groups = getVal('groups', $data, []);
sqlQuery('DELETE FROM '.getTableName('users_groups_relations')."
WHERE id_user='".$ID."' ");
foreach ($groups as $id_group => $group) {
if (!empty($group['use'])) {
sqlQuery('INSERT INTO '.getTableName('users_groups_relations')."
SET id_group='{$id_group}', id_user='{$ID}'");
}
}
$newsletter = getVal('get_news', $data, 'N');
$new_user = ($this->getAction() == 'add');
$userConsent = ServiceContainer::getService(\KupShop\UserBundle\Util\UserConsent::class);
$userConsent->updateNewsletter($ID, $newsletter, $new_user, true);
}
return $SQL;
}
public function generateToken($size = 20)
{
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$count = mb_strlen($chars);
for ($i = 0, $password = ''; $i < $size; $i++) {
$index = rand(0, $count - 1);
$password .= mb_substr($chars, $index, 1);
}
return $password;
}
public function handleRegenerateToken()
{
$this->updateSQL('users', ['feed_token' => $this->generateToken(15)], ['id' => $this->getID()]);
$this->returnOK('Přegenerováno');
}
public function handleDelete()
{
if (findModule(Modules::MAILERLITE)) {
$mailerlite = ServiceContainer::getService(\KupShop\MailerLiteBundle\MailerLite::class);
if (!$mailerlite->error) {
$user = User::createFromId($this->getID());
if ($user) {
$mailerlite_update = $mailerlite->updateUser($user, 'N');
}
}
}
$SQL = parent::handleDelete();
}
public function handleEmailChangePass()
{
if (!$this->forceUpdate()) {
return false;
}
$data = $this->getData();
$res = false;
if (!empty($data['email'])) {
$user = User::createFromId($this->getID());
if ($user) {
$contextManager = ServiceContainer::getService(ContextManager::class);
$emailService = ServiceContainer::getService(PasswordResetAdminEmail::class);
$message = null;
$contextManager->activateContexts(
[
LanguageContext::class => $user->id_language ?? null,
DomainContext::class => $contextManager->getDomainFromLanguage($user->id_language ?? null),
],
function () use (&$message, $emailService, $user) {
$emailService->setUser($user);
$message = $emailService->getEmail();
}
);
$message['to'] = $user['email'];
$res = $emailService->sendEmail($message);
}
}
if ($res) {
$this->returnOK("Odesláno na email {$data['email']}");
} else {
$this->returnError('Nepodařilo se odeslat');
}
}
protected function getSalesStats(): array
{
if (!findModule(Modules::SALES)) {
return [];
}
$baseQb = sqlQueryBuilder()
->from('sales')
->where(Operator::equals(['id_user' => $this->getID()]));
$data = (clone $baseQb)->select('COUNT(*) AS count, SUM(total_price) AS total_price')
->execute()->fetchAssociative();
$data['last_year_total_price'] = (clone $baseQb)->select('SUM(total_price) AS total_price')
->andWhere('date_created > DATE_SUB(NOW(), INTERVAL 1 YEAR)')
->execute()->fetchOne();
$data['current_year_total_price'] = (clone $baseQb)->select('SUM(total_price) AS total_price')
->andWhere('YEAR(date_created) = :year')
->setParameter('year', date('Y'))
->execute()->fetchOne();
return $data;
}
public function validatePhoneNumber(array $input): string
{
$validator = ServiceContainer::getService(\KupShop\UserBundle\Util\PhoneNumberValidator::class);
try {
$validated = $validator->validate($input['phone'], $input['country']);
} catch (PhoneValidationException $e) {
$this->returnError('Selhala validace telefoního čísla');
}
return $validated->dbNumber ?? '';
}
}