first commit
This commit is contained in:
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
.php text eol=lf
|
||||||
11
.gitignore
vendored
Normal file
11
.gitignore
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/vendor
|
||||||
|
/vendor-cache
|
||||||
|
/vendor-shared
|
||||||
|
/node_modules
|
||||||
|
/.php-cs-fixer.cache
|
||||||
|
/.php-cs-fixer.shop.cache
|
||||||
|
/.twig-cs-fixer.cache
|
||||||
|
*.bak
|
||||||
|
*po~
|
||||||
|
/admin/static/build/
|
||||||
|
.DS_Store
|
||||||
4
.gitlab-ci.yml
Normal file
4
.gitlab-ci.yml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
include:
|
||||||
|
- project: kupshop/ci
|
||||||
|
file: gitlab-ci-engine.yml
|
||||||
|
ref: master
|
||||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "smarty"]
|
||||||
|
path = jquery/bootflat_v2
|
||||||
|
url = git@github.com:bootflat/bootflat.github.io.git
|
||||||
15
.htaccess
Normal file
15
.htaccess
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#Caching
|
||||||
|
#php_flag zlib.output_compression on
|
||||||
|
|
||||||
|
#SetOutputFilter DEFLATE
|
||||||
|
|
||||||
|
ExpiresActive on
|
||||||
|
ExpiresDefault "access plus 8 hours"
|
||||||
|
ExpiresByType text/html "now"
|
||||||
|
ExpiresByType text/xml "now"
|
||||||
|
ExpiresByType text/css "access plus 8 hours"
|
||||||
|
ExpiresByType text/plain "access plus 8 hours"
|
||||||
|
ExpiresByType application/x-javascript "access plus 8 hours"
|
||||||
|
ExpiresByType image/png "access plus 8 hours"
|
||||||
|
ExpiresByType image/jpeg "access plus 8 hours"
|
||||||
|
|
||||||
2
.npmrc
Normal file
2
.npmrc
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
@kupshop:registry = "https://gitlab.wpj.cz/api/v4/packages/npm/"
|
||||||
|
//gitlab.wpj.cz/:_authToken=${CI_JOB_TOKEN}
|
||||||
15
.php-cs-fixer.config.php
Normal file
15
.php-cs-fixer.config.php
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return (new PhpCsFixer\Config())
|
||||||
|
->setParallelConfig(new PhpCsFixer\Runner\Parallel\ParallelConfig(4))
|
||||||
|
->setRules(
|
||||||
|
[
|
||||||
|
'@Symfony' => true,
|
||||||
|
'phpdoc_no_access' => false, // Destroys Restler API
|
||||||
|
'yoda_style' => false,
|
||||||
|
'increment_style' => false,
|
||||||
|
'single_line_throw' => false,
|
||||||
|
'explicit_string_variable' => true,
|
||||||
|
'fully_qualified_strict_types' => false,
|
||||||
|
]
|
||||||
|
);
|
||||||
21
.php-cs-fixer.dist.php
Normal file
21
.php-cs-fixer.dist.php
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$finder = PhpCsFixer\Finder::create()
|
||||||
|
->in(__DIR__.'/admin')
|
||||||
|
->in(__DIR__.'/bundles')
|
||||||
|
->in(__DIR__.'/class')
|
||||||
|
->in(__DIR__.'/tests')
|
||||||
|
->in(__DIR__.'/upgrade')
|
||||||
|
->in(__DIR__.'/web')
|
||||||
|
->in(__DIR__.'/bin')
|
||||||
|
->in(__DIR__.'/socket')
|
||||||
|
->exclude('PHPExcel')
|
||||||
|
->exclude('XBase')
|
||||||
|
->exclude('highcharts')
|
||||||
|
->exclude('phpxbase')
|
||||||
|
->exclude('xmlrpc');
|
||||||
|
|
||||||
|
$config = require_once __DIR__.'/.php-cs-fixer.config.php';
|
||||||
|
|
||||||
|
return $config
|
||||||
|
->setFinder($finder);
|
||||||
34
.php-cs-fixer.shop.php
Normal file
34
.php-cs-fixer.shop.php
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$finder = PhpCsFixer\Finder::create()
|
||||||
|
->in('admin');
|
||||||
|
|
||||||
|
if (file_exists('./include')) {
|
||||||
|
$finder->in('include');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file_exists('./bundles')) {
|
||||||
|
$finder->in('bundles');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file_exists('./app')) {
|
||||||
|
$finder->in('app');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file_exists('./src')) {
|
||||||
|
$finder->in('src');
|
||||||
|
}
|
||||||
|
|
||||||
|
$finder2 = PhpCsFixer\Finder::create()
|
||||||
|
->in('.')
|
||||||
|
->depth('== 0');
|
||||||
|
|
||||||
|
$files = new AppendIterator();
|
||||||
|
$files->append($finder->getIterator());
|
||||||
|
$files->append($finder2->getIterator());
|
||||||
|
|
||||||
|
$config = require_once __DIR__.'/.php-cs-fixer.config.php';
|
||||||
|
|
||||||
|
return $config
|
||||||
|
->setFinder($files)
|
||||||
|
->setCacheFile('./engine/.php-cs-fixer.shop.cache');
|
||||||
15
.prettierignore
Normal file
15
.prettierignore
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
.idea
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
build
|
||||||
|
**/ComponentsBundle/
|
||||||
|
vendor
|
||||||
|
*.d.ts
|
||||||
|
**/views/components/
|
||||||
|
*.config.ts
|
||||||
|
wpj.*.ts
|
||||||
|
WpjComponentLoader.ts
|
||||||
|
WpjConfig.ts
|
||||||
|
**/interfaces/
|
||||||
|
query.tsx
|
||||||
|
query.ts
|
||||||
9
.prettierrc.mjs
Normal file
9
.prettierrc.mjs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import wpjPrettierConfig from '@kupshop/prettier-config-wpj';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {import("prettier").Config}
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
...wpjPrettierConfig,
|
||||||
|
tabWidth: 3,
|
||||||
|
}
|
||||||
116
admin/SplitOrder.php
Normal file
116
admin/SplitOrder.php
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||||
|
use KupShop\OrderingBundle\Util\Order\OrderItemEditTrait;
|
||||||
|
use KupShop\OrderingBundle\Util\Order\OrderUtil;
|
||||||
|
use Query\Operator;
|
||||||
|
|
||||||
|
class SplitOrder extends Window
|
||||||
|
{
|
||||||
|
use DatabaseCommunication;
|
||||||
|
use OrderItemEditTrait;
|
||||||
|
|
||||||
|
public function get_vars()
|
||||||
|
{
|
||||||
|
$vars = parent::get_vars();
|
||||||
|
$ID = $this->getID();
|
||||||
|
|
||||||
|
$order = $this->prepareOrder($ID);
|
||||||
|
$vars['products'] = $order->fetchItems();
|
||||||
|
$vars['order'] = $order;
|
||||||
|
$vars['body']['data']['id'] = $ID;
|
||||||
|
|
||||||
|
return $vars;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleUpdate()
|
||||||
|
{
|
||||||
|
$ID_OLD = $this->getID();
|
||||||
|
$ID_NEW = null;
|
||||||
|
$data = $this->getData();
|
||||||
|
|
||||||
|
$order_old = $this->prepareOrder($ID_OLD);
|
||||||
|
$order_new = null;
|
||||||
|
|
||||||
|
if (findModule(\Modules::ORDER_PAYMENT) && abs($order_old->getPayments()) > 1) {
|
||||||
|
// Uhrazenou objednávku již nelze rozdělit
|
||||||
|
$this->returnError('Objednávku nelze rozdělit, protože k ní existuje platba, která doposud nebyla vrácena! Nejprve vraťte platby.');
|
||||||
|
}
|
||||||
|
if (intval($order_old['storno']) == 1) {
|
||||||
|
// Stornovanou objednávku již nelze rozdělit
|
||||||
|
$this->returnError(getTextString('SplitOrder', 'errorCanceledCantEdit'));
|
||||||
|
}
|
||||||
|
$order_new = sqlGetConnection()->transactional(function () use ($data, $ID_OLD, $order_old, $order_new, $ID_NEW) {
|
||||||
|
$orderUtil = ServiceContainer::getService(OrderUtil::class);
|
||||||
|
|
||||||
|
$order_new = $orderUtil->copyOrder($ID_OLD, ['status_payed', 'status_dispatch', 'status_storno']);
|
||||||
|
sqlQueryBuilder()->update('orders')->directValues(['date_created' => $order_old['date_created']->format('Y-m-d H:i:s')])
|
||||||
|
->where(Operator::equals(['id' => $order_new['id']]))->execute();
|
||||||
|
$ID_NEW = $order_new['id'];
|
||||||
|
|
||||||
|
$order_items = sqlQueryBuilder()->select('*')
|
||||||
|
->from('order_items')
|
||||||
|
->where(Operator::equals(['id_order' => $ID_OLD]))
|
||||||
|
->execute()
|
||||||
|
->fetchAll();
|
||||||
|
|
||||||
|
foreach ($order_items as $item_old) {
|
||||||
|
$get_item = $data['items'][$item_old['id']];
|
||||||
|
|
||||||
|
if (floatval($get_item['pieces_new']) > 0) {
|
||||||
|
$old_pcs = $item_old['pieces'] - $get_item['pieces_new'];
|
||||||
|
if ($old_pcs == 0) {
|
||||||
|
// na novou objednávku přesunout celou položku
|
||||||
|
sqlQueryBuilder()->update('order_items')
|
||||||
|
->directValues(['id_order' => $ID_NEW])
|
||||||
|
->where(Operator::equals(['id' => $item_old['id']]))
|
||||||
|
->execute();
|
||||||
|
} else {
|
||||||
|
// na novou objednávku přesunout část položek a přepočítat
|
||||||
|
$item_new_data = $item_old;
|
||||||
|
$item_new_data['id_order'] = $ID_NEW;
|
||||||
|
$item_new_data['pieces'] = $get_item['pieces_new'];
|
||||||
|
$item_new_data['pieces_reserved'] = $get_item['pieces_new'];
|
||||||
|
$item_new_data['total_price'] = $get_item['pieces_new'] * $item_old['piece_price'];
|
||||||
|
|
||||||
|
unset($item_new_data['id'], $item_new_data['pohoda_id']);
|
||||||
|
sqlQueryBuilder()->insert('order_items')
|
||||||
|
->directValues($item_new_data)
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
// z původní objednávky odebrat část položek a přepočítat
|
||||||
|
sqlQueryBuilder()->update('order_items')
|
||||||
|
->directValues([
|
||||||
|
'pieces' => $item_old['pieces'] - $get_item['pieces_new'],
|
||||||
|
'pieces_reserved' => $item_old['pieces_reserved'] - $get_item['pieces_new'],
|
||||||
|
'total_price' => $item_old['piece_price'] * ($item_old['pieces'] - $get_item['pieces_new']),
|
||||||
|
])
|
||||||
|
->where(Operator::equals(['id' => $item_old['id']]))
|
||||||
|
->execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$order_old->recalculate();
|
||||||
|
$order_new->recalculate();
|
||||||
|
|
||||||
|
return $order_new;
|
||||||
|
});
|
||||||
|
writeDownActivity(sprintf(getTextString('SplitOrder', 'activitySplit'), $order_old['order_no'], $order_new['order_no']));
|
||||||
|
|
||||||
|
$order_old->logHistory(sprintf(getTextString('SplitOrder', 'splitOldNote'), $order_new['order_no']));
|
||||||
|
$order_new->logHistory(sprintf(getTextString('SplitOrder', 'splitNewNote'), $order_old['order_no']));
|
||||||
|
|
||||||
|
$this->redirect(['s' => 'orders.php', 'ID' => $order_new['id'], 'acn' => 'edit', 'force_resize' => 1, 'reload_parent' => 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function prepareOrder($orderId)
|
||||||
|
{
|
||||||
|
$order = new Order();
|
||||||
|
$order->createFromDB($orderId);
|
||||||
|
|
||||||
|
return $order;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SplitOrder::class;
|
||||||
84
admin/adminEdit.php
Normal file
84
admin/adminEdit.php
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$main_class = 'AdminEdit';
|
||||||
|
|
||||||
|
class AdminEdit extends Window
|
||||||
|
{
|
||||||
|
protected $tableName = 'admins';
|
||||||
|
|
||||||
|
public function handleUpdate()
|
||||||
|
{
|
||||||
|
if (getVal('Submit')) {
|
||||||
|
$data = $this->getData();
|
||||||
|
global $adminID;
|
||||||
|
$admPassOld = $data['admPassOld'];
|
||||||
|
$admPass1 = $data['admPass1'];
|
||||||
|
$admPass2 = $data['admPass2'];
|
||||||
|
$error = 0;
|
||||||
|
// nova hesla se musi rovnat
|
||||||
|
if ($admPass1 != $admPass2) {
|
||||||
|
$error = 1;
|
||||||
|
// Zadané heslo a kontrolní heslo se neshodují
|
||||||
|
$ErrStr = translate('errorPasswNotEqual');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen($admPass1) < 6) {
|
||||||
|
$error = 15;
|
||||||
|
$ErrStr = translate('errorPasswLength');
|
||||||
|
}
|
||||||
|
|
||||||
|
// kontrola puvodniho hesla
|
||||||
|
$qb = sqlQueryBuilder()->select('id', 'login', 'password', 'OLD_PASSWORD(:admPassOld) AS passwGet')
|
||||||
|
->from('admins')
|
||||||
|
->where(\Query\Operator::equals(['id' => $adminID]))
|
||||||
|
->setParameter('admPassOld', $admPassOld)
|
||||||
|
->setMaxResults(1)
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
if ($qb->rowCount() == 1) {
|
||||||
|
$log = $qb->fetch();
|
||||||
|
$admName = $log['login'];
|
||||||
|
if (($log['passwGet'] != $log['password']) && (password_verify($admPassOld, $log['password']) == false)) {
|
||||||
|
$error = 1;
|
||||||
|
// Zadané současné heslo není správné
|
||||||
|
$ErrStr = translate('errorBadPassw');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($error == 0) {
|
||||||
|
$new_hash = password_hash($admPass1, PASSWORD_BCRYPT);
|
||||||
|
|
||||||
|
if ($this->updateSQL('admins', ['password' => $new_hash], ['id' => $adminID])) {
|
||||||
|
$ErrStr = urlencode(sprintf(translate('activityPasswEdited'), $admName));
|
||||||
|
writeDownActivity(sprintf(translate('activityPasswEdited'), $admName));
|
||||||
|
} else {
|
||||||
|
$ErrStr = translate('scripterror', 'status');
|
||||||
|
}
|
||||||
|
redirect('launch.php?s=adminEdit.php&acn=passw&ErrStr='.$ErrStr);
|
||||||
|
} else {
|
||||||
|
redirect('launch.php?s=adminEdit.php&acn=passw&ErrStr='.urlencode($ErrStr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::handleUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getData()
|
||||||
|
{
|
||||||
|
$data = parent::getData();
|
||||||
|
|
||||||
|
$data['email'] = getAdminUser()['email'];
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getID()
|
||||||
|
{
|
||||||
|
return getAdminUser()['id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getAction()
|
||||||
|
{
|
||||||
|
return 'edit';
|
||||||
|
}
|
||||||
|
}
|
||||||
342
admin/admins.php
Normal file
342
admin/admins.php
Normal file
@@ -0,0 +1,342 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// ##############################################################
|
||||||
|
global $cfg;
|
||||||
|
// ##############################################################
|
||||||
|
|
||||||
|
use KupShop\AdminBundle\Util\ActivityLog;
|
||||||
|
use KupShop\AdminBundle\Util\LegacyAdminCredentials;
|
||||||
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||||
|
use Query\Operator;
|
||||||
|
|
||||||
|
$main_class = 'Admins';
|
||||||
|
|
||||||
|
class Admins extends Window
|
||||||
|
{
|
||||||
|
use DatabaseCommunication;
|
||||||
|
|
||||||
|
protected $nameField = 'login';
|
||||||
|
protected $required = ['login' => true];
|
||||||
|
|
||||||
|
public function get_vars()
|
||||||
|
{
|
||||||
|
$vars = parent::get_vars();
|
||||||
|
$pageVars = getVal('body', $vars);
|
||||||
|
$ID = $this->getID();
|
||||||
|
$acn = $this->getAction();
|
||||||
|
|
||||||
|
$pageVars['data']['data'] = $pageVars['data']['data'] ?? null;
|
||||||
|
$this->unserializeCustomData($pageVars['data']);
|
||||||
|
|
||||||
|
$vars['body'] = $pageVars;
|
||||||
|
|
||||||
|
return $vars;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getObject()
|
||||||
|
{
|
||||||
|
$data = parent::getObject();
|
||||||
|
if ($data['privilege'] == 'ALL_RIGHTS') {
|
||||||
|
$data['all_rights'] = 'Y';
|
||||||
|
} else {
|
||||||
|
$data['all_rights'] = 'N';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getData()
|
||||||
|
{
|
||||||
|
$data = parent::getData();
|
||||||
|
$acn = $this->getAction();
|
||||||
|
|
||||||
|
if (getVal('Submit') && $acn != 'passw') {
|
||||||
|
$data['date_valid'] = $this->prepareDateTime($data['date_valid']);
|
||||||
|
|
||||||
|
if ($data['all_rights'] == 'Y') {
|
||||||
|
$data['privilege'] = 'ALL_RIGHTS';
|
||||||
|
} else {
|
||||||
|
$data['privilege'] = '';
|
||||||
|
foreach ($data as $key => $row) {
|
||||||
|
if ($row == 'ON') {
|
||||||
|
$data['privilege'] .= $key.'|';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$data['privilege'] = substr($data['privilege'], 0, -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($acn == 'add' && !getVal('Submit')) {
|
||||||
|
$data['privilege'] = '';
|
||||||
|
$data['date_reg'] = date('Y-m-d H:i');
|
||||||
|
$data['active'] = 'Y';
|
||||||
|
}
|
||||||
|
|
||||||
|
$data['data'] = $data['custom_data'] ?? [];
|
||||||
|
|
||||||
|
$this->serializeCustomData($data);
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updatePass($password, $id)
|
||||||
|
{
|
||||||
|
$new_hash = password_hash($password, PASSWORD_BCRYPT);
|
||||||
|
$this->updateSQL('admins', ['password' => $new_hash], ['id' => $id]);
|
||||||
|
|
||||||
|
return $new_hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleImpersonate(): void
|
||||||
|
{
|
||||||
|
if (!findRight('OTH_ADM_EDIT')) {
|
||||||
|
$this->returnError('Nedostatečená práva');
|
||||||
|
}
|
||||||
|
|
||||||
|
$legacyAdminCredentials = ServiceContainer::getService(LegacyAdminCredentials::class);
|
||||||
|
|
||||||
|
$newAdmin = $legacyAdminCredentials->getAdminById(
|
||||||
|
(int) $this->getID()
|
||||||
|
);
|
||||||
|
|
||||||
|
addActivityLog(
|
||||||
|
ActivityLog::SEVERITY_NOTICE,
|
||||||
|
ActivityLog::TYPE_SECURITY,
|
||||||
|
sprintf(translate('impersonateLogMessage'), $newAdmin['login'])
|
||||||
|
);
|
||||||
|
|
||||||
|
$legacyAdminCredentials->setLoginSession($this->getID());
|
||||||
|
|
||||||
|
$this->redirect(['acn' => 'erased3']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handlePassw()
|
||||||
|
{
|
||||||
|
if (getVal('Submit')) {
|
||||||
|
$data = $this->getData();
|
||||||
|
global $adminID;
|
||||||
|
$admPassOld = $data['admPassOld'];
|
||||||
|
$admPass1 = $data['admPass1'];
|
||||||
|
$admPass2 = $data['admPass2'];
|
||||||
|
if (!empty($admPassOld) && !empty($admPass1) && !empty($admPass2)) {
|
||||||
|
$error = 0;
|
||||||
|
// nova hesla se musi rovnat
|
||||||
|
if ($admPass1 != $admPass2) {
|
||||||
|
$error = 1;
|
||||||
|
// Zadané heslo a kontrolní heslo se neshodují
|
||||||
|
$ErrStr = translate('errorPasswNotEqual');
|
||||||
|
}
|
||||||
|
// kontrola puvodniho hesla
|
||||||
|
$SQL = sqlQuery("SELECT id, login, password, OLD_PASSWORD('".$admPassOld."') AS passwGet
|
||||||
|
FROM ".getTableName('admins')."
|
||||||
|
WHERE id='".$adminID."'
|
||||||
|
LIMIT 1");
|
||||||
|
|
||||||
|
if (sqlNumRows($SQL) == 1) {
|
||||||
|
$log = sqlFetchArray($SQL);
|
||||||
|
$admName = $log['login'];
|
||||||
|
if (($log['passwGet'] != $log['password']) && (password_verify($admPassOld, $log['password']) == false)) {
|
||||||
|
$error = 1;
|
||||||
|
// Zadané současné heslo není správné
|
||||||
|
$ErrStr = translate('errorBadPassw');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sqlFreeResult($SQL);
|
||||||
|
|
||||||
|
if ($error == 0) {
|
||||||
|
/*$SQL = sqlQuery("UPDATE ".getTableName("admins")."
|
||||||
|
SET password=OLD_PASSWORD('".$admPass1."') WHERE id='".$adminID."' ");
|
||||||
|
*/
|
||||||
|
$new_hash = password_hash($admPass1, PASSWORD_BCRYPT);
|
||||||
|
$this->updateSQL('admins', ['password' => $new_hash], ['id' => $adminID]);
|
||||||
|
|
||||||
|
if ($SQL) {
|
||||||
|
$ErrStr = urlencode(translate('saved', 'status'));
|
||||||
|
|
||||||
|
writeDownActivity(sprintf(translate('activityPasswEdited'), $admName));
|
||||||
|
|
||||||
|
redirect('launch.php?s=admins.php&acn=passw&ErrStr='.$ErrStr);
|
||||||
|
} else {
|
||||||
|
$ErrStr = translate('scripterror', 'status');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
redirect('launch.php?s=admins.php&acn=passw&ErrStr='.urlencode($ErrStr));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$ErrStr = translate('errorNotAllValidPassw');
|
||||||
|
redirect('launch.php?s=admins.php&acn=passw&ErrStr='.urlencode($ErrStr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// die($ErrStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleUpdate()
|
||||||
|
{
|
||||||
|
$SQL = parent::handleUpdate();
|
||||||
|
if ($SQL) {
|
||||||
|
$IDadm = $this->getID();
|
||||||
|
$data = $this->getData();
|
||||||
|
|
||||||
|
if (!empty($data['pass'])) {
|
||||||
|
/*sqlQuery("UPDATE ".getTableName("admins")."
|
||||||
|
SET password=OLD_PASSWORD('{$data['pass']}')
|
||||||
|
WHERE id='{$IDadm}' ");
|
||||||
|
*/
|
||||||
|
$new_hash = password_hash($data['pass'], PASSWORD_BCRYPT);
|
||||||
|
$this->updateSQL('admins', ['password' => $new_hash], ['id' => $IDadm]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ####################################################
|
||||||
|
// UPRAVA PRAV ADMINA KE CLANKUM
|
||||||
|
if (isset($data['ArtAuthors'])) {
|
||||||
|
if (findModule('articles')) {
|
||||||
|
// smazat vsechny radky
|
||||||
|
sqlQuery('DELETE FROM '.getTableName('articles_authors_admins')."
|
||||||
|
WHERE id_admin='".$IDadm."' ", '@');
|
||||||
|
|
||||||
|
if ($data['ArtAuthors'][0] != 0) {
|
||||||
|
$no = count($data['ArtAuthors']);
|
||||||
|
for ($i = 0; $i < $no; $i++) {
|
||||||
|
sqlQuery('INSERT INTO '.getTableName('articles_authors_admins')."
|
||||||
|
SET id_admin='".$IDadm."', id_auth='".$data['ArtAuthors'][$i]."' ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ####################################################
|
||||||
|
// UPRAVA PRAV ADMINA K SEKCIM CLANKU
|
||||||
|
if (isset($data['ArtSections'])) {
|
||||||
|
if (findModule('articles_sections')) {
|
||||||
|
// smazat vsechny radky
|
||||||
|
sqlQuery('DELETE FROM '.getTableName('articles_branches_admins')."
|
||||||
|
WHERE id_admin='".$IDadm."' ", '@');
|
||||||
|
|
||||||
|
if ($data['ArtSections'][0] != 0) {
|
||||||
|
$no = count($data['ArtSections']);
|
||||||
|
for ($i = 0; $i < $no; $i++) {
|
||||||
|
sqlQuery('INSERT INTO '.getTableName('articles_branches_admins')."
|
||||||
|
SET id_admin='".$IDadm."', id_branch='".$data['ArtSections'][$i]."' ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ####################################################
|
||||||
|
}
|
||||||
|
|
||||||
|
return $SQL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleDelete()
|
||||||
|
{
|
||||||
|
$IDadm = $this->getID();
|
||||||
|
if (!findRight('OTH_ADM_ERASE')) {
|
||||||
|
redirect('launch.php?s=error.php&id=1');
|
||||||
|
}
|
||||||
|
global $adminID;
|
||||||
|
if ($adminID != $IDadm) {
|
||||||
|
writeDownActivity(sprintf(translate('activityDeleted'), returnSQLResult('SELECT login
|
||||||
|
FROM '.getTableName('admins')."
|
||||||
|
WHERE id='".$IDadm."' ")));
|
||||||
|
|
||||||
|
$SQL = sqlQuery('DELETE FROM '.getTableName('admins')." WHERE id='{$IDadm}' ");
|
||||||
|
|
||||||
|
redirect('launch.php?s=admins.php&acn=erased');
|
||||||
|
} else {
|
||||||
|
// Nemůžete smazat administrátora, pod kterým jste právě přihlášen
|
||||||
|
$ErrStr = translate('errorCantDeleteActive');
|
||||||
|
|
||||||
|
redirect('launch.php?s=admins.php&acn=edit&ID='.$IDadm.'&ErrStr='.$ErrStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function articlesSections($topCat)
|
||||||
|
{
|
||||||
|
$data = [];
|
||||||
|
$SQL = sqlQuery('SELECT ab.id, ab.name
|
||||||
|
FROM '.getTableName('articles_branches')." AS ab
|
||||||
|
WHERE ab.top_branch='".$topCat."'
|
||||||
|
ORDER BY ab.name ASC");
|
||||||
|
$ID = $this->getID();
|
||||||
|
foreach ($SQL as $key => $row) {
|
||||||
|
$data[$key]['id'] = $row['id'];
|
||||||
|
$data[$key]['level'] = $topCat;
|
||||||
|
$data[$key]['selected'] = returnSQLResult('SELECT Count(id_admin)
|
||||||
|
FROM '.getTableName('articles_branches_admins')."
|
||||||
|
WHERE id_admin='".$ID."' AND id_branch='".$row['id']."' LIMIT 1 ");
|
||||||
|
$data[$key]['name'] = $row['name'];
|
||||||
|
$data[$key]['submenu'] = $this->articlesSections($row['id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleSendPassword()
|
||||||
|
{
|
||||||
|
global $dbcfg, $cfg;
|
||||||
|
$ID = $this->getID();
|
||||||
|
|
||||||
|
$admin = sqlFetch($this->selectSQL('admins', ['id' => $ID]));
|
||||||
|
|
||||||
|
$password = $this->generatePassword(10);
|
||||||
|
|
||||||
|
$admin['password'] = $password;
|
||||||
|
$new_hash = password_hash($password, PASSWORD_BCRYPT);
|
||||||
|
|
||||||
|
$this->updateSQL('admins', ['password' => $new_hash], ['id' => $ID]);
|
||||||
|
|
||||||
|
if (!isset($cfg['Menu']['wpj_toolbar'])) {
|
||||||
|
$cfg['Menu']['wpj_toolbar'] = null;
|
||||||
|
}
|
||||||
|
$admin_url = getVal('admin_url', $cfg['Menu']['wpj_toolbar'], 'admin/');
|
||||||
|
|
||||||
|
$smarty = createSmarty(false, true);
|
||||||
|
$smarty->assign(['admin' => $admin, 'admin_url' => $admin_url]);
|
||||||
|
$content = $smarty->fetch(findTemplate('email/password_generate.tpl'));
|
||||||
|
|
||||||
|
if (SendMail($dbcfg->shop_email, $admin['email'], 'Nové heslo do administrace '.substr($cfg['Addr']['print'], 0, -1), $content, 'text/html')) {
|
||||||
|
$this->returnOK('Heslo bylo úspěšně zasláno na email');
|
||||||
|
} else {
|
||||||
|
$this->returnError('Heslo se nepodařilo odeslat, zkuste to prosím znovu');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function generatePassword($length = 8)
|
||||||
|
{
|
||||||
|
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
||||||
|
$count = mb_strlen($chars);
|
||||||
|
|
||||||
|
for ($i = 0, $result = ''; $i < $length; $i++) {
|
||||||
|
$index = rand(0, $count - 1);
|
||||||
|
$result .= mb_substr($chars, $index, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handlePrintHashLogin()
|
||||||
|
{
|
||||||
|
$ID = $this->getID();
|
||||||
|
|
||||||
|
$admin = sqlQueryBuilder()->select('*')->from('admins')->where(Operator::equals(['id' => $ID]))->execute()->fetch();
|
||||||
|
|
||||||
|
if (empty($admin['token'])) {
|
||||||
|
$this->returnError('Nejdříve musíte vygenerovat přihlašovací token!');
|
||||||
|
}
|
||||||
|
|
||||||
|
$smarty = createSmarty(true, true);
|
||||||
|
$smarty->assign([
|
||||||
|
'login' => $admin['login'],
|
||||||
|
'code' => $admin['token'],
|
||||||
|
]);
|
||||||
|
$smarty->display('window/adminsPrintHashLogin.tpl');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function generateAdminToken(): string
|
||||||
|
{
|
||||||
|
return ServiceContainer::getService(\KupShop\KupShopBundle\Util\System\TokenGenerator::class)->generate(16);
|
||||||
|
}
|
||||||
|
}
|
||||||
233
admin/ajax.php
Normal file
233
admin/ajax.php
Normal file
@@ -0,0 +1,233 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use KupShop\KupShopBundle\Config;
|
||||||
|
use Query\Operator;
|
||||||
|
|
||||||
|
class AdminAjax
|
||||||
|
{
|
||||||
|
/** @var \Query\QueryBuilder */
|
||||||
|
public $qb;
|
||||||
|
|
||||||
|
private $search;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->qb = sqlQueryBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
header('Content-type: application/json');
|
||||||
|
$type = getVal('type');
|
||||||
|
|
||||||
|
$limit = getVal('limit', null, 100);
|
||||||
|
if ($limit < 0) {
|
||||||
|
$limit = 999999;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->qb->setMaxResults($limit);
|
||||||
|
|
||||||
|
return $this->handle($type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle($type)
|
||||||
|
{
|
||||||
|
$method = 'handle'.ucfirst($type);
|
||||||
|
if (method_exists($this, $method)) {
|
||||||
|
return $this->$method();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->fallback($type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleOrder()
|
||||||
|
{
|
||||||
|
$orderId = getVal('id_order');
|
||||||
|
$result = false;
|
||||||
|
if (!empty($orderId)) {
|
||||||
|
$result = sqlQueryBuilder()->select('o.*')
|
||||||
|
->from('orders', 'o')
|
||||||
|
->where(Operator::equals(['o.id' => $orderId]))
|
||||||
|
->execute()->fetch();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$result) {
|
||||||
|
$result = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return json_encode($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handlePositionsOverSupply()
|
||||||
|
{
|
||||||
|
if (findModule(Modules::WAREHOUSE)) {
|
||||||
|
sqlQueryBuilder()->update('warehouse_products')
|
||||||
|
->directValues(['over_supply' => getVal('value')])
|
||||||
|
->andWhere(Operator::equalsNullable([
|
||||||
|
'id_position' => getVal('id_position'),
|
||||||
|
'id_product' => getVal('id_product'),
|
||||||
|
'id_variation' => getVal('id_variation') ?: null,
|
||||||
|
]))->execute();
|
||||||
|
|
||||||
|
return getVal('value') == 'Y';
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleProduct_info()
|
||||||
|
{
|
||||||
|
$cfg = Config::get();
|
||||||
|
$qb = $this->qb
|
||||||
|
->select('v.vat as vat, COALESCE(pv.in_store, p.in_store) as quantity, COALESCE(pv.ean, p.ean) as ean, COALESCE(pv.price, p.price) as price, p.discount as discount');
|
||||||
|
|
||||||
|
if (!empty($cfg['Modules']['products_variations']['variationCode'])) {
|
||||||
|
$qb->addSelect(' COALESCE(pv.code, p.code) as code');
|
||||||
|
} else {
|
||||||
|
$qb->addSelect(' p.code as code');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (findModule('products', 'weight')) {
|
||||||
|
if (findModule('products_variations')) {
|
||||||
|
$qb->addSelect(' COALESCE(pv.weight, p.weight) as weight');
|
||||||
|
} else {
|
||||||
|
$qb->addSelect(' p.weight as weight');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (findModule(Modules::PRODUCTS, Modules::SUB_PRICE_BUY)) {
|
||||||
|
if (findModule(Modules::PRODUCTS_VARIATIONS)) {
|
||||||
|
$qb->addSelect('COALESCE(pv.price_buy, p.price_buy) as price_buy');
|
||||||
|
} else {
|
||||||
|
$qb->addSelect('p.price_buy as price_buy');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$qb->from('products', 'p')
|
||||||
|
->leftJoin('p', 'products_variations', 'pv', 'p.id=pv.id_product')
|
||||||
|
->leftJoin('p', 'vats', 'v', 'p.vat=v.id');
|
||||||
|
|
||||||
|
if (!getVal('id_product')) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$id_product = intval(getVal('id_product'));
|
||||||
|
$id_variation = intval(getVal('id_variation'));
|
||||||
|
|
||||||
|
$qb->where(Operator::equals(['p.id' => $id_product]));
|
||||||
|
|
||||||
|
if ($id_variation > 0) {
|
||||||
|
$qb->andWhere(Operator::equals(['pv.id' => $id_variation]));
|
||||||
|
}
|
||||||
|
|
||||||
|
$products = $qb->execute()->fetchAll();
|
||||||
|
$user_id = getVal('user_id');
|
||||||
|
|
||||||
|
if (findModule(Modules::PRICE_LEVELS) && $user_id) {
|
||||||
|
$user = User::createFromId($user_id);
|
||||||
|
if ($price_level_id = $user->getUserPricelevelId()) {
|
||||||
|
$plService = KupShop\KupShopBundle\Util\Compat\ServiceContainer::getService(\KupShop\KupShopBundle\Context\PriceLevelContext::class);
|
||||||
|
$plService->activate($price_level_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getVal('currency')) {
|
||||||
|
$currencyContext = KupShop\KupShopBundle\Util\Compat\ServiceContainer::getService(\KupShop\KupShopBundle\Context\CurrencyContext::class);
|
||||||
|
$currencyContext->activate(getVal('currency'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = [];
|
||||||
|
|
||||||
|
foreach ($products as $product) {
|
||||||
|
$PRICE_ARRAY = formatCustomerPrice($product['price'], $product['discount'], $product['vat'], $_GET['id_product']);
|
||||||
|
|
||||||
|
$price_with_vat = $PRICE_ARRAY['value_without_vat_no_rounding']->addVat($product['vat']);
|
||||||
|
|
||||||
|
$price_with_vat = roundPrice($price_with_vat);
|
||||||
|
|
||||||
|
$product['price'] = $price_with_vat->removeVat($product['vat'])->asFloat();
|
||||||
|
|
||||||
|
if (findModule(Modules::PRODUCTS, Modules::SUB_PRICE_BUY)) {
|
||||||
|
$product['price_buy_with_vat'] = toDecimal($product['price_buy'])->addVat($product['vat'])->value(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
$product['price_with_vat'] = $price_with_vat->asFloat();
|
||||||
|
|
||||||
|
$result[] = $product;
|
||||||
|
}
|
||||||
|
|
||||||
|
return json_encode($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function prepareSearchFields($fields)
|
||||||
|
{
|
||||||
|
return get_search_query($this->search, $fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function prepareSearch($search)
|
||||||
|
{
|
||||||
|
return sqlFormatInput(trim($search));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getResult()
|
||||||
|
{
|
||||||
|
return json_encode($this->qb->execute()->fetchAll());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function fallback($type)
|
||||||
|
{
|
||||||
|
$limit = getVal('limit', null, 100);
|
||||||
|
$group = null;
|
||||||
|
$where = ' 1 ';
|
||||||
|
|
||||||
|
$result = [];
|
||||||
|
|
||||||
|
$data = [];
|
||||||
|
|
||||||
|
if ($limit < 0) {
|
||||||
|
$limit = 999999;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($type) {
|
||||||
|
case 'product_of_suppliers_info':
|
||||||
|
$fields = 'pos.code code, pos.id_supplier id_supplier';
|
||||||
|
$from = getTableName('products_of_suppliers').' pos';
|
||||||
|
if (empty($_GET['id_product'])) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
$id_product = intval($_GET['id_product']);
|
||||||
|
$id_variation = intval($_GET['id_variation']);
|
||||||
|
|
||||||
|
$where = "pos.id_product={$id_product}";
|
||||||
|
|
||||||
|
if (!empty($_GET['id_supplier'])) {
|
||||||
|
$id_supplier = intval($_GET['id_supplier']);
|
||||||
|
$where .= " AND pos.id_supplier={$id_supplier}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($id_variation)) {
|
||||||
|
$where .= " AND pos.id_variation={$id_variation}";
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($where) {
|
||||||
|
$where = " WHERE {$where} ";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($group) {
|
||||||
|
$where .= " GROUP BY {$group} ";
|
||||||
|
}
|
||||||
|
|
||||||
|
$SQL = sqlQuery("SELECT {$fields}
|
||||||
|
FROM {$from}
|
||||||
|
{$where} LIMIT {$limit}", $data);
|
||||||
|
|
||||||
|
$result = array_merge($result, $SQL->fetchAll());
|
||||||
|
|
||||||
|
return json_encode($result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo (new AdminAjax())->run();
|
||||||
107
admin/artauthors.php
Normal file
107
admin/artauthors.php
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use KupShop\AdminBundle\AdminBlocksTrait;
|
||||||
|
use KupShop\AdminBundle\Util\BlocksHistory;
|
||||||
|
use KupShop\ContentBundle\Util\BlocksTrait;
|
||||||
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||||
|
|
||||||
|
class Artauthors extends Window
|
||||||
|
{
|
||||||
|
use BlocksTrait;
|
||||||
|
use AdminBlocksTrait;
|
||||||
|
|
||||||
|
protected $tableName = 'articles_authors';
|
||||||
|
protected $show_on_web = 'articlesAuthor';
|
||||||
|
|
||||||
|
private BlocksHistory $blocksHistory;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->defaults = ['date_reg' => date('d-m-Y H:i'),
|
||||||
|
'active' => 'Y',
|
||||||
|
'sex' => 'M',
|
||||||
|
'top_branch' => '0',
|
||||||
|
];
|
||||||
|
$this->blocksHistory = ServiceContainer::getService(BlocksHistory::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getData()
|
||||||
|
{
|
||||||
|
$data = parent::getData();
|
||||||
|
|
||||||
|
if (!empty($data['date_reg'])) {
|
||||||
|
$data['date_reg'] = $this->prepareDate($data['date_reg']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($data['date_borned'])) {
|
||||||
|
$data['date_borned'] = $this->prepareDate($data['date_borned']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_vars()
|
||||||
|
{
|
||||||
|
$vars = parent::get_vars();
|
||||||
|
$pageVars = getVal('body', $vars);
|
||||||
|
if (!empty($pageVars['data']['photo'])) {
|
||||||
|
$pageVars['data']['photo'] = @getImage($this->getID(), $pageVars['data']['photo'], '../articles_authors/', 'articles_authors', dateUpdate: strtotime($pageVars['data']['date_update']));
|
||||||
|
}
|
||||||
|
|
||||||
|
$vars['body'] = $pageVars;
|
||||||
|
|
||||||
|
if (isset($pageVars['data']['id_block'])) {
|
||||||
|
$vars['body']['data']['blocks'] = $this->getBlocks($pageVars['data']['id_block']);
|
||||||
|
$vars['body']['data']['blocks_history'] = $this->blocksHistory->getBlocksHistory($pageVars['data']['id_block']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $vars;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleUpdate()
|
||||||
|
{
|
||||||
|
$SQL = parent::handleUpdate();
|
||||||
|
|
||||||
|
$ID = $this->getID();
|
||||||
|
|
||||||
|
if (!empty($_FILES['picture']['name'])) {
|
||||||
|
$img = new Photos('articles_authors');
|
||||||
|
$img->newImage($ID);
|
||||||
|
$img->uploadImage($_FILES['picture'], strtolower(substr(strrchr($_FILES['picture']['name'], '.'), 0)));
|
||||||
|
|
||||||
|
if ($img->checkFileType()) {
|
||||||
|
$img->insertImageIntoDB();
|
||||||
|
} else {
|
||||||
|
$this->returnError(getTextString('producers', 'errorBadPhoto'));
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($img);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->getAction() == 'edit') {
|
||||||
|
// historii je treba ulozit jeste pred ulozenim bloku
|
||||||
|
$this->blocksHistory->saveBlocksHistory(getVal('blocks', $this->getData(), []));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->saveBlocks($this->getData(), $ID, 'articles_authors');
|
||||||
|
|
||||||
|
return $SQL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleErasephoto()
|
||||||
|
{
|
||||||
|
$ID = getVal('ID');
|
||||||
|
// sqlQuery("DELETE FROM ".getTableName("photos")." WHERE id='$IDsec'");
|
||||||
|
|
||||||
|
// ########################################################################
|
||||||
|
$img = new Photos('articles_authors');
|
||||||
|
$img->newImage($ID);
|
||||||
|
$img->deletePhoto();
|
||||||
|
unset($img);
|
||||||
|
// ########################################################################
|
||||||
|
|
||||||
|
$this->returnOK('Fotografie byla smazána');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Artauthors::class;
|
||||||
23
admin/articles.photos.php
Normal file
23
admin/articles.photos.php
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$main_class = 'ArticlesPhotos';
|
||||||
|
|
||||||
|
class ArticlesPhotos extends BaseAdminPhotos
|
||||||
|
{
|
||||||
|
use DatabaseCommunication;
|
||||||
|
use \KupShop\ContentBundle\Util\BlocksTrait;
|
||||||
|
|
||||||
|
protected $relation_table_name = 'photos_articles_relation';
|
||||||
|
protected $photo_type = 4;
|
||||||
|
protected $tablefield = 'id_art';
|
||||||
|
protected $photo_nametype = 'Article';
|
||||||
|
protected $copy_from = 'z článku';
|
||||||
|
protected $search_field = 'article';
|
||||||
|
|
||||||
|
public function handleMovePhoto()
|
||||||
|
{
|
||||||
|
parent::handleMovePhoto();
|
||||||
|
|
||||||
|
$this->updateBlocksPhotosPositions($this->getID(), 'articles', $this->tablefield);
|
||||||
|
}
|
||||||
|
}
|
||||||
440
admin/articles.php
Normal file
440
admin/articles.php
Normal file
@@ -0,0 +1,440 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Admin;
|
||||||
|
|
||||||
|
use KupShop\AdminBundle\AdminBlocksTrait;
|
||||||
|
use KupShop\AdminBundle\Util\AdminSectionTree;
|
||||||
|
use KupShop\AdminBundle\Util\BlocksHistory;
|
||||||
|
use KupShop\ContentBundle\Util\BlocksTrait;
|
||||||
|
use KupShop\I18nBundle\Translations\ArticlesTranslation;
|
||||||
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||||
|
use KupShop\KupShopBundle\Util\StringUtil;
|
||||||
|
use Query\Operator;
|
||||||
|
|
||||||
|
class Articles extends \Window
|
||||||
|
{
|
||||||
|
use BlocksTrait;
|
||||||
|
use AdminBlocksTrait;
|
||||||
|
|
||||||
|
protected $tableName = 'articles';
|
||||||
|
protected $template = 'window/articles.tpl';
|
||||||
|
|
||||||
|
protected $nameField = 'title';
|
||||||
|
protected $show_on_web = 'article';
|
||||||
|
|
||||||
|
/** @var BlocksHistory */
|
||||||
|
private $blocksHistory;
|
||||||
|
|
||||||
|
private AdminSectionTree $adminSectionTree;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->blocksHistory = ServiceContainer::getService(BlocksHistory::class);
|
||||||
|
$this->adminSectionTree = ServiceContainer::getService(AdminSectionTree::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function articlesSections($topCat, $Pos = 0, $ignored = null)
|
||||||
|
{
|
||||||
|
$SQL = sqlQueryBuilder()
|
||||||
|
->select('ab.id, ab.name, ab.descr, ab.figure')
|
||||||
|
->from('articles_branches', 'ab')
|
||||||
|
->where(\Query\Operator::equalsNullable(['ab.top_branch' => $topCat]))
|
||||||
|
->orderBy('ab.name', 'ASC')
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
$data = [];
|
||||||
|
foreach ($SQL as $key => $row) {
|
||||||
|
if ($ignored == null || $ignored != $row['id']) {
|
||||||
|
$data[$key]['id'] = $row['id'];
|
||||||
|
$data[$key]['title'] = $row['name'];
|
||||||
|
$data[$key]['figure'] = $row['figure'];
|
||||||
|
$data[$key]['level'] = $Pos;
|
||||||
|
$data[$key]['submenu'] = $this->articlesSections($row['id'], $Pos + 1, $ignored = null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createObject()
|
||||||
|
{
|
||||||
|
$data = parent::createObject();
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_vars()
|
||||||
|
{
|
||||||
|
$vars = parent::get_vars();
|
||||||
|
$pageVars = getVal('body', $vars);
|
||||||
|
$ID = $this->getID();
|
||||||
|
$acn = $this->getAction();
|
||||||
|
|
||||||
|
if (!empty($ID)) {
|
||||||
|
$pageVars['tree'] = $this->articlesSections(null);
|
||||||
|
$pageVars['selected'] = $this->adminSectionTree->getSelected($this->getID(), 'articles_relation', 'id_art', 'id_branch');
|
||||||
|
$this->adminSectionTree->getOpened($pageVars['tree']);
|
||||||
|
$pageVars['opened'] = $this->adminSectionTree->opened;
|
||||||
|
$pageVars['articleURL'] = path('kupshop_content_articles_article_1', [
|
||||||
|
'IDa' => $ID,
|
||||||
|
'slug' => StringUtil::slugify($pageVars['data']['title']),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$SQL = sqlQuery('SELECT id_auth
|
||||||
|
FROM '.getTableName('articles_authors_relation')."
|
||||||
|
WHERE id_art='".$ID."' ");
|
||||||
|
foreach ($SQL as $row) {
|
||||||
|
$pageVars['dbAuth'][$row['id_auth']] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$SQL = sqlQuery('SELECT id_branch
|
||||||
|
FROM '.getTableName('articles_branches_admins')."
|
||||||
|
WHERE id_admin='".$GLOBALS['adminID']."' ");
|
||||||
|
$pageVars['permittedBranches'] = [];
|
||||||
|
foreach ($SQL as $row) {
|
||||||
|
$pageVars['permittedBranches'][$row['id_branch']] = 'ENABLED';
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
// zjistit povolene autory
|
||||||
|
$SQL = sqlQuery('SELECT id_auth
|
||||||
|
FROM '.getTableName('articles_authors_admins')."
|
||||||
|
WHERE id_admin='".$GLOBALS['adminID']."' ");
|
||||||
|
$pageVars['permittedAuthors'] = [];
|
||||||
|
foreach ($SQL as $row) {
|
||||||
|
$pageVars['permittedAuthors'][$row['id_auth']] = 'ENABLED';
|
||||||
|
}
|
||||||
|
if ($acn == 'edit') {
|
||||||
|
$strSections = '';
|
||||||
|
$strAuthors = '';
|
||||||
|
|
||||||
|
// kdyz jsou nejake povolene sekce
|
||||||
|
if (count($pageVars['permittedBranches']) > 0) {
|
||||||
|
foreach ($pageVars['permittedBranches'] as $key => $value) {
|
||||||
|
if ($strSections != '') {
|
||||||
|
$strSections .= ' OR ';
|
||||||
|
}
|
||||||
|
$strSections .= "ar.id_branch='".$key."'";
|
||||||
|
}
|
||||||
|
|
||||||
|
$no = returnSQLResult('SELECT COUNT(*)
|
||||||
|
FROM '.getTableName('articles').' AS a, '.getTableName('articles_relation')." AS ar
|
||||||
|
WHERE a.id='".$ID."' AND a.id=ar.id_art AND (".$strSections.') ');
|
||||||
|
if (intval($no) == 0) {
|
||||||
|
$acn = 'disabled';
|
||||||
|
// redirect("launch.php?s=error.php&id=1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// kdyz jsou nejaci povoleni autori
|
||||||
|
if (count($pageVars['permittedAuthors']) > 0) {
|
||||||
|
foreach ($pageVars['permittedAuthors'] as $key => $value) {
|
||||||
|
if ($strAuthors != '') {
|
||||||
|
$strAuthors .= ' OR ';
|
||||||
|
}
|
||||||
|
$strAuthors .= "aar.id_auth='".$key."'";
|
||||||
|
}
|
||||||
|
|
||||||
|
$no = returnSQLResult('SELECT COUNT(*)
|
||||||
|
FROM '.getTableName('articles').' AS a, '.getTableName('articles_authors_relation')." AS aar
|
||||||
|
WHERE a.id='".$ID."' AND a.id=aar.id_art AND (".$strAuthors.') ');
|
||||||
|
if (intval($no) == 0) {
|
||||||
|
$acn = 'disabled';
|
||||||
|
// redirect("launch.php?s=error.php&id=1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($pageVars['data']['id_block']) {
|
||||||
|
$pageVars['data']['blocks_history'] = $this->blocksHistory->getBlocksHistory($pageVars['data']['id_block']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach ($pageVars['tree'] as $key => $row) {
|
||||||
|
if (count($pageVars['permittedBranches']) > 0 && !array_key_exists($row['id'], $pageVars['permittedBranches']) == true) {
|
||||||
|
$pageVars['disabled'][$key] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$pageVars['data']['photos'] = sqlQueryBuilder()->select('id_photo')->from('photos_articles_relation')
|
||||||
|
->where(\Query\Operator::equals(['id_art' => $this->getID()]))
|
||||||
|
->orderBy('position')->execute()->fetchAll();
|
||||||
|
|
||||||
|
$tags = sqlQueryBuilder()
|
||||||
|
->select('at.id, at.tag')
|
||||||
|
->from('articles_tags_relation', 'atr')
|
||||||
|
->leftJoin('atr', 'articles_tags', 'at', 'at.id = atr.id_tag')
|
||||||
|
->where(\Query\Operator::equals(['atr.id_article' => $ID]))
|
||||||
|
->execute()->fetchAll();
|
||||||
|
|
||||||
|
$pageVars['data']['tags'] = array_combine(array_column($tags, 'id'), array_column($tags, 'tag'));
|
||||||
|
|
||||||
|
$authors = sqlQueryBuilder()
|
||||||
|
->select('id_auth as id')
|
||||||
|
->from('articles_authors_relation')
|
||||||
|
->where(Operator::equals(['id_art' => $ID]))
|
||||||
|
->execute()->fetchAll();
|
||||||
|
|
||||||
|
$pageVars['data']['authors'] = array_combine(array_column($authors, 'id'), array_column($authors, 'id'));
|
||||||
|
|
||||||
|
// related articles
|
||||||
|
$relatedQb = sqlQueryBuilder()
|
||||||
|
->select('ar.id_article_related as value, ar.position, a.title as label')
|
||||||
|
->from('articles_related', 'ar')
|
||||||
|
->join('ar', 'articles', 'a', 'a.id = ar.id_article_related')
|
||||||
|
->where(Operator::equals(['ar.id_article' => $ID]))
|
||||||
|
->orderBy('ar.position')
|
||||||
|
->groupBy('ar.id_article, ar.id_article_related');
|
||||||
|
|
||||||
|
if (findModule(\Modules::ARTICLES_RELATED_TYPES)) {
|
||||||
|
$relatedQb->addSelect('ar.type')
|
||||||
|
->addSelect('GROUP_CONCAT(ar.type) as types');
|
||||||
|
}
|
||||||
|
|
||||||
|
$pageVars['articles_related'] = [];
|
||||||
|
foreach ($relatedQb->execute() as $relatedKey => $relatedItem) {
|
||||||
|
$pageVars['articles_related'][$relatedKey] = $relatedItem;
|
||||||
|
if (!empty($relatedItem['types'])) {
|
||||||
|
$relatedItem['types'] = array_map('intval', explode(',', $relatedItem['types']));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$pageVars['related_additional_data'] = [
|
||||||
|
'articlesRelatedTypes' => $this->getArticlesRelatedTypes(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$pageVars['acn'] = $acn;
|
||||||
|
|
||||||
|
$pageVars['articleTranslationsFigure'] = $this->getTranslationUtil()?->getTranslationsFigure(ArticlesTranslation::class, $this->getID());
|
||||||
|
|
||||||
|
$this->unserializeCustomData($pageVars['data']);
|
||||||
|
|
||||||
|
$vars['body'] = $pageVars;
|
||||||
|
|
||||||
|
return $vars;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getData()
|
||||||
|
{
|
||||||
|
$data = parent::getData();
|
||||||
|
$acn = $this->getAction();
|
||||||
|
|
||||||
|
if (getVal('Submit')) {
|
||||||
|
$data['date'] = $this->prepareDateTime($data['date']);
|
||||||
|
$data['date_created'] = $this->prepareDateTime($data['date_created']);
|
||||||
|
$this->serializeCustomData($data);
|
||||||
|
|
||||||
|
$data['url'] = trim($data['url'] ?? '', '/');
|
||||||
|
|
||||||
|
if (findModule('seo')) {
|
||||||
|
if (empty($data['meta_title_changed'])) {
|
||||||
|
$data['meta_title'] = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($acn == 'add') {
|
||||||
|
$data['figure'] = empty($data['figure']) ? 'Y' : $data['figure'];
|
||||||
|
$data['seen'] = '0';
|
||||||
|
$data['type'] = empty($data['type']) ? 'A' : $data['type'];
|
||||||
|
$data['rating_value'] = '0';
|
||||||
|
$data['rating_voted'] = '0';
|
||||||
|
$data['comments'] = 'Y';
|
||||||
|
$data['tags'] = [];
|
||||||
|
|
||||||
|
$data['article_body'] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getObject()
|
||||||
|
{
|
||||||
|
$data = parent::getObject();
|
||||||
|
|
||||||
|
$ID = $this->getID();
|
||||||
|
|
||||||
|
$data['show_in_lead'] = 'N';
|
||||||
|
$no = returnSQLResult('SELECT COUNT(*)
|
||||||
|
FROM photos_articles_relation
|
||||||
|
WHERE id_art=:id AND show_in_lead="Y"', ['id' => $ID]);
|
||||||
|
if ($no == 0) {
|
||||||
|
$data['show_in_lead'] = 'Y';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($data['id_block'] === null) {
|
||||||
|
$data['blocks'] = [];
|
||||||
|
} else {
|
||||||
|
$data['blocks'] = $this->getBlocks($data['id_block']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleUpdate()
|
||||||
|
{
|
||||||
|
$data = $this->getData();
|
||||||
|
|
||||||
|
$SQL = parent::handleUpdate();
|
||||||
|
|
||||||
|
if ($SQL) {
|
||||||
|
$ID = $this->getID();
|
||||||
|
|
||||||
|
// SAVE BLOCKS
|
||||||
|
if (!empty($data)) {
|
||||||
|
if ($this->getAction() == 'edit') {
|
||||||
|
// historii je treba ulozit jeste pred ulozenim bloku
|
||||||
|
$this->blocksHistory->saveBlocksHistory(getVal('blocks', $data, []));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->saveBlocks($data, $this->getID(), 'articles');
|
||||||
|
$this->updateBlocksPhotosPositions($this->getID(), 'articles', 'id_art');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ############################################
|
||||||
|
// # ZARAZENI DO SEKCI
|
||||||
|
if (findModule('articles_sections') || findModule('news')) {
|
||||||
|
sqlQuery('DELETE FROM '.getTableName('articles_relation')."
|
||||||
|
WHERE id_art='".$ID."' ");
|
||||||
|
|
||||||
|
if (isset($_POST['sec'])) {
|
||||||
|
$no = count($_POST['sec']);
|
||||||
|
if ($no > 0) {
|
||||||
|
foreach ($_POST['sec'] as $key => $value) {
|
||||||
|
if (!empty($key)) {
|
||||||
|
sqlQuery('INSERT INTO '.getTableName('articles_relation')."
|
||||||
|
SET id_art='".$ID."', id_branch='".$key."' ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset($key, $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ############################################
|
||||||
|
// # ZAPSANI AUTORU
|
||||||
|
$this->deleteSQL('articles_authors_relation', ['id_art' => $ID]);
|
||||||
|
if (!empty($data['authors'])) {
|
||||||
|
foreach (array_unique($data['authors']) as $authorId) {
|
||||||
|
$this->insertSQL('articles_authors_relation', ['id_art' => $ID, 'id_auth' => $authorId]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ############################################
|
||||||
|
|
||||||
|
// Save related articles
|
||||||
|
$this->deleteSQL('articles_related', ['id_article' => $ID]);
|
||||||
|
foreach ($data['articles_related'] ?? [] as $related) {
|
||||||
|
if (!empty($related['delete'])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (findModule(\Modules::ARTICLES_RELATED_TYPES)) {
|
||||||
|
$types = $related['type'] ?? [];
|
||||||
|
if (empty($types)) {
|
||||||
|
$types = [$this->getArticlesRelatedTypes()[0]['id']];
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($types as $type) {
|
||||||
|
sqlQueryBuilder()
|
||||||
|
->insert('articles_related')
|
||||||
|
->directValues(
|
||||||
|
[
|
||||||
|
'id_article' => $ID,
|
||||||
|
'id_article_related' => $related['id_article'],
|
||||||
|
'position' => $related['position'],
|
||||||
|
'type' => $type,
|
||||||
|
]
|
||||||
|
)->execute();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sqlQueryBuilder()
|
||||||
|
->insert('articles_related')
|
||||||
|
->directValues(
|
||||||
|
[
|
||||||
|
'id_article' => $ID,
|
||||||
|
'id_article_related' => $related['id_article'],
|
||||||
|
'position' => $related['position'],
|
||||||
|
]
|
||||||
|
)->execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save tags
|
||||||
|
$this->deleteSQL('articles_tags_relation', ['id_article' => $ID]);
|
||||||
|
if (!empty($data['tags'])) {
|
||||||
|
foreach (array_unique($data['tags']) as $id_tag) {
|
||||||
|
$this->insertSQL('articles_tags_relation', ['id_article' => $ID, 'id_tag' => $id_tag]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save translations figure
|
||||||
|
$this->getTranslationUtil()?->updateTranslationsFigure(ArticlesTranslation::class, $this->getID(), $data['translation_figure'] ?? []);
|
||||||
|
|
||||||
|
if (!empty($data['products'])) {
|
||||||
|
foreach ($data['products'] as $id => $item) {
|
||||||
|
$item['id'] = intval($id);
|
||||||
|
|
||||||
|
if (!empty($item['delete']) || !$id) {
|
||||||
|
if ($id > 0) {
|
||||||
|
$this->deleteSQL('products_in_articles', ['id_product' => $item['id_product'], 'id_article' => $ID]);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if ($id < 0) {
|
||||||
|
$this->insertSQL('products_in_articles', ['id_product' => $item['id_product'], 'id_article' => $ID]);
|
||||||
|
}
|
||||||
|
} catch (Doctrine\DBAL\DBALException $e) {
|
||||||
|
if (intval($e->getPrevious()->errorInfo[1]) == '1062') {
|
||||||
|
$this->returnError('Produkt je již k tomuto článku přidán!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->returnOK();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $SQL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleDelete()
|
||||||
|
{
|
||||||
|
$IDa = $this->getID();
|
||||||
|
$object = $this->getObject();
|
||||||
|
|
||||||
|
writeDownActivity('smazán článek: '.
|
||||||
|
returnSQLResult('SELECT title
|
||||||
|
FROM '.getTableName('articles')."
|
||||||
|
WHERE id='".$IDa."' "));
|
||||||
|
|
||||||
|
sqlQuery('DELETE FROM '.getTableName('photos_articles')."
|
||||||
|
WHERE id_art='".$IDa."' ");
|
||||||
|
|
||||||
|
sqlQuery('DELETE FROM '.getTableName('articles_relation')."
|
||||||
|
WHERE id_art='".$IDa."' ");
|
||||||
|
|
||||||
|
sqlQuery('DELETE FROM '.getTableName('articles_authors_relation')."
|
||||||
|
WHERE id_art='".$IDa."' ");
|
||||||
|
|
||||||
|
sqlQuery('DELETE FROM '.getTableName('articles')."
|
||||||
|
WHERE id='".$IDa."' ");
|
||||||
|
|
||||||
|
$this->removeBlocks($object['id_block']);
|
||||||
|
|
||||||
|
redirect('launch.php?s=articles.php&acn=erased&refresh=parent&ErrStr='.urlencode('Článek byl odstraněn.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getArticlesRelatedTypes(): array
|
||||||
|
{
|
||||||
|
if (!findModule(\Modules::ARTICLES_RELATED_TYPES)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return sqlQueryBuilder()
|
||||||
|
->select('id, name')
|
||||||
|
->from('articles_related_types')
|
||||||
|
->orderBy('id', 'ASC')
|
||||||
|
->execute()->fetchAllAssociative();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Articles::class;
|
||||||
9
admin/articlesTags.php
Normal file
9
admin/articlesTags.php
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class ArticlesTags extends Window
|
||||||
|
{
|
||||||
|
protected $tableName = 'articles_tags';
|
||||||
|
protected $nameField = 'tag';
|
||||||
|
}
|
||||||
|
|
||||||
|
return ArticlesTags::class;
|
||||||
135
admin/artsections.php
Normal file
135
admin/artsections.php
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Artsections extends Window
|
||||||
|
{
|
||||||
|
protected $tableName = 'articles_branches';
|
||||||
|
protected $show_on_web = 'articlesSection';
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->defaults = ['date' => date('Y-m-d H:i'),
|
||||||
|
'behaviour' => '1',
|
||||||
|
'orderby' => 'date',
|
||||||
|
'orderdir' => 'ASC',
|
||||||
|
'top_branch' => null,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_vars()
|
||||||
|
{
|
||||||
|
$vars = parent::get_vars();
|
||||||
|
$pageVars = getVal('body', $vars);
|
||||||
|
|
||||||
|
$acn = $this->getAction();
|
||||||
|
$ID = $this->getID();
|
||||||
|
$pageVars['tree'] = $this->articlesSections(null, 0, $ID);
|
||||||
|
|
||||||
|
if ($acn == 'remove') {
|
||||||
|
$SQL = sqlQuery('SELECT * FROM '.getTableName('articles_branches')." WHERE id='{$ID}' ");
|
||||||
|
foreach ($SQL as $row) {
|
||||||
|
$pageVars['data'] = $row;
|
||||||
|
}
|
||||||
|
$pageVars['acn'] = 'erase';
|
||||||
|
}
|
||||||
|
|
||||||
|
$vars['body'] = $pageVars;
|
||||||
|
|
||||||
|
return $vars;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getData()
|
||||||
|
{
|
||||||
|
$data = parent::getData();
|
||||||
|
if (isset($data['template'])) {
|
||||||
|
$data['template'] = !preg_match('/^[a-zA-Z0-9_\-.]+$/', $data['template']) ? null : $data['template'];
|
||||||
|
}
|
||||||
|
if (isset($data['items_per_page'])) {
|
||||||
|
$data['items_per_page'] = empty($data['items_per_page']) || !is_numeric($data['items_per_page']) ? null : (int) $data['items_per_page'];
|
||||||
|
}
|
||||||
|
if (empty($data['top_branch'])) {
|
||||||
|
$data['top_branch'] = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleUpdate()
|
||||||
|
{
|
||||||
|
clearCache('article-sections-', true);
|
||||||
|
|
||||||
|
$newBranchId = $_POST['data']['top_branch'] ?? null;
|
||||||
|
$childrenIds = $this->getDescendantCategories($this->getID());
|
||||||
|
|
||||||
|
if (in_array($newBranchId, $childrenIds)) {
|
||||||
|
$this->returnError('Nelze zvolit jako nadřazenou sekci některou z podsekcí!');
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::handleUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDescendantCategories($topBranch): array
|
||||||
|
{
|
||||||
|
return sqlFetchAll(sqlQuery(
|
||||||
|
'WITH RECURSIVE cte (level, id) AS (
|
||||||
|
SELECT 0, SR1.top_branch
|
||||||
|
FROM articles_branches SR1
|
||||||
|
WHERE SR1.top_branch = :top_branch
|
||||||
|
UNION ALL
|
||||||
|
SELECT cte.level + 1, SR2.id
|
||||||
|
FROM articles_branches SR2
|
||||||
|
INNER JOIN cte ON (cte.id = SR2.top_branch)
|
||||||
|
WHERE cte.level < 50
|
||||||
|
)
|
||||||
|
SELECT id
|
||||||
|
FROM cte ORDER BY level', ['top_branch' => $topBranch]), ['id' => 'id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleDelete()
|
||||||
|
{
|
||||||
|
clearCache('article-sections-', true);
|
||||||
|
|
||||||
|
$IDsec = $this->getID();
|
||||||
|
$IDsecSel = getVal('IDsecSel');
|
||||||
|
if ($IDsecSel > 0) {
|
||||||
|
@sqlQuery('UPDATE '.getTableName('articles_relation')."
|
||||||
|
SET id_branch='".$IDsecSel."'
|
||||||
|
WHERE id_branch='".$IDsec."' ");
|
||||||
|
} elseif ($IDsecSel == 0) {
|
||||||
|
@sqlQuery('DELETE
|
||||||
|
FROM '.getTableName('articles_relation')."
|
||||||
|
WHERE id_branch='".$IDsec."' ");
|
||||||
|
}
|
||||||
|
|
||||||
|
$SQL = @sqlQuery('DELETE
|
||||||
|
FROM '.getTableName('articles_branches')."
|
||||||
|
WHERE id='".$IDsec."' ");
|
||||||
|
writeDownActivity(sprintf(translate('activityDeleted'), $IDsec));
|
||||||
|
redirect('launch.php?s=artsections.php&acn=erased&ErrStr='.urlencode(translate('note_5')));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function articlesSections($topCat, $Pos = 0, $ignored = null)
|
||||||
|
{
|
||||||
|
$SQL = sqlQueryBuilder()
|
||||||
|
->select('ab.id, ab.name, ab.descr, ab.figure')
|
||||||
|
->from('articles_branches', 'ab')
|
||||||
|
->where(\Query\Operator::equalsNullable(['ab.top_branch' => $topCat]))
|
||||||
|
->orderBy('ab.name', 'ASC')
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
$data = [];
|
||||||
|
foreach ($SQL as $key => $row) {
|
||||||
|
if ($ignored == null || $ignored != $row['id']) {
|
||||||
|
$data[$key]['id'] = $row['id'];
|
||||||
|
$data[$key]['title'] = $row['name'];
|
||||||
|
$data[$key]['figure'] = $row['figure'];
|
||||||
|
$data[$key]['level'] = $Pos;
|
||||||
|
$data[$key]['submenu'] = $this->articlesSections($row['id'], $Pos + 1, $ignored = null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$artsections = new Artsections();
|
||||||
|
$artsections->run();
|
||||||
2005
admin/autocomplete.php
Normal file
2005
admin/autocomplete.php
Normal file
File diff suppressed because it is too large
Load Diff
268
admin/automatic_import.php
Normal file
268
admin/automatic_import.php
Normal file
@@ -0,0 +1,268 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class AutomaticImports extends Window
|
||||||
|
{
|
||||||
|
protected $tableName = 'import';
|
||||||
|
protected $template = 'window/automatic_import.tpl';
|
||||||
|
|
||||||
|
public function get_vars()
|
||||||
|
{
|
||||||
|
$ID = $this->getID();
|
||||||
|
$vars = parent::get_vars();
|
||||||
|
$pageVars = getVal('body', $vars);
|
||||||
|
$acn = $this->getAction();
|
||||||
|
|
||||||
|
if ($acn == 'edit' || ($acn == 'add' && $this->isDuplicate() && !empty($ID))) {
|
||||||
|
$SQL = sqlQuery('SELECT s.*
|
||||||
|
FROM '.getTableName('import')." s
|
||||||
|
WHERE s.id='".$ID."' ");
|
||||||
|
if (sqlNumRows($SQL) == 1) {
|
||||||
|
$pageVars['data'] = sqlFetchArray($SQL);
|
||||||
|
if ($acn == 'add' && $this->isDuplicate() && !empty($ID)) {
|
||||||
|
$pageVars['data']['name'] = stringCopy(trim($pageVars['data']['name']));
|
||||||
|
}
|
||||||
|
$pageVars['data']['local_file'] = $GLOBALS['cfg']['Path']['data'].'/tmp/autoimport_'.$ID;
|
||||||
|
if (empty($pageVars['data']['source']) && file_exists($pageVars['data']['local_file'])) {
|
||||||
|
$pageVars['data']['source_type'] = 'upload';
|
||||||
|
} else {
|
||||||
|
$pageVars['data']['source_type'] = 'url';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} elseif ($acn == 'add') {
|
||||||
|
$pageVars['data']['source_type'] = 'upload';
|
||||||
|
$pageVars['data']['source'] = '';
|
||||||
|
$pageVars['data']['type'] = AutomaticImport::TYPE_XML;
|
||||||
|
$pageVars['data']['interval'] = 1;
|
||||||
|
$pageVars['data']['delete_old'] = null;
|
||||||
|
$pageVars['data']['modify_in_store'] = 1;
|
||||||
|
$pageVars['data']['pair'] = 1;
|
||||||
|
$pageVars['data']['local_file'] = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = sqlQuery('SELECT id, name FROM '.getTableName('suppliers'));
|
||||||
|
foreach ($sql as $row) {
|
||||||
|
$pageVars['suppliers'][$row['id']] = $row['name'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$pageVars['automatic_import'] = AutomaticImport::$types;
|
||||||
|
|
||||||
|
if (file_exists($pageVars['data']['local_file'])) {
|
||||||
|
$pageVars['data']['local_file_time'] = date('d.m.Y H:i:s', filemtime($pageVars['data']['local_file']));
|
||||||
|
}
|
||||||
|
|
||||||
|
$pageVars['choices'] = ['1' => 'u produktu/varianty'];
|
||||||
|
if (findModule(\Modules::PRODUCTS_SUPPLIERS) || findModule(\Modules::SUPPLIERS)) {
|
||||||
|
$pageVars['choices']['0'] = 'u dodavatele';
|
||||||
|
}
|
||||||
|
|
||||||
|
$pageVars['add_new'] = [
|
||||||
|
'0' => 'Pouze aktualizovat stávající',
|
||||||
|
'1' => 'Přidat nové i aktualizovat stávající',
|
||||||
|
'2' => 'Pouze přidat nové',
|
||||||
|
'3' => 'Přidat a aktualizovat pouze varianty',
|
||||||
|
];
|
||||||
|
$pageVars['pair'] = ['0' => 'Ne', '1' => 'Ano'];
|
||||||
|
|
||||||
|
if (findModule('products_suppliers') && !empty($pageVars['data']['id_supplier'])) {
|
||||||
|
$pageVars['products_of_suppliers'] = returnSQLResult('SELECT COUNT(*) FROM '.getTableName('products_of_suppliers')." pos WHERE pos.id_supplier='{$pageVars['data']['id_supplier']}'");
|
||||||
|
}
|
||||||
|
|
||||||
|
$vars['type'] = 'automatic_import';
|
||||||
|
$vars['body'] = $pageVars;
|
||||||
|
|
||||||
|
return $vars;
|
||||||
|
}
|
||||||
|
|
||||||
|
// protected function getData()
|
||||||
|
// {
|
||||||
|
// $data = parent::getData();
|
||||||
|
//
|
||||||
|
// $data['transformation'] = $this->prettyXml($data['transformation']);
|
||||||
|
//
|
||||||
|
// return $data;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// function prettyXml($string)
|
||||||
|
// {
|
||||||
|
// $domxml = new DOMDocument('1.0');
|
||||||
|
// $domxml->preserveWhiteSpace = false;
|
||||||
|
// $domxml->formatOutput = true;
|
||||||
|
//
|
||||||
|
// /* @var $xml SimpleXMLElement */
|
||||||
|
// $domxml->loadXML($string);
|
||||||
|
// return $domxml->saveXML();
|
||||||
|
// }
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$ID = $this->getID();
|
||||||
|
|
||||||
|
ini_set('memory_limit', '1024M');
|
||||||
|
|
||||||
|
$synchronize = getVal('synchronize');
|
||||||
|
$synchronize_try = getVal('synchronize_try');
|
||||||
|
if ((!empty($synchronize) || !empty($synchronize_try)) && !empty($ID)) {
|
||||||
|
// $errors = error_reporting(E_ALL|E_STRICT);
|
||||||
|
|
||||||
|
$import = \KupShop\KupShopBundle\Util\Compat\ServiceContainer::getService(\KupShop\AdminBundle\Util\AutomaticImport::class);
|
||||||
|
|
||||||
|
$import->setData($ID);
|
||||||
|
|
||||||
|
if (getVal('dumpXmlBefore') || getVal('dumpXmlAfter')) {
|
||||||
|
if (!$import->parseParams()) {
|
||||||
|
exit($import->error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$import->getSourceFile()) {
|
||||||
|
exit($import->error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$import->getXML()) {
|
||||||
|
exit($import->error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getVal('dumpXmlBefore')) {
|
||||||
|
exit($import->dumpXML());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$import->transformXML()) {
|
||||||
|
exit($import->error);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit($import->dumpXML());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$import->process(!empty($synchronize_try))) {
|
||||||
|
redirect('launch.php?s=automatic_import.php&acn=edit&refresh=parent&ID='.$ID.'&ErrStr='.urlencode("Chyba importu: {$import->error}"));
|
||||||
|
}
|
||||||
|
|
||||||
|
$import->deleteOldProducts();
|
||||||
|
|
||||||
|
$import->showUpdatedProducts();
|
||||||
|
|
||||||
|
// presmerovani
|
||||||
|
if (empty($synchronize_try)) {
|
||||||
|
$smarty = createSmarty(true, true);
|
||||||
|
$smarty->assign(Window::get_vars());
|
||||||
|
$smarty->assign([
|
||||||
|
'ID' => $this->getID(),
|
||||||
|
'import' => $import,
|
||||||
|
'view' => $this,
|
||||||
|
]);
|
||||||
|
$columns = $import->getDebugData();
|
||||||
|
|
||||||
|
$updatedProducts = array_filter($import->updatedCreatedProducts ?? [], function ($product) {
|
||||||
|
return $product['status'] != 'ignorován';
|
||||||
|
});
|
||||||
|
|
||||||
|
$smarty->assign(['updatedProducts' => $updatedProducts]);
|
||||||
|
$smarty->assign($columns);
|
||||||
|
$smarty->display('window/import.result.tpl');
|
||||||
|
if (in_array('import_error', $columns['columns'])) {
|
||||||
|
$number = 0;
|
||||||
|
foreach ($columns['products'] as $product) {
|
||||||
|
if (!empty($product['import_error'])) {
|
||||||
|
$number++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writeDownActivity('Pozor: Auto. import - počet neúspěšně importovaných souborů:'.$number);
|
||||||
|
}
|
||||||
|
exit;
|
||||||
|
/*$ret = "";
|
||||||
|
$ret .= "Načteno {$import->stats['products']} produktů\\n";
|
||||||
|
$ret .= "Načteno {$import->stats['variations']} variant\\n";
|
||||||
|
$ret .= "Vytvořeno {$import->stats['products_created']} produktů\\n";
|
||||||
|
$ret .= "Vytvořeno {$import->stats['variations_created']} variant\\n";
|
||||||
|
$ret .= "Aktualizováno {$import->stats['products_updated']} produktů\\n";
|
||||||
|
$ret .= "Aktualizováno {$import->stats['variations_updated']} variant\\n";
|
||||||
|
$ret .= "Smazáno ".count($import->stats['deleted'])." starých produktů/variant\\n";
|
||||||
|
//$ret .= "Smazáno ".count($import->stats['variations_deleted'])." starých variant\\n";
|
||||||
|
|
||||||
|
redirect("launch.php?s=automatic_import.php&acn=edit&refresh=parent&ID=".$ID."&ErrStr=".urlencode($ret));*/
|
||||||
|
} else {
|
||||||
|
$smarty = createSmarty(true, true);
|
||||||
|
$smarty->assign(Frame::get_vars());
|
||||||
|
$smarty->assign([
|
||||||
|
'data' => $this->getData(),
|
||||||
|
'ID' => $this->getID(),
|
||||||
|
'import' => $import,
|
||||||
|
'view' => $this,
|
||||||
|
'all' => getVal('all'),
|
||||||
|
]);
|
||||||
|
$smarty->assign($import->getDebugData());
|
||||||
|
$smarty->display('window/automatic_import.dump.tpl');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// error_reporting($errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
parent::handle();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleUpdate()
|
||||||
|
{
|
||||||
|
$data = $this->getData();
|
||||||
|
$ID = $this->getID();
|
||||||
|
$acn = $this->getAction();
|
||||||
|
|
||||||
|
$SQL = parent::handleUpdate();
|
||||||
|
|
||||||
|
if ($SQL) {
|
||||||
|
if ($acn == 'add') {
|
||||||
|
$ID = sqlInsertID();
|
||||||
|
}
|
||||||
|
if (!empty($_FILES['source_file']) && is_uploaded_file($_FILES['source_file']['tmp_name'])) {
|
||||||
|
$data['local_file'] = $GLOBALS['cfg']['Path']['data'].'/tmp/autoimport_'.$ID;
|
||||||
|
if (!move_uploaded_file($_FILES['source_file']['tmp_name'], $data['local_file'])) {
|
||||||
|
$ErrStr = 'Nelze přesunout uploadovaný soubor.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $SQL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleDownload()
|
||||||
|
{
|
||||||
|
$ID = $this->getID();
|
||||||
|
$type = returnSqlResult('SELECT type
|
||||||
|
FROM '.getTableName('import')." s
|
||||||
|
WHERE s.id='{$ID}' ");
|
||||||
|
|
||||||
|
$file = $GLOBALS['cfg']['Path']['data'].'/tmp/autoimport_'.$ID;
|
||||||
|
|
||||||
|
if (!file_exists($file)) {
|
||||||
|
$this->returnError('Soubor neexistuje');
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($type) {
|
||||||
|
case AutomaticImport::TYPE_XML:
|
||||||
|
$contentType = 'application/pdf';
|
||||||
|
$extension = 'pdf';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AutomaticImport::TYPE_CSV:
|
||||||
|
$contentType = 'text/csv';
|
||||||
|
$extension = 'csv';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AutomaticImport::TYPE_XLS:
|
||||||
|
$contentType = 'application/vnd.ms-excel';
|
||||||
|
$extension = 'xls';
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
$contentType = 'application/octet-stream';
|
||||||
|
$extension = 'bin';
|
||||||
|
}
|
||||||
|
|
||||||
|
header("Content-type: {$contentType}");
|
||||||
|
header("Content-Disposition: attachment; filename=\"automatic_import_{$ID}.{$extension}\"");
|
||||||
|
|
||||||
|
readfile($file);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return AutomaticImports::class;
|
||||||
55
admin/barcode.php
Normal file
55
admin/barcode.php
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
if (!class_exists(Picqer\Barcode\BarcodeGeneratorPNG::class)) {
|
||||||
|
// HACK superhack, ale jinak to nejde, je to kvuli kompatibilite, nekteri to volaji
|
||||||
|
// naprimo z /engine aby to bylo bez loginu pres admin
|
||||||
|
chdir(str_replace('engine/admin/barcode.php', '', $_SERVER['SCRIPT_FILENAME']));
|
||||||
|
|
||||||
|
if (file_exists('./config/config.php')) {
|
||||||
|
require_once './config/config.php';
|
||||||
|
} else {
|
||||||
|
require_once './include/config.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once './include/functions.php';
|
||||||
|
require_once './engine/web/common.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
$type = 'int25';
|
||||||
|
if (!empty($_GET['type'])) {
|
||||||
|
$type = $_GET['type'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($type == 'ean13') {
|
||||||
|
$_GET['oID'] = sprintf('%013d', intval($_GET['oID']));
|
||||||
|
}
|
||||||
|
|
||||||
|
$height = 60;
|
||||||
|
if (!empty($_GET['height'])) {
|
||||||
|
$height = $_GET['height'];
|
||||||
|
}
|
||||||
|
$size = $_GET['size'] ?? 1;
|
||||||
|
$show_value = ($_GET['showValue'] ?? '') !== 'false';
|
||||||
|
|
||||||
|
// Convert to BarcodeGenerator
|
||||||
|
$generator = new Picqer\Barcode\BarcodeGeneratorPNG();
|
||||||
|
|
||||||
|
switch ($type) {
|
||||||
|
case 'int25':
|
||||||
|
$type = $generator::TYPE_INTERLEAVED_2_5;
|
||||||
|
break;
|
||||||
|
case 'ean13':
|
||||||
|
$type = $generator::TYPE_EAN_13;
|
||||||
|
break;
|
||||||
|
case 'code39':
|
||||||
|
$type = $generator::TYPE_CODE_39;
|
||||||
|
break;
|
||||||
|
case 'code128':
|
||||||
|
$type = $generator::TYPE_CODE_128;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $generator->getBarcode($_GET['oID'], $type, $size + 1, $height);
|
||||||
|
|
||||||
|
header('Content-Type: image/png');
|
||||||
|
echo $result;
|
||||||
20
admin/board.php
Normal file
20
admin/board.php
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
global $cfg, $type;
|
||||||
|
|
||||||
|
use KupShop\AdminBundle\Util\AdminClassLocator;
|
||||||
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||||
|
|
||||||
|
$type = getVal('type', null, 'index');
|
||||||
|
$className = $type;
|
||||||
|
|
||||||
|
$adminClassLocator = ServiceContainer::getService(AdminClassLocator::class);
|
||||||
|
$classPath = $adminClassLocator->getClassPath('board/board.'.$className.'.php');
|
||||||
|
|
||||||
|
if (file_exists($classPath)) {
|
||||||
|
$list = $adminClassLocator->createClass($classPath, $className);
|
||||||
|
$list->run();
|
||||||
|
} else {
|
||||||
|
$err = "Neexistující board {$type}";
|
||||||
|
throw new Exception('Neexistující board '.$type);
|
||||||
|
}
|
||||||
9
admin/board/board.export_orders.php
Normal file
9
admin/board/board.export_orders.php
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// ##############################################################
|
||||||
|
$main_class = 'ExportOrdersBoard';
|
||||||
|
|
||||||
|
class ExportOrdersBoard extends Frame
|
||||||
|
{
|
||||||
|
protected $template = 'board/export_orders.tpl';
|
||||||
|
}
|
||||||
19
admin/board/board.export_products.php
Normal file
19
admin/board/board.export_products.php
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// ##############################################################
|
||||||
|
$main_class = 'ExportProductsBoard';
|
||||||
|
|
||||||
|
class ExportProductsBoard extends Frame
|
||||||
|
{
|
||||||
|
protected $template = 'board/export_products.tpl';
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
if (getVal('Submit')) {
|
||||||
|
$export = new ExportProducts();
|
||||||
|
$export->getFile();
|
||||||
|
|
||||||
|
exit('Done');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
19
admin/board/board.export_selling_products.php
Normal file
19
admin/board/board.export_selling_products.php
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// ##############################################################
|
||||||
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||||
|
|
||||||
|
$main_class = 'ExportSellingProducts';
|
||||||
|
|
||||||
|
class ExportSellingProducts extends Frame
|
||||||
|
{
|
||||||
|
protected $template = 'board/export_selling_products.tpl';
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
if (getVal('Submit')) {
|
||||||
|
$export = ServiceContainer::getService(\KupShop\AdminBundle\Util\Export\ExportProductsSelling::class);
|
||||||
|
$export->exportXLS();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
20
admin/board/board.export_users.php
Normal file
20
admin/board/board.export_users.php
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use KupShop\AdminBundle\Util\Export\ExportUsers;
|
||||||
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||||
|
|
||||||
|
class ExportUsersBoard extends Frame
|
||||||
|
{
|
||||||
|
protected $template = 'board/export_users.tpl';
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
if (getVal('Submit')) {
|
||||||
|
$export = ServiceContainer::getService(ExportUsers::class);
|
||||||
|
|
||||||
|
$export->exportXLSX();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ExportUsersBoard::class;
|
||||||
88
admin/board/board.index.php
Normal file
88
admin/board/board.index.php
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use KupShop\KupShopBundle\Context\DomainContext;
|
||||||
|
use KupShop\KupShopBundle\Util\Contexts;
|
||||||
|
use KupShop\OrderingBundle\Util\Order\OrderInfo;
|
||||||
|
use Query\Operator;
|
||||||
|
|
||||||
|
$main_class = 'IndexBoard';
|
||||||
|
|
||||||
|
class IndexBoard extends Frame
|
||||||
|
{
|
||||||
|
protected $template = 'board/index.tpl';
|
||||||
|
|
||||||
|
public function get_vars()
|
||||||
|
{
|
||||||
|
$vars = parent::get_vars();
|
||||||
|
|
||||||
|
$stats = [];
|
||||||
|
|
||||||
|
$today = new DateTime('today');
|
||||||
|
$todayRange = new \Range($today->format('Y-m-d 00:00:00'), $today->format('Y-m-d 23:59:59'));
|
||||||
|
|
||||||
|
$orders = sqlQueryBuilder()->select('COUNT(id)')
|
||||||
|
->from('orders')
|
||||||
|
->andWhere('status_storno=0')
|
||||||
|
->andWhere(Operator::between('date_created', $todayRange))
|
||||||
|
->andWhere(Operator::not(Operator::equals(['source' => OrderInfo::ORDER_SOURCE_RETURNS])));
|
||||||
|
$stats['today_orders'] = $orders->execute()->fetchOne();
|
||||||
|
|
||||||
|
$total_price = (findModule(Modules::CURRENCIES) ? 'total_price * currency_rate' : 'total_price');
|
||||||
|
$orders->select("SUM({$total_price})");
|
||||||
|
$stats['today_price'] = $orders->execute()->fetchOne();
|
||||||
|
|
||||||
|
$stats['unfinished_orders'] = returnSQLResult("SELECT COUNT(*) FROM orders WHERE status='0' AND status_storno='0'");
|
||||||
|
|
||||||
|
$stats['total_products'] = returnSQLResult('SELECT COUNT(*) FROM products');
|
||||||
|
|
||||||
|
$yesterday = (new DateTime('yesterday'))->format('Y-m-d H:i:s');
|
||||||
|
|
||||||
|
$stats['errors_critical'] = sqlQueryBuilder()->select('COUNT(*)')
|
||||||
|
->from('report_activities')
|
||||||
|
->where('date > :date')
|
||||||
|
->andWhere(Operator::equals(['severity' => 'error']))
|
||||||
|
->andWhere(Operator::not(Operator::equals(['type' => 'sync'])))
|
||||||
|
->setParameter('date', getAdminUser()['date_check_error'] ?? $yesterday)
|
||||||
|
->execute()->fetchColumn();
|
||||||
|
|
||||||
|
$stats['errors_sync'] = sqlQueryBuilder()->select('COUNT(*)')
|
||||||
|
->from('report_activities')
|
||||||
|
->where('date > :date')
|
||||||
|
->andWhere(Operator::equals(['severity' => 'error']))
|
||||||
|
->andWhere(Operator::equals(['type' => 'sync']))
|
||||||
|
->setParameter('date', getAdminUser()['date_check_error'] ?? $yesterday)
|
||||||
|
->execute()->fetchColumn();
|
||||||
|
|
||||||
|
$stats['errors_recommendation'] = sqlQueryBuilder()->select('COUNT(*)')
|
||||||
|
->from('report_activities')
|
||||||
|
->where('date > :date')
|
||||||
|
->andWhere(Operator::equals(['severity' => 'recommendation']))
|
||||||
|
->setParameter('date', $yesterday)
|
||||||
|
->execute()->fetchColumn();
|
||||||
|
|
||||||
|
$links = [];
|
||||||
|
|
||||||
|
$mainDomain = Contexts::get(DomainContext::class)->getSupported()[0];
|
||||||
|
$domain = join('.', array_slice(explode('.', $mainDomain), -2));
|
||||||
|
|
||||||
|
if (strpos($domain, 'kupshop.cz') !== false || strpos($domain, 'wpj.biz') !== false || strpos($domain, 'wpj.cloud') !== false || strpos($domain, 'wpjshop.cz') !== false) {
|
||||||
|
$domain = join('.', array_slice(explode('.', $mainDomain), -3));
|
||||||
|
}
|
||||||
|
|
||||||
|
$hash = md5(date('Y-m-d').'wpj_wpj');
|
||||||
|
$hash = base64_encode(json_encode(['url' => 'https://'.$domain, 'hash' => $hash]));
|
||||||
|
|
||||||
|
$links['klient'] = "https://klient.wpj.cz/list/{$hash}";
|
||||||
|
|
||||||
|
$vars['stats'] = $stats;
|
||||||
|
$vars['links'] = $links;
|
||||||
|
|
||||||
|
if (isAutoDeploy()) {
|
||||||
|
$vars['deploy_time'] = filemtime(__FILE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
$vars['changelog_time'] = getAdminUser()['date_check_changelog'] ?? (new DateTime('yesterday'))->format('c');
|
||||||
|
|
||||||
|
return $vars;
|
||||||
|
}
|
||||||
|
}
|
||||||
178
admin/board/board.usersImport.php
Normal file
178
admin/board/board.usersImport.php
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$main_class = 'usersImport';
|
||||||
|
|
||||||
|
class UsersImport extends Frame
|
||||||
|
{
|
||||||
|
use DatabaseCommunication;
|
||||||
|
|
||||||
|
protected $template = 'board/usersImport.tpl';
|
||||||
|
|
||||||
|
protected $errs = [];
|
||||||
|
protected $info = [];
|
||||||
|
protected $added_users = [];
|
||||||
|
|
||||||
|
public function get_vars()
|
||||||
|
{
|
||||||
|
$vars = parent::get_vars();
|
||||||
|
|
||||||
|
$vars['errs'] = $this->errs;
|
||||||
|
$vars['info'] = $this->info;
|
||||||
|
$vars['added_users'] = $this->added_users;
|
||||||
|
|
||||||
|
return $vars;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$try = getVal('Try');
|
||||||
|
$execute = getVal('Execute');
|
||||||
|
global $cfg;
|
||||||
|
|
||||||
|
if (!empty($execute) || (!empty($try))) {
|
||||||
|
if (!empty($_FILES['file']['tmp_name'])) {
|
||||||
|
$path = $cfg['Path']['data'].'tmp/users_import.xsl';
|
||||||
|
|
||||||
|
move_uploaded_file($_FILES['file']['tmp_name'], $path);
|
||||||
|
|
||||||
|
// Increase memory for large files
|
||||||
|
ini_set('memory_limit', '512M');
|
||||||
|
|
||||||
|
$import = new AutomaticImportTransform($path);
|
||||||
|
$users_array = $import->LoadBinfileAsArray();
|
||||||
|
/*
|
||||||
|
* A = jméno
|
||||||
|
* B = přijmení
|
||||||
|
* C = společnost
|
||||||
|
* D = email
|
||||||
|
* E = telefon
|
||||||
|
* F = ulice
|
||||||
|
* G = město
|
||||||
|
* H = země
|
||||||
|
* I = psč
|
||||||
|
* J = skupiny
|
||||||
|
* K = newsletter
|
||||||
|
* L = ICO
|
||||||
|
* M = DIC
|
||||||
|
* N = delivery name
|
||||||
|
* O = delivery surname
|
||||||
|
* P = delivery firm
|
||||||
|
* Q = delivery street
|
||||||
|
* R = delivery city
|
||||||
|
* S = delivery zip
|
||||||
|
* T = delivery_country
|
||||||
|
*/
|
||||||
|
$errs = [];
|
||||||
|
$added = 0;
|
||||||
|
$price_levels = sqlFetchAll(sqlQueryBuilder()->select('id, name')->from('price_levels')->execute(), ['id' => 'name']);
|
||||||
|
foreach (reset($users_array) as $index => $user) {
|
||||||
|
if ($index == 1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!empty($user['D'])) {
|
||||||
|
if (filter_var($user['D'], FILTER_VALIDATE_EMAIL)) {
|
||||||
|
$groups = [];
|
||||||
|
if (!empty($user['K'])) {
|
||||||
|
$groups = explode(';', str_replace(' ', '', $user['K']));
|
||||||
|
}
|
||||||
|
|
||||||
|
$fields = ['figure' => 'N'];
|
||||||
|
if (!empty($user['A'])) {
|
||||||
|
$fields['name'] = $user['A'];
|
||||||
|
}
|
||||||
|
if (!empty($user['B'])) {
|
||||||
|
$fields['surname'] = $user['B'];
|
||||||
|
}
|
||||||
|
if (!empty($user['C'])) {
|
||||||
|
$fields['firm'] = $user['C'];
|
||||||
|
}
|
||||||
|
if (!empty($user['E'])) {
|
||||||
|
$fields['phone'] = $user['E'];
|
||||||
|
}
|
||||||
|
if (!empty($user['F'])) {
|
||||||
|
$fields['street'] = $user['F'];
|
||||||
|
}
|
||||||
|
if (!empty($user['G'])) {
|
||||||
|
$fields['city'] = $user['G'];
|
||||||
|
}
|
||||||
|
if (!empty($user['H'])) {
|
||||||
|
$fields['zip'] = $user['H'];
|
||||||
|
}
|
||||||
|
if (!empty($user['I'])) {
|
||||||
|
$fields['state'] = $user['I'];
|
||||||
|
}
|
||||||
|
if (!empty($user['J'])) {
|
||||||
|
$fields['country'] = $user['J'];
|
||||||
|
}
|
||||||
|
if (!empty($user['L'])) {
|
||||||
|
$fields['get_news'] = ($user['L'] == 'ano') ? 'Y' : 'N';
|
||||||
|
}
|
||||||
|
if (!empty($user['M'])) {
|
||||||
|
$fields['ico'] = $user['M'];
|
||||||
|
}
|
||||||
|
if (!empty($user['N'])) {
|
||||||
|
$fields['dic'] = $user['N'];
|
||||||
|
}
|
||||||
|
if (!empty($user['O'])) {
|
||||||
|
$fields['delivery_name'] = $user['O'];
|
||||||
|
}
|
||||||
|
if (!empty($user['P'])) {
|
||||||
|
$fields['delivery_surname'] = $user['P'];
|
||||||
|
}
|
||||||
|
if (!empty($user['Q'])) {
|
||||||
|
$fields['delivery_firm'] = $user['Q'];
|
||||||
|
}
|
||||||
|
if (!empty($user['R'])) {
|
||||||
|
$fields['delivery_street'] = $user['R'];
|
||||||
|
}
|
||||||
|
if (!empty($user['S'])) {
|
||||||
|
$fields['delivery_city'] = $user['S'];
|
||||||
|
}
|
||||||
|
if (!empty($user['T'])) {
|
||||||
|
$fields['delivery_zip'] = $user['T'];
|
||||||
|
}
|
||||||
|
if (!empty($user['U'])) {
|
||||||
|
$fields['delivery_state'] = $user['U'];
|
||||||
|
}
|
||||||
|
if (!empty($user['V'])) {
|
||||||
|
$fields['delivery_country'] = $user['V'];
|
||||||
|
}
|
||||||
|
$price_level = null;
|
||||||
|
if (!empty($user['W'])) { // cenová hladina
|
||||||
|
$price_level = array_search(trim($user['W']), $price_levels);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($try)) {
|
||||||
|
$confirmed = false;
|
||||||
|
if (getVal('newsletter_confirm')) {
|
||||||
|
$confirmed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$user['id'] = addUserEmail($user['D'], $groups, $fields, $confirmed);
|
||||||
|
if ($price_level) {
|
||||||
|
sqlQuery("REPLACE INTO users_dealer_price_level (id_user, id_price_level)
|
||||||
|
VALUES ('{$user['id']}', '{$price_level}')");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$fields['email'] = $user['D'];
|
||||||
|
$fields['groups'] = $groups;
|
||||||
|
$fields['price_level'] = ($price_level ? $price_level.' - '.$user['W'] : '');
|
||||||
|
$this->added_users[] = $fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
++$added;
|
||||||
|
} else {
|
||||||
|
$errs[$index] = "Nevalidní email {$user['D']}";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$errs[$index] = 'Prázdný email - uživatel nemůže být přidán';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$info['test'] = !empty($try) ? 1 : 2;
|
||||||
|
$info['added'] = $added;
|
||||||
|
$this->info = $info;
|
||||||
|
$this->errs = $errs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
28
admin/board/board.usersUnsubscribe.php
Normal file
28
admin/board/board.usersUnsubscribe.php
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$main_class = 'usersUnsubscribe';
|
||||||
|
|
||||||
|
class usersUnsubscribe extends Frame
|
||||||
|
{
|
||||||
|
use DatabaseCommunication;
|
||||||
|
|
||||||
|
protected $template = 'board/usersUnsubscribe.tpl';
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$emails = getVal('emails');
|
||||||
|
|
||||||
|
$emails = array_filter(preg_split('/[\s;,]/i', mb_strtolower($emails)));
|
||||||
|
|
||||||
|
if ($emails) {
|
||||||
|
$count = sqlQueryBuilder()->update('users')
|
||||||
|
->set('get_news', '"N"')
|
||||||
|
->set('date_updated', 'NOW()')
|
||||||
|
->set('date_unsubscribe', 'NOW()')
|
||||||
|
->where(Query\Operator::inStringArray($emails, 'email'))
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
$this->returnOK("Odhlášeno {$count} uživatelů");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
47
admin/checktimeout.php
Normal file
47
admin/checktimeout.php
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||||
|
|
||||||
|
class Checktimeout extends Window
|
||||||
|
{
|
||||||
|
public function get_vars()
|
||||||
|
{
|
||||||
|
$vars = parent::get_vars();
|
||||||
|
|
||||||
|
$pageVars = getVal('body', $vars);
|
||||||
|
|
||||||
|
if (getVal('frame')) {
|
||||||
|
$this->setTemplate('window/checktimeoutFrame.tpl');
|
||||||
|
} else {
|
||||||
|
$this->setTemplate('window/checktimeoutWindow.tpl');
|
||||||
|
}
|
||||||
|
|
||||||
|
$session = ServiceContainer::getService('session');
|
||||||
|
|
||||||
|
$pageVars['expiry'] = $session->get('_expiry');
|
||||||
|
$pageVars['time'] = time();
|
||||||
|
|
||||||
|
$vars['body'] = $pageVars;
|
||||||
|
|
||||||
|
return $vars;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasRights($name = null)
|
||||||
|
{
|
||||||
|
switch ($name) {
|
||||||
|
case Window::RIGHT_SAVE:
|
||||||
|
case Window::RIGHT_DELETE:
|
||||||
|
case Window::RIGHT_DUPLICATE:
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
return parent::hasRights($name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$checktimeout = new Checktimeout();
|
||||||
|
$checktimeout->run();
|
||||||
135
admin/class/Export/ExportData.php
Normal file
135
admin/class/Export/ExportData.php
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Export;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ExportData is the base class for exporters to specific file formats. See other
|
||||||
|
* classes below.
|
||||||
|
*
|
||||||
|
* php-export-data by Eli Dickinson, http://github.com/elidickinson/php-export-data
|
||||||
|
*/
|
||||||
|
abstract class ExportData
|
||||||
|
{
|
||||||
|
protected $exportTo; // Set in constructor to one of 'browser', 'file', 'string'
|
||||||
|
protected $stringData; // stringData so far, used if export string mode
|
||||||
|
protected $tempFile; // handle to temp file (for export file mode)
|
||||||
|
protected $tempFilename; // temp file name and path (for export file mode)
|
||||||
|
public $filename; // file mode: the output file name; browser mode: file name for download; string mode: not used
|
||||||
|
protected $encoding;
|
||||||
|
|
||||||
|
public function __construct($exportTo = 'browser', $filename = 'exportdata')
|
||||||
|
{
|
||||||
|
if (!in_array($exportTo, ['browser', 'file', 'string'])) {
|
||||||
|
throw new Exception("{$exportTo} is not a valid ExportData export type");
|
||||||
|
}
|
||||||
|
$this->exportTo = $exportTo;
|
||||||
|
$this->filename = $filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function initialize()
|
||||||
|
{
|
||||||
|
global $cfg;
|
||||||
|
switch ($this->exportTo) {
|
||||||
|
case 'browser':
|
||||||
|
$this->sendHttpHeaders();
|
||||||
|
break;
|
||||||
|
case 'string':
|
||||||
|
$this->stringData = '';
|
||||||
|
break;
|
||||||
|
case 'file':
|
||||||
|
$this->tempFilename = tempnam($cfg['Path']['data'], 'exportdata');
|
||||||
|
$this->tempFile = fopen($this->tempFilename, 'w');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->write($this->generateHeader());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addRow($row)
|
||||||
|
{
|
||||||
|
$this->write($this->generateRow($row));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function loadOrdersData($order_ids)
|
||||||
|
{
|
||||||
|
foreach ($order_ids as $id) {
|
||||||
|
$this->addRow($this->getOrder($id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function finalize()
|
||||||
|
{
|
||||||
|
$this->write($this->generateFooter());
|
||||||
|
|
||||||
|
switch ($this->exportTo) {
|
||||||
|
case 'browser':
|
||||||
|
flush();
|
||||||
|
break;
|
||||||
|
case 'string':
|
||||||
|
// do nothing
|
||||||
|
break;
|
||||||
|
case 'file':
|
||||||
|
// close temp file and move it to correct location
|
||||||
|
fclose($this->tempFile);
|
||||||
|
rename($this->tempFilename, $this->filename);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getString()
|
||||||
|
{
|
||||||
|
return $this->stringData;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract public function sendHttpHeaders();
|
||||||
|
|
||||||
|
protected function write($data)
|
||||||
|
{
|
||||||
|
if (!empty($data)) {
|
||||||
|
switch ($this->exportTo) {
|
||||||
|
case 'browser':
|
||||||
|
echo $data;
|
||||||
|
break;
|
||||||
|
case 'string':
|
||||||
|
$this->stringData .= $data;
|
||||||
|
break;
|
||||||
|
case 'file':
|
||||||
|
fwrite($this->tempFile, $data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function generateHeader()
|
||||||
|
{
|
||||||
|
// can be overridden by subclass to return any data that goes at the top of the exported file
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function generateFooter()
|
||||||
|
{
|
||||||
|
// can be overridden by subclass to return any data that goes at the bottom of the exported file
|
||||||
|
}
|
||||||
|
|
||||||
|
// In subclasses generateRow will take $row array and return string of it formatted for export type
|
||||||
|
abstract protected function generateRow($row);
|
||||||
|
|
||||||
|
protected function getOrder($id)
|
||||||
|
{
|
||||||
|
$order = new \Order();
|
||||||
|
|
||||||
|
$order->createFromDB($id);
|
||||||
|
$order->fetchItems();
|
||||||
|
|
||||||
|
return $order;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setCoding($encoding)
|
||||||
|
{
|
||||||
|
$this->encoding = $encoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function encodeData($string)
|
||||||
|
{
|
||||||
|
return iconv('utf-8', $this->encoding.'//TRANSLIT', $string);
|
||||||
|
}
|
||||||
|
}
|
||||||
26
admin/class/Export/ExportDataCSV.php
Normal file
26
admin/class/Export/ExportDataCSV.php
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Export;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ExportDataCSV - Exports to CSV (comma separated value) format.
|
||||||
|
*/
|
||||||
|
class ExportDataCSV extends ExportData
|
||||||
|
{
|
||||||
|
public function generateRow($row)
|
||||||
|
{
|
||||||
|
foreach ($row as $key => $value) {
|
||||||
|
// Escape inner quotes and wrap all contents in new quotes.
|
||||||
|
// Note that we are using \" to escape double quote not ""
|
||||||
|
$row[$key] = '"'.str_replace('"', '\"', $value).'"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode(',', $row)."\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sendHttpHeaders()
|
||||||
|
{
|
||||||
|
header('Content-type: text/csv');
|
||||||
|
header('Content-Disposition: attachment; filename='.basename($this->filename));
|
||||||
|
}
|
||||||
|
}
|
||||||
156
admin/class/Export/ExportDataDBF.php
Normal file
156
admin/class/Export/ExportDataDBF.php
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Export;
|
||||||
|
|
||||||
|
use XBase\Record;
|
||||||
|
use XBase\WritableTable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Own class for DBF export.
|
||||||
|
*/
|
||||||
|
class ExportDataDBF extends ExportData
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var WritableTable
|
||||||
|
*/
|
||||||
|
private $table;
|
||||||
|
|
||||||
|
public function initialize()
|
||||||
|
{
|
||||||
|
global $cfg;
|
||||||
|
|
||||||
|
$this->tempFilename = $cfg['Path']['data'].'export_data.dbf';
|
||||||
|
|
||||||
|
$this->table = WritableTable::create($this->tempFilename, $this->columnDefs(), $this->tempFilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function finalize()
|
||||||
|
{
|
||||||
|
$this->sendHttpHeaders();
|
||||||
|
$this->table->close();
|
||||||
|
|
||||||
|
readfile($this->tempFilename);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $order \Order
|
||||||
|
*/
|
||||||
|
public function generateRow($order)
|
||||||
|
{
|
||||||
|
$row_pointer = $this->table->appendRecord();
|
||||||
|
|
||||||
|
$this->appendToRow($row_pointer, $order);
|
||||||
|
|
||||||
|
$this->table->writeRecord();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sendHttpHeaders()
|
||||||
|
{
|
||||||
|
header('Content-Type: application/x-dbase; charset='.$this->encoding);
|
||||||
|
header('Content-Disposition: attachment; filename="'.$this->filename.'"');
|
||||||
|
header('Expires: 0');
|
||||||
|
header('Pragma: no-cache');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function columnDefs()
|
||||||
|
{
|
||||||
|
/* FIXME: dodělat zbytek a přesměrovat DBF z export_sracka sem */
|
||||||
|
return [
|
||||||
|
['DATUM_VYST', Record::DBFFIELD_TYPE_DATE], // datum vystavení
|
||||||
|
// ['DATUM_SPL', DBFFIELD_TYPE_DATE], //prázdné
|
||||||
|
// ['DOKLAD_1', DBFFIELD_TYPE_CHAR, 12], //aby tam bylo fčíslo objednávky např. f11521
|
||||||
|
// ['TYP_ZAP', DBFFIELD_TYPE_CHAR, 1], //hodnota P
|
||||||
|
// ['ZNAK_UCT', DBFFIELD_TYPE_CHAR, 5], //prázdné
|
||||||
|
// ['SYMBOLY', DBFFIELD_TYPE_CHAR, 20], //včísloobjednávky např. v11521
|
||||||
|
// ['PAR_ZNAK', DBFFIELD_TYPE_CHAR, 12], //to samé jako DOKLAD_1 např. f11521
|
||||||
|
// ['BANK_UCET', DBFFIELD_TYPE_CHAR, 44], //prázdné
|
||||||
|
// ['SPEC_SYMB', DBFFIELD_TYPE_CHAR, 10], //prázdné
|
||||||
|
// ['POPIS_TEXT', DBFFIELD_TYPE_CHAR, 30], //libovolný text - např. prodej eshop-objednávka 11521
|
||||||
|
// ['DRUH_UCT', DBFFIELD_TYPE_CHAR, 5], //hodnota PZ
|
||||||
|
// ['MENA', DBFFIELD_TYPE_CHAR, 3], //buď Kč nebo EUR
|
||||||
|
// ['CELKEM_KC', DBFFIELD_TYPE_NUMERIC, 8, 2], //celková částka dokladu včetně DPH v Kč
|
||||||
|
// ['CELKEMCIZI', DBFFIELD_TYPE_NUMERIC, 8, 2], //celková částka dokladu v EUR - prodej na Slovensko?
|
||||||
|
// ['KURZ', DBFFIELD_TYPE_NUMERIC, 5, 3], //kurz pro přepočet
|
||||||
|
// ['DATUM_DPH', DBFFIELD_TYPE_DATE], //datum DPH = datum vystavení
|
||||||
|
// ['TYP_DPH', DBFFIELD_TYPE_CHAR, 5], //hodnota U
|
||||||
|
// ['ZAKL_DPH_Z', DBFFIELD_TYPE_NUMERIC, 8, 2], //Částka bez daně v základní sazbě
|
||||||
|
// ['DPH_Z', DBFFIELD_TYPE_NUMERIC, 8, 2], //Daň s azba 21 %
|
||||||
|
// ['ZAKL_DPH_S', DBFFIELD_TYPE_NUMERIC, 8, 2], //Částka bez daně ve snížené sazbě
|
||||||
|
// ['DPH_S', DBFFIELD_TYPE_NUMERIC, 8, 2], //Daň s azba 15 %
|
||||||
|
// ['TYPMIMODPH', DBFFIELD_TYPE_CHAR, 1], //prázdné
|
||||||
|
// ['CASTKAMIMO', DBFFIELD_TYPE_NUMERIC, 8, 2], //prázdné
|
||||||
|
// ['STREDISKO', DBFFIELD_TYPE_CHAR, 5], //PRÁZDNÉ
|
||||||
|
// ['vykon', DBFFIELD_TYPE_CHAR, 5], //prázdné
|
||||||
|
// ['zakazka', DBFFIELD_TYPE_CHAR, 5], //prázdné
|
||||||
|
// ['POZNAMKA', DBFFIELD_TYPE_CHAR, 150], //sem naimportovat jméno a příjmění a město kupujícího JAN NOVAK TURNOV
|
||||||
|
// ['FIRMA', DBFFIELD_TYPE_CHAR, 30], // Firma
|
||||||
|
// ['JMENO', DBFFIELD_TYPE_CHAR, 30], //Jmeno
|
||||||
|
// ['PRIJMENI', DBFFIELD_TYPE_CHAR, 30], //Prijmeni
|
||||||
|
// ['ICO', DBFFIELD_TYPE_CHAR, 15], //ICO
|
||||||
|
// ['DIC', DBFFIELD_TYPE_CHAR, 20], //DIC
|
||||||
|
//
|
||||||
|
// ['ZAKAZNIK', DBFFIELD_TYPE_CHAR, 80], //Prijmeni nebo firma
|
||||||
|
// ['ULICE', DBFFIELD_TYPE_CHAR, 50], //Adresa
|
||||||
|
// ['MESTO', DBFFIELD_TYPE_CHAR, 30], //Adresa
|
||||||
|
// ['PSC', DBFFIELD_TYPE_CHAR, 10], //Adresa
|
||||||
|
// ['ZEME', DBFFIELD_TYPE_CHAR, 30], //Adresa
|
||||||
|
//
|
||||||
|
// ['STAV', DBFFIELD_TYPE_CHAR, 10], // STORNO/PRODEJ
|
||||||
|
// ['DATUM_SPLAT', DBFFIELD_TYPE_DATE], //datum splatnosti
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $row_pointer Record
|
||||||
|
* @param $order \Order
|
||||||
|
*/
|
||||||
|
protected function appendToRow($row_pointer, $order)
|
||||||
|
{
|
||||||
|
/* FIXME: dodělat zbytek a přesměrovat DBF z export_sracka sem */
|
||||||
|
if ($order->date_handle) {
|
||||||
|
$row_pointer->setObjectByName('DATUM_VYST', $order->date_handle->format('Ymd')); // datum vystavení
|
||||||
|
}
|
||||||
|
// $r->setObjectByName("DATUM_SPL", $row['DBFFIELD_TYPE_DATE']); //prázdné
|
||||||
|
// $row_pointer->setObjectByName('DOKLAD_1', $order['order_no']); //aby tam bylo fčíslo objednávky např. f11521
|
||||||
|
// $row_pointer->setObjectByName('TYP_ZAP', 'P'); //hodnota P
|
||||||
|
// $row_pointer->setObjectByName('ZNAK_UCT', ''); //prázdné
|
||||||
|
// $row_pointer->setObjectByName('SYMBOLY', $order['id']); //včísloobjednávky např. v11521
|
||||||
|
// $row_pointer->setObjectByName('PAR_ZNAK', $order['order_no']); //to samé jako DOKLAD_1 např. f11521
|
||||||
|
// $row_pointer->setObjectByName('BANK_UCET', ''); //prázdné
|
||||||
|
// $row_pointer->setObjectByName('SPEC_SYMB', ''); //prázdné
|
||||||
|
// $row_pointer->setObjectByName('POPIS_TEXT', $encode('Objednávka: ').$order['id']); //libovolný text - např. prodej eshop-objednávka 11521
|
||||||
|
// $row_pointer->setObjectByName('DRUH_UCT', 'PZ'); //hodnota PZ
|
||||||
|
// $row_pointer->setObjectByName('MENA', $encode('Kč')); //buď Kč nebo EUR
|
||||||
|
// $row_pointer->setObjectByName('CELKEM_KC', $total_price); //celková částka dokladu včetně DPH v Kč
|
||||||
|
// $row_pointer->setObjectByName('CELKEMCIZI', 0); //celková částka dokladu v EUR - prodej na Slovensko?
|
||||||
|
// $row_pointer->setObjectByName('KURZ', 0); //kurz pro přepočet
|
||||||
|
// $row_pointer->setObjectByName('DATUM_DPH', strtotime($order['date_handle'])); //datum DPH = datum vystavení
|
||||||
|
// $row_pointer->setObjectByName('TYP_DPH', 'U'); //hodnota U
|
||||||
|
// $row_pointer->setObjectByName('ZAKL_DPH_Z', $taxes['21']); //Částka bez daně v základní sazbě
|
||||||
|
// $row_pointer->setObjectByName('DPH_Z', $taxes['21']->mul(toDecimal(0.21))); //Daň sazba 21 %
|
||||||
|
// $row_pointer->setObjectByName('ZAKL_DPH_S', $taxes['15']); //Částka bez daně ve snížené sazbě
|
||||||
|
// $row_pointer->setObjectByName('DPH_S', $taxes['15']->mul(toDecimal(0.15))); //Částka bez daně ve snížené sazbě
|
||||||
|
// $row_pointer->setObjectByName('TYPMIMODPH', ''); //prázdné
|
||||||
|
// $row_pointer->setObjectByName('CASTKAMIMO', $taxes['0']); //prázdné
|
||||||
|
// $row_pointer->setObjectByName('STREDISKO', ''); //PRÁZDNÉ
|
||||||
|
// $row_pointer->setObjectByName('vykon', ''); //prázdné
|
||||||
|
// $row_pointer->setObjectByName('zakazka', ''); //prázdné
|
||||||
|
// $row_pointer->setObjectByName('POZNAMKA', "{$order['invoice_name']} {$order['invoice_surname']}, {$order['invoice_city']}"); //sem naimportovat jméno a příjmění a město kupujícího JAN NOVAK TURNOV
|
||||||
|
// $row_pointer->setObjectByName('FIRMA', $order['invoice_firm']); // Firma
|
||||||
|
// $row_pointer->setObjectByName('JMENO', $order['invoice_name']); //Jmeno
|
||||||
|
// $row_pointer->setObjectByName('PRIJMENI', $order['invoice_surname']); //Prijmeni
|
||||||
|
//
|
||||||
|
// $row_pointer->setObjectByName('ICO', $order['invoice_ico']); //ICO
|
||||||
|
// $row_pointer->setObjectByName('DIC', $order['invoice_dic']); //DIC
|
||||||
|
//
|
||||||
|
// $row_pointer->setObjectByName('ZAKAZNIK', $order['invoice_firm'] ? $order['invoice_firm'] : "{$order['invoice_name']} {$order['invoice_surname']}"); //Prijmeni nebo firma
|
||||||
|
// $row_pointer->setObjectByName('ULICE', $order['invoice_street']);
|
||||||
|
// $row_pointer->setObjectByName('MESTO', $order['invoice_city']);
|
||||||
|
// $row_pointer->setObjectByName('PSC', $order['invoice_zip']);
|
||||||
|
// $row_pointer->setObjectByName('ZEME', $order['invoice_country']);
|
||||||
|
//
|
||||||
|
// $row_pointer->setObjectByName('STAV', $order['status_storno'] ? 'STORNO' : 'PRODEJ'); // STORNO/PRODEJ
|
||||||
|
// $row_pointer->setObjectByName('DATUM_SPLAT', strtotime($order['date_due']));
|
||||||
|
}
|
||||||
|
}
|
||||||
125
admin/class/Export/ExportDataDBFUcto.php
Normal file
125
admin/class/Export/ExportDataDBFUcto.php
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Export;
|
||||||
|
|
||||||
|
use XBase\Record;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Own class for DBF export.
|
||||||
|
*/
|
||||||
|
class ExportDataDBFUcto extends ExportDataDBF
|
||||||
|
{
|
||||||
|
protected function columnDefs()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
['Veta', Record::DBFFIELD_TYPE_NUMERIC, 6, 0], // datum vystavení
|
||||||
|
['DatumVyst', Record::DBFFIELD_TYPE_DATE], // datum vystavení
|
||||||
|
['DatumSpl', Record::DBFFIELD_TYPE_DATE], // datum splatnosti
|
||||||
|
['Datum', Record::DBFFIELD_TYPE_DATE], // datum zaplacení - většinou prázdné
|
||||||
|
|
||||||
|
['Doklad', Record::DBFFIELD_TYPE_CHAR, 30], // Doklad
|
||||||
|
['DokladKH', Record::DBFFIELD_TYPE_CHAR, 20],
|
||||||
|
['TypD', Record::DBFFIELD_TYPE_CHAR, 3],
|
||||||
|
['Text', Record::DBFFIELD_TYPE_CHAR, 30], // text
|
||||||
|
['Druh', Record::DBFFIELD_TYPE_CHAR, 3], // klic do ciselniku druhu
|
||||||
|
['Firma', Record::DBFFIELD_TYPE_CHAR, 5], // cislo firmy v adresari ucta
|
||||||
|
['Ico', Record::DBFFIELD_TYPE_CHAR, 10], // ico firmy
|
||||||
|
['Vykon', Record::DBFFIELD_TYPE_CHAR, 5], // klic do ciselniku vykonu
|
||||||
|
|
||||||
|
['Plat', Record::DBFFIELD_TYPE_CHAR, 1], // platba: B-banka, H-hotovos
|
||||||
|
['Celkem', Record::DBFFIELD_TYPE_FLOATING, 11, 2], // celkova castka
|
||||||
|
|
||||||
|
['DatumDPH', Record::DBFFIELD_TYPE_DATE], // datum zd. pl
|
||||||
|
['DatumKH', Record::DBFFIELD_TYPE_DATE],
|
||||||
|
|
||||||
|
['BezDaneZ', Record::DBFFIELD_TYPE_FLOATING, 11, 2], // dph
|
||||||
|
['DphZ', Record::DBFFIELD_TYPE_FLOATING, 11, 2], // dph
|
||||||
|
['BezDaneS', Record::DBFFIELD_TYPE_FLOATING, 11, 2], // dph
|
||||||
|
['DphS', Record::DBFFIELD_TYPE_FLOATING, 11, 2], // dph
|
||||||
|
['BezDaneS2', Record::DBFFIELD_TYPE_FLOATING, 11, 2], // dph
|
||||||
|
['DphS2', Record::DBFFIELD_TYPE_FLOATING, 11, 2], // dph
|
||||||
|
['BezDaneO', Record::DBFFIELD_TYPE_FLOATING, 11, 2], // dph
|
||||||
|
['Zaloha', Record::DBFFIELD_TYPE_FLOATING, 11, 2], // dph
|
||||||
|
|
||||||
|
['Prikaz', Record::DBFFIELD_TYPE_LOGICAL], // nevyplnovat, vyber pro prikaz k uhrade
|
||||||
|
['DatumPrik', Record::DBFFIELD_TYPE_DATE], // nevyplnovat, datum pro prikaz k uhrade
|
||||||
|
|
||||||
|
['Pozn', Record::DBFFIELD_TYPE_MEMO], // poznámka (memo)
|
||||||
|
['Ozn', Record::DBFFIELD_TYPE_LOGICAL], // označené věty
|
||||||
|
|
||||||
|
['Měna2', Record::DBFFIELD_TYPE_CHAR, 3], // Měna2
|
||||||
|
['Kč2', Record::DBFFIELD_TYPE_FLOATING, 11, 2], // Kč2
|
||||||
|
|
||||||
|
['Naz0', Record::DBFFIELD_TYPE_CHAR, 30], // označené věty
|
||||||
|
['Dic0', Record::DBFFIELD_TYPE_CHAR, 14], // označené věty
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $row_pointer Record
|
||||||
|
* @param $order \Order
|
||||||
|
*/
|
||||||
|
protected function appendToRow($row_pointer, $order)
|
||||||
|
{
|
||||||
|
// $row_pointer->setObjectByName('Veta', '');
|
||||||
|
$row_pointer->setObjectByName('DatumVyst', $order->date_handle ? strtotime($order->date_handle->format('Ymd')) : '');
|
||||||
|
// $row_pointer->setObjectByName('DatumPrik', '');
|
||||||
|
|
||||||
|
/* TODO: dořešit due_days, nejlíp na order */
|
||||||
|
$row_pointer->setObjectByName('DatumSpl', ($order->date_handle) ? strtotime($order->date_handle->modify('+14 days')->format('Ymd')) : '');
|
||||||
|
// $row_pointer->setObjectByName('Datum', '');
|
||||||
|
$row_pointer->setObjectByName('Doklad', 'f/'.$order->order_no);
|
||||||
|
$row_pointer->setObjectByName('DokladKH', $order->order_no);
|
||||||
|
$row_pointer->setObjectByName('TypD', ' ');
|
||||||
|
$row_pointer->setObjectByName('Text', $this->encodeData($order->invoice_firm ? $order->invoice_firm : $order->invoice_name.' '.$order->invoice_surname));
|
||||||
|
$row_pointer->setObjectByName('Druh', 'PZ ');
|
||||||
|
$row_pointer->setObjectByName('Firma', ' ');
|
||||||
|
$row_pointer->setObjectByName('Ico', strtoupper($order->invoice_ico));
|
||||||
|
$row_pointer->setObjectByName('Vykon', ' ');
|
||||||
|
|
||||||
|
$pay_type = $order->getDeliveryType()->getPayment();
|
||||||
|
|
||||||
|
if ($pay_type && $pay_type->getPayMethod() == \Payment::METHOD_CASH) {
|
||||||
|
$pay_type = 'H';
|
||||||
|
} else {
|
||||||
|
$pay_type = 'B';
|
||||||
|
}
|
||||||
|
|
||||||
|
$row_pointer->setObjectByName('Plat', $this->encodeData($pay_type));
|
||||||
|
$row_pointer->setObjectByName('Celkem', !$order->status_storno ? $order->total_price->printFloatValue(2) : 0);
|
||||||
|
|
||||||
|
/* TODO: datum zd. plneni */
|
||||||
|
$row_pointer->setObjectByName('DatumDPH', $order->date_handle ? strtotime($order->date_handle->format('Ymd')) : '');
|
||||||
|
// $row_pointer->setObjectByName('DatumKH', '');
|
||||||
|
|
||||||
|
if (!empty($order->vats[21]) && !$order->status_storno) {
|
||||||
|
$row_pointer->setObjectByName('BezDaneZ', $order->vats[21]['total_price_without_vat']->printFloatValue(2));
|
||||||
|
$row_pointer->setObjectByName('DphZ', $order->vats[21]['tax']['value_vat']->printFloatValue(2));
|
||||||
|
} else {
|
||||||
|
$row_pointer->setObjectByName('BezDaneZ', 0);
|
||||||
|
$row_pointer->setObjectByName('DphZ', 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (!empty($order->vats[15])) {
|
||||||
|
// $row_pointer->setObjectByName('BezDaneS', $order->vats[15]['total_price_without_vat']->printFloatValue(2));
|
||||||
|
// $row_pointer->setObjectByName('DphS', $order->vats[15]['tax']['value_vat']->printFloatValue(2));
|
||||||
|
// } else {
|
||||||
|
// $row_pointer->setObjectByName('BezDaneS', 0);
|
||||||
|
// $row_pointer->setObjectByName('DphS', 0);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// $row_pointer->setObjectByName('BezDaneS2', 0);
|
||||||
|
// $row_pointer->setObjectByName('DphS2', 0);
|
||||||
|
// $row_pointer->setObjectByName('BezDaneO', 0);
|
||||||
|
// $row_pointer->setObjectByName('Zaloha', 0);
|
||||||
|
|
||||||
|
$row_pointer->setObjectByName('Prikaz', false);
|
||||||
|
// $row_pointer->setObjectByName('DatumPrik', 0);
|
||||||
|
// $row_pointer->setObjectByName('Pozn', '');
|
||||||
|
$row_pointer->setObjectByName('Ozn', false);
|
||||||
|
$row_pointer->setObjectByName('Měna2', ' ');
|
||||||
|
// $row_pointer->setObjectByName('Kč2', $order->currency_rate);
|
||||||
|
$row_pointer->setObjectByName('Naz0', ' ');
|
||||||
|
$row_pointer->setObjectByName('Dic0', strtoupper($order->invoice_dic));
|
||||||
|
}
|
||||||
|
}
|
||||||
110
admin/class/Export/ExportDataExcel.php
Normal file
110
admin/class/Export/ExportDataExcel.php
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Export;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ExportDataExcel exports data into an XML format (spreadsheetML) that can be
|
||||||
|
* read by MS Excel 2003 and newer as well as OpenOffice.
|
||||||
|
*
|
||||||
|
* Creates a workbook with a single worksheet (title specified by
|
||||||
|
* $title).
|
||||||
|
*
|
||||||
|
* Note that using .XML is the "correct" file extension for these files, but it
|
||||||
|
* generally isn't associated with Excel. Using .XLS is tempting, but Excel 2007 will
|
||||||
|
* throw a scary warning that the extension doesn't match the file type.
|
||||||
|
*
|
||||||
|
* Based on Excel XML code from Excel_XML (http://github.com/oliverschwarz/php-excel)
|
||||||
|
* by Oliver Schwarz
|
||||||
|
*/
|
||||||
|
class ExportDataExcel extends ExportData
|
||||||
|
{
|
||||||
|
public const XmlHeader = "<?xml version=\"1.0\" encoding=\"%s\"?\>\n<Workbook xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\" xmlns:x=\"urn:schemas-microsoft-com:office:excel\" xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\" xmlns:html=\"http://www.w3.org/TR/REC-html40\">";
|
||||||
|
public const XmlFooter = '</Workbook>';
|
||||||
|
|
||||||
|
public $encoding = 'UTF-8'; // encoding type to specify in file.
|
||||||
|
// Note that you're on your own for making sure your data is actually encoded to this encoding
|
||||||
|
public $title = 'Sheet1'; // title for Worksheet
|
||||||
|
|
||||||
|
public function generateHeader()
|
||||||
|
{
|
||||||
|
// workbook header
|
||||||
|
$output = stripslashes(sprintf(self::XmlHeader, $this->encoding))."\n";
|
||||||
|
|
||||||
|
// Set up styles
|
||||||
|
$output .= "<Styles>\n";
|
||||||
|
$output .= "<Style ss:ID=\"sDT\"><NumberFormat ss:Format=\"Short Date\"/></Style>\n";
|
||||||
|
$output .= "</Styles>\n";
|
||||||
|
|
||||||
|
// worksheet header
|
||||||
|
$output .= sprintf("<Worksheet ss:Name=\"%s\">\n <Table>\n", htmlentities($this->title));
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function generateFooter()
|
||||||
|
{
|
||||||
|
$output = '';
|
||||||
|
|
||||||
|
// worksheet footer
|
||||||
|
$output .= " </Table>\n</Worksheet>\n";
|
||||||
|
|
||||||
|
// workbook footer
|
||||||
|
$output .= self::XmlFooter;
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function generateRow($row)
|
||||||
|
{
|
||||||
|
$output = '';
|
||||||
|
$output .= " <Row>\n";
|
||||||
|
foreach ($row as $k => $v) {
|
||||||
|
$output .= $this->generateCell($v);
|
||||||
|
}
|
||||||
|
$output .= " </Row>\n";
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function generateCell($item)
|
||||||
|
{
|
||||||
|
$output = '';
|
||||||
|
$style = '';
|
||||||
|
|
||||||
|
// Tell Excel to treat as a number. Note that Excel only stores roughly 15 digits, so keep
|
||||||
|
// as text if number is longer than that.
|
||||||
|
if (preg_match("/^-?\d+(?:[.,]\d+)?$/", $item) && (strlen($item) < 15)) {
|
||||||
|
$type = 'Number';
|
||||||
|
}
|
||||||
|
// Sniff for valid dates; should look something like 2010-07-14 or 7/14/2010 etc. Can
|
||||||
|
// also have an optional time after the date.
|
||||||
|
//
|
||||||
|
// Note we want to be very strict in what we consider a date. There is the possibility
|
||||||
|
// of really screwing up the data if we try to reformat a string that was not actually
|
||||||
|
// intended to represent a date.
|
||||||
|
elseif (preg_match("/^(\d{1,2}|\d{4})[\/\-]\d{1,2}[\/\-](\d{1,2}|\d{4})([^\d].+)?$/", $item)
|
||||||
|
&& ($timestamp = strtotime($item))
|
||||||
|
&& ($timestamp > 0)
|
||||||
|
&& ($timestamp < strtotime('+500 years'))) {
|
||||||
|
$type = 'DateTime';
|
||||||
|
$item = strftime('%Y-%m-%dT%H:%M:%S', $timestamp);
|
||||||
|
$style = 'sDT'; // defined in header; tells excel to format date for display
|
||||||
|
} else {
|
||||||
|
$type = 'String';
|
||||||
|
}
|
||||||
|
|
||||||
|
$item = str_replace(''', ''', htmlspecialchars($item, ENT_QUOTES));
|
||||||
|
$output .= ' ';
|
||||||
|
$output .= $style ? "<Cell ss:StyleID=\"{$style}\">" : '<Cell>';
|
||||||
|
$output .= sprintf('<Data ss:Type="%s">%s</Data>', $type, $item);
|
||||||
|
$output .= "</Cell>\n";
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sendHttpHeaders()
|
||||||
|
{
|
||||||
|
header('Content-Type: application/vnd.ms-excel; charset='.$this->encoding);
|
||||||
|
header('Content-Disposition: inline; filename="'.basename($this->filename).'"');
|
||||||
|
}
|
||||||
|
}
|
||||||
26
admin/class/Export/ExportDataTSV.php
Normal file
26
admin/class/Export/ExportDataTSV.php
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Export;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ExportDataTSV - Exports to TSV (tab separated value) format.
|
||||||
|
*/
|
||||||
|
class ExportDataTSV extends ExportData
|
||||||
|
{
|
||||||
|
public function generateRow($row)
|
||||||
|
{
|
||||||
|
foreach ($row as $key => $value) {
|
||||||
|
// Escape inner quotes and wrap all contents in new quotes.
|
||||||
|
// Note that we are using \" to escape double quote not ""
|
||||||
|
$row[$key] = '"'.str_replace('"', '\"', $value).'"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode("\t", $row)."\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sendHttpHeaders()
|
||||||
|
{
|
||||||
|
header('Content-type: text/tab-separated-values');
|
||||||
|
header('Content-Disposition: attachment; filename='.basename($this->filename));
|
||||||
|
}
|
||||||
|
}
|
||||||
412
admin/class/class.AdminBarMenu.php
Normal file
412
admin/class/class.AdminBarMenu.php
Normal file
@@ -0,0 +1,412 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use KupShop\AdminBundle\AdminRegister\AdminRegisterLocator;
|
||||||
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||||
|
|
||||||
|
class AdminBarMenu
|
||||||
|
{
|
||||||
|
protected $customMenuItems = [];
|
||||||
|
|
||||||
|
protected $menu = [
|
||||||
|
[
|
||||||
|
'name' => 'administration',
|
||||||
|
'submenu' => [
|
||||||
|
[
|
||||||
|
'name' => 'leadpage',
|
||||||
|
'left' => 'blank', 'right' => 's=board.php',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'shopStore',
|
||||||
|
'left' => 's=menu.php&type=shopStore', 'right' => 's=board.php&type=shopStore',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'newWindow',
|
||||||
|
'script' => 'newWindow();',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'logout',
|
||||||
|
'script' => 'logout(0)',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'adminEdit',
|
||||||
|
'script' => "nw('adminEdit')",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'htmlComponents',
|
||||||
|
/* 'left' => 's=menu.php&type=htmlComponents', */ 'right' => 's=board.php&type=htmlComponents',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'chooseLanguage',
|
||||||
|
'submenu' => [
|
||||||
|
[
|
||||||
|
'name' => 'czech',
|
||||||
|
'href' => 'admin-change-language/czech',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'english',
|
||||||
|
'href' => 'admin-change-language/english',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'productsMenu',
|
||||||
|
'left' => 's=menu.php&type=products', 'right' => 's=list.php&type=products',
|
||||||
|
'submenu' => [
|
||||||
|
[
|
||||||
|
'name' => 'products',
|
||||||
|
'left' => 's=menu.php&type=products', 'right' => 's=list.php&type=products',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'productsMassModification',
|
||||||
|
'left' => 'blank', 'right' => 's=list.php&type=productsMassModification',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'parameters',
|
||||||
|
'left' => 's=menu.php&type=parameters', 'right' => 's=list.php&type=parameters',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'productsVarLabels',
|
||||||
|
'left' => 's=menu.php&type=productsVarLabels', 'right' => 's=list.php&type=productsVarLabels',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'sections',
|
||||||
|
'left' => 's=menu.php&type=sections', 'right' => 's=list.php&type=sections',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'producers',
|
||||||
|
'left' => 's=menu.php&type=producers', 'right' => 's=list.php&type=producers',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'templatesMenu',
|
||||||
|
'submenu' => [
|
||||||
|
[
|
||||||
|
'name' => 'templates',
|
||||||
|
'left' => 's=menu.php&type=templates', 'right' => 's=list.php&type=templates',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'templatesCategories',
|
||||||
|
'left' => 's=menu.php&type=templatesCategories', 'right' => 's=list.php&type=templatesCategories',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'reviews',
|
||||||
|
'left' => 's=menu.php&type=reviews', 'right' => 's=list.php&type=reviews&type_list=ShowNotConfirmed',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'productsRelatedTypes',
|
||||||
|
'left' => 's=menu.php&type=productsRelatedTypes', 'right' => 's=list.php&type=productsRelatedTypes',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'ordersMenu',
|
||||||
|
'left' => 's=menu.php&type=orders', 'right' => 's=list.php&type=orders',
|
||||||
|
'submenu' => [
|
||||||
|
[
|
||||||
|
'name' => 'orders',
|
||||||
|
'left' => 's=menu.php&type=orders', 'right' => 's=list.php&type=orders',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'users',
|
||||||
|
'left' => 's=menu.php&type=users', 'right' => 's=list.php&type=users',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'usersGroups',
|
||||||
|
'left' => 's=menu.php&type=usersGroups', 'right' => 's=list.php&type=usersGroups',
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
'name' => 'ordersMassProcess',
|
||||||
|
'left' => 's=menu.php&type=ordersMassProcess', 'right' => 's=list.php&type=ordersMassProcess',
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
'name' => 'old_pos',
|
||||||
|
'script' => "nw('old_pos')",
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
'name' => 'orderPayment',
|
||||||
|
'left' => 's=menu.php&type=orderPayment', 'right' => null,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'stockMenu',
|
||||||
|
'submenu' => [
|
||||||
|
[
|
||||||
|
'name' => 'stockIn',
|
||||||
|
'left' => 's=menu.php&type=stockIn', 'right' => 's=list.php&type=stockIn',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'suppliers',
|
||||||
|
'left' => 's=menu.php&type=suppliers', 'right' => 's=list.php&type=suppliers',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'stockInMissing',
|
||||||
|
'left' => 's=menu.php&type=stockInMissing', 'right' => 's=list.php&type=stockInMissing&fromNav=1',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'productsOfSuppliers',
|
||||||
|
'left' => 's=menu.php&type=productsOfSuppliers', 'right' => 's=list.php&type=productsOfSuppliers',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'ordersOfSuppliers',
|
||||||
|
'left' => 's=menu.php&type=ordersOfSuppliers', 'right' => 's=list.php&type=ordersOfSuppliers',
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
'name' => 'inventory',
|
||||||
|
'left' => 's=menu.php&type=inventory', 'right' => 's=list.php&type=inventory',
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
'name' => 'productsPrices',
|
||||||
|
'left' => 's=menu.php&type=productsPrices', 'right' => 's=list.php&type=productsPrices',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'contentMenu',
|
||||||
|
'submenu' => [
|
||||||
|
[
|
||||||
|
'name' => 'menu',
|
||||||
|
'left' => 's=menu.php&type=menu', 'right' => 's=list.php&type=menu',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'sliders',
|
||||||
|
'left' => 's=menu.php&type=sliders', 'right' => 's=list.php&type=sliders',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'articlesMenu',
|
||||||
|
'submenu' => [
|
||||||
|
[
|
||||||
|
'name' => 'articles',
|
||||||
|
'left' => 's=menu.php&type=articles', 'right' => 's=list.php&type=articles',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'artsections',
|
||||||
|
'left' => 's=menu.php&type=artsections', 'right' => 's=list.php&type=artsections',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'artauthors',
|
||||||
|
'left' => 's=menu.php&type=artauthors', 'right' => 's=list.php&type=artauthors',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'articlesTags',
|
||||||
|
'left' => 's=menu.php&type=articlesTags', 'right' => 's=list.php&type=articlesTags',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'sellers',
|
||||||
|
'left' => 's=menu.php&type=sellers', 'right' => 's=list.php&type=sellers',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'photos',
|
||||||
|
'left' => 's=menu.php&type=photos', 'right' => 's=list.php&type=photos',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'fileBrowser',
|
||||||
|
'script' => 'nw(\'kcfinder\', \'all\')',
|
||||||
|
],
|
||||||
|
/*[
|
||||||
|
'name' => 'fileBrowser',
|
||||||
|
'submenu' => [
|
||||||
|
[
|
||||||
|
'name' => 'browseImages',
|
||||||
|
'script' => 'nw(\'kcfinder\')',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'browseFiles',
|
||||||
|
'script' => 'nw(\'kcfinder\', \'other\')',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],*/
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'toolsMenu',
|
||||||
|
'submenu' => [
|
||||||
|
[
|
||||||
|
'name' => 'dbbackup',
|
||||||
|
'left' => 's=menu.php&type=dbbackup', 'right' => 's=list.php&type=dbbackup',
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
'name' => 'stats',
|
||||||
|
'left' => 'blank', 'right' => 's=board.php&type=stats',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'export',
|
||||||
|
'submenu' => [
|
||||||
|
[
|
||||||
|
'name' => 'export_products',
|
||||||
|
'left' => 's=menu.php&type=export', 'right' => 's=board.php&type=export_products',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'export_selling_products',
|
||||||
|
'left' => 's=menu.php&type=export', 'right' => 's=board.php&type=export_selling_products',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'export_orders',
|
||||||
|
'left' => 's=menu.php&type=export', 'right' => 's=board.php&type=export_orders',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'export_users',
|
||||||
|
'left' => 's=menu.php&type=export', 'right' => 's=board.php&type=export_users',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'import',
|
||||||
|
'submenu' => [
|
||||||
|
[
|
||||||
|
'name' => 'import-generic',
|
||||||
|
'right' => 's=import.generic.php',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'import_automatic',
|
||||||
|
'left' => 's=menu.php&type=automatic_import', 'right' => 's=list.php&type=automatic_import',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'import-xml_feed',
|
||||||
|
'script' => "nw('import.xml_feed')",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'import-xml_feed_new',
|
||||||
|
'script' => "nw('import.xml_feed_new')",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'cleaning',
|
||||||
|
'script' => "nw('cleaning')",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'settingsMenu',
|
||||||
|
'submenu' => [
|
||||||
|
[
|
||||||
|
'name' => 'admins',
|
||||||
|
'left' => 's=menu.php&type=admins', 'right' => 's=list.php&type=admins',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'settings',
|
||||||
|
'script' => "nw('settings')",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'emails',
|
||||||
|
'script' => "nw('emails')",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'delivery',
|
||||||
|
'submenu' => [
|
||||||
|
[
|
||||||
|
'name' => 'delivery_type',
|
||||||
|
'left' => 's=menu.php&type=delivery', 'right' => 's=list.php&type=delivery',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'deliveryDelivery',
|
||||||
|
'left' => 's=menu.php&type=deliveryDelivery', 'right' => 's=list.php&type=deliveryDelivery',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'deliveryPayment',
|
||||||
|
'left' => 's=menu.php&type=deliveryPayment', 'right' => 's=list.php&type=deliveryPayment',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'vats',
|
||||||
|
'left' => 's=menu.php&type=vats', 'right' => 's=list.php&type=vats',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'priceLevels',
|
||||||
|
'left' => 's=menu.php&type=pricelevels', 'right' => 's=list.php&type=pricelevels',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'fulltext',
|
||||||
|
'script' => "nw('fulltext')",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
public function getMenu(): array
|
||||||
|
{
|
||||||
|
$userRights = new UserRights();
|
||||||
|
/** @var \Symfony\Component\EventDispatcher\EventDispatcher $dispatcher */
|
||||||
|
$dispatcher = ServiceContainer::getService('event_dispatcher');
|
||||||
|
$event = new \KupShop\KupShopBundle\Event\CreateMenuEvent($this, $userRights);
|
||||||
|
$dispatcher->dispatch($event, \KupShop\KupShopBundle\Event\CreateMenuEvent::COMPLETING_TREE);
|
||||||
|
$adminRegisterLocator = ServiceContainer::getService(AdminRegisterLocator::class);
|
||||||
|
foreach ($adminRegisterLocator->getMenu() as $menu => $items) {
|
||||||
|
foreach ($items as $item) {
|
||||||
|
$this->addItem($menu, $item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->sortMenu($this->menu);
|
||||||
|
|
||||||
|
return $this->menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function sortMenu(&$menu)
|
||||||
|
{
|
||||||
|
foreach ($menu as $pos => &$item) {
|
||||||
|
if (is_array($item) && array_key_exists('submenu', $item)) {
|
||||||
|
$this->sortMenu($item['submenu']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($item) && array_key_exists('position', $item)) {
|
||||||
|
$menuItem = [$menu[$pos]];
|
||||||
|
unset($menu[$pos]);
|
||||||
|
array_splice($menu, $item['position'], 0, $menuItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addItem($menuName, $item, &$menu = null, $index = 0)
|
||||||
|
{
|
||||||
|
if (!$menu) {
|
||||||
|
$menu = &$this->menu;
|
||||||
|
}
|
||||||
|
// / new
|
||||||
|
$menuNames = $this->getMenuNames($menuName);
|
||||||
|
$maxIndex = count($menuNames) - 1;
|
||||||
|
foreach ($menu as &$menuItem) {
|
||||||
|
if ($menuItem['name'] == $menuNames[$index]) {
|
||||||
|
if ($index == $maxIndex) {
|
||||||
|
$menuItem['submenu'][] = $item;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
$result = $this->addItem($menuName, $item, $menuItem['submenu'], ++$index);
|
||||||
|
if ($result) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// create root menu item if $menuItem was not found
|
||||||
|
$menu[] = $item;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMenuNames($menuName)
|
||||||
|
{
|
||||||
|
$names = explode('/', $menuName);
|
||||||
|
|
||||||
|
return $names;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setMenu(array $menu)
|
||||||
|
{
|
||||||
|
$this->menu = $menu;
|
||||||
|
}
|
||||||
|
}
|
||||||
31
admin/class/class.AdminListSortable.php
Normal file
31
admin/class/class.AdminListSortable.php
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
trait AdminListSortable
|
||||||
|
{
|
||||||
|
public function saveList($item, $table, $columns = 'position', $extra_where = '', $id_column = 'id')
|
||||||
|
{
|
||||||
|
if ($item['direction'] == 'down') {
|
||||||
|
$item['position']++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($columns)) {
|
||||||
|
$column = reset($columns);
|
||||||
|
} else {
|
||||||
|
$column = $columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
$columns = join(', ', (array) $columns);
|
||||||
|
|
||||||
|
sqlQuery("UPDATE {$table} SET {$column}={$column}+1 WHERE {$column} >= {$item['position']}{$extra_where}");
|
||||||
|
|
||||||
|
sqlQuery("UPDATE {$table} SET {$column}={$item['position']} WHERE {$id_column}={$item['id']}{$extra_where}");
|
||||||
|
|
||||||
|
$this->saveAllPositions($column, $columns, $extra_where, $table);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function saveAllPositions($column, $columns, mixed $extraWhere, ?string $table = null): void
|
||||||
|
{
|
||||||
|
$table ??= $this->tableName;
|
||||||
|
sqlQuery("SELECT @i := -1; UPDATE {$table} SET {$column} = (select @i := @i + 1) WHERE 1{$extraWhere} ORDER BY {$columns}");
|
||||||
|
}
|
||||||
|
}
|
||||||
95
admin/class/class.Base.php
Normal file
95
admin/class/class.Base.php
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by PhpStorm.
|
||||||
|
* User: hanz
|
||||||
|
* Date: 29.4.14
|
||||||
|
* Time: 14:49s.
|
||||||
|
*/
|
||||||
|
class Base
|
||||||
|
{
|
||||||
|
protected $smarty;
|
||||||
|
protected $template;
|
||||||
|
|
||||||
|
public function init_smarty()
|
||||||
|
{
|
||||||
|
$this->smarty = createSmarty(true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTemplate()
|
||||||
|
{
|
||||||
|
if (empty($this->template)) {
|
||||||
|
throw new Exception('Empty template name');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->template;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setTemplate($name)
|
||||||
|
{
|
||||||
|
$this->template = $name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getClassName()
|
||||||
|
{
|
||||||
|
$className = explode('\\', get_called_class());
|
||||||
|
|
||||||
|
return end($className);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function display()
|
||||||
|
{
|
||||||
|
$this->smarty->display($this->getTemplate());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$acn = getVal('acn');
|
||||||
|
if ($acn) {
|
||||||
|
$action = 'handle'.ucfirst($acn);
|
||||||
|
if (method_exists($this, $action)) {
|
||||||
|
call_user_func([$this, $action]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
// Process POSTEd values
|
||||||
|
$this->handle();
|
||||||
|
|
||||||
|
// Collect template variables
|
||||||
|
$vars = $this->collectVariables();
|
||||||
|
|
||||||
|
// Init templating system
|
||||||
|
$this->init_smarty();
|
||||||
|
|
||||||
|
// Assign template variables to template
|
||||||
|
$this->assign_($vars);
|
||||||
|
|
||||||
|
// Render template
|
||||||
|
$this->display();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function collectVariables()
|
||||||
|
{
|
||||||
|
return $this->get_vars();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function get_vars()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'view' => $this,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPageHandler()
|
||||||
|
{
|
||||||
|
return getVal('s');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function assign_($array)
|
||||||
|
{
|
||||||
|
$this->smarty->assign($array);
|
||||||
|
}
|
||||||
|
}
|
||||||
271
admin/class/class.BaseAdminPhotos.php
Normal file
271
admin/class/class.BaseAdminPhotos.php
Normal file
@@ -0,0 +1,271 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class BaseAdminPhotos extends Frame
|
||||||
|
{
|
||||||
|
use DatabaseCommunication;
|
||||||
|
|
||||||
|
protected $template = 'adminPhotos.tpl';
|
||||||
|
protected $relation_table_name;
|
||||||
|
protected $photo_type;
|
||||||
|
protected $tablefield;
|
||||||
|
protected $photo_nametype;
|
||||||
|
protected $photo_admin_name;
|
||||||
|
protected $copy_from;
|
||||||
|
|
||||||
|
public function get_vars()
|
||||||
|
{
|
||||||
|
$vars = parent::get_vars();
|
||||||
|
|
||||||
|
$pageVars = getVal('body', $vars, []);
|
||||||
|
|
||||||
|
$acn = $this->getAction();
|
||||||
|
$ID = $this->getID();
|
||||||
|
$pageVars['acn'] = $acn;
|
||||||
|
$pageVars['s'] = getVal('s');
|
||||||
|
|
||||||
|
$SQL = sqlQuery("SELECT ph.id, ph.descr,ph.source, ph.image_2, MAX(php.show_in_lead) as show_in_lead, ph.date,
|
||||||
|
MAX(php.position) as position, ph.data as data, ph.date_update
|
||||||
|
FROM photos AS ph, {$this->relation_table_name} AS php
|
||||||
|
WHERE ph.id=php.id_photo AND php.{$this->tablefield}=:id
|
||||||
|
GROUP BY ph.id
|
||||||
|
ORDER BY position ASC", ['id' => $ID]); // , php.date_added ASC;
|
||||||
|
|
||||||
|
$photos = [];
|
||||||
|
foreach ($SQL as $row) {
|
||||||
|
$row['IDph'] = $row['id'];
|
||||||
|
$row['img'] = getImage($row['id'], $row['image_2'], $row['source'], $this->photo_type, $row['descr'], strtotime($row['date_update']));
|
||||||
|
$row['width'] = ($row['img']['width'] <= 200) ? $row['img']['width'] : 200;
|
||||||
|
$this->unserializeCustomData($row);
|
||||||
|
if (findModule('products_variations_photos') && $this->relation_table_name == 'photos_products_relation') {
|
||||||
|
$row['varSel'] = [];
|
||||||
|
$SQLp = sqlQuery("SELECT id_variation FROM {$this->relation_table_name} pp WHERE pp.id_photo=:id_photo AND pp.{$this->tablefield}=:ID AND pp.id_variation IS NOT NULL", ['id_photo' => $row['IDph'], 'ID' => $ID]);
|
||||||
|
foreach ($SQLp as $rowp) {
|
||||||
|
$row['varSel'][] = $rowp['id_variation'];
|
||||||
|
}
|
||||||
|
if (empty($row['varSel'])) {
|
||||||
|
$row['varSel'] = ['-1'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$photos[] = $row;
|
||||||
|
}
|
||||||
|
$pageVars['photos'] = $photos;
|
||||||
|
|
||||||
|
if (findModule('products_variations_photos') && $this->relation_table_name == 'photos_products_relation') {
|
||||||
|
$variations = ['-1' => 'Žádná přiřazená varianta'];
|
||||||
|
if (findModule('products_variations_photos')) {
|
||||||
|
$SQLv = sqlQuery("SELECT id, title
|
||||||
|
FROM products_variations pv
|
||||||
|
WHERE pv.{$this->tablefield}=:ID", ['ID' => $ID]);
|
||||||
|
while (($row = sqlFetchAssoc($SQLv)) !== false) {
|
||||||
|
$variations[$row['id']] = $row['title'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$pageVars['variations'] = $variations;
|
||||||
|
}
|
||||||
|
$pageVars['ID'] = $ID;
|
||||||
|
$pageVars['tablefield'] = $this->tablefield;
|
||||||
|
$pageVars['copy_from'] = $this->copy_from;
|
||||||
|
$pageVars['photo_nametype'] = $this->photo_nametype;
|
||||||
|
$pageVars['search_field'] = $this->search_field;
|
||||||
|
|
||||||
|
$vars['body'] = $pageVars;
|
||||||
|
|
||||||
|
return $vars;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
global $cfg;
|
||||||
|
parent::handle();
|
||||||
|
$ID = $this->getID();
|
||||||
|
if (getVal('data') && $ID) {
|
||||||
|
if (findModule('products_variations_photos') && $this->relation_table_name == 'photos_products_relation') {
|
||||||
|
$photoVariations = getVal('id_variation', null, []);
|
||||||
|
|
||||||
|
foreach ($photoVariations as $IDph => $variations) {
|
||||||
|
sqlQuery("DELETE FROM {$this->relation_table_name} WHERE id_photo=:IDph AND {$this->tablefield} = :ID", ['ID' => $ID, 'IDph' => $IDph]);
|
||||||
|
|
||||||
|
foreach ($variations as $variation) {
|
||||||
|
$insert = [
|
||||||
|
'id_photo' => $IDph,
|
||||||
|
$this->tablefield => $ID,
|
||||||
|
'date_added' => 'NOW()',
|
||||||
|
];
|
||||||
|
|
||||||
|
if ($variation > 0) {
|
||||||
|
$insert['id_variation'] = $variation;
|
||||||
|
} else { // maze to duplicity z databaze
|
||||||
|
sqlQuery("DELETE FROM {$this->relation_table_name} WHERE id_photo=:IDph AND {$this->tablefield} = :ID", ['ID' => $ID, 'IDph' => $IDph]);
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlQueryBuilder()->insert($this->relation_table_name)
|
||||||
|
->directValues($insert)->onDuplicateKeyUpdate([])->execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = getVal('data', null, []);
|
||||||
|
$pos = 0;
|
||||||
|
foreach ($data as $id => $photo) {
|
||||||
|
if (!empty($photo['delete']) || !$id) {
|
||||||
|
if ($id > 0) {
|
||||||
|
$this->handleDeleteRelationPhoto($id);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$values = ['position' => $pos++];
|
||||||
|
if (isset($cfg['Photo']['kind']) && $this->tablefield == 'id_product') {
|
||||||
|
$values['show_in_lead'] = $photo['show_in_lead'];
|
||||||
|
}
|
||||||
|
$this->serializeCustomData($photo);
|
||||||
|
$this->updateSQL('photos', $photo, ['id' => $id], ['position', 'show_in_lead']);
|
||||||
|
$this->updateSQL($this->relation_table_name, $values, [$this->tablefield => $ID, 'id_photo' => $id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Photos::checkLeadPhoto($this->relation_table_name, $this->tablefield, $ID);
|
||||||
|
|
||||||
|
$this->returnOK('Uloženo');
|
||||||
|
}
|
||||||
|
if (!empty($_FILES)) {
|
||||||
|
global $cfg;
|
||||||
|
|
||||||
|
sqlGetConnection()->transactional(function () use ($ID) {
|
||||||
|
$img = new Photos($this->photo_admin_name ?: lcfirst($this->photo_nametype));
|
||||||
|
$img->newImage();
|
||||||
|
|
||||||
|
// uploadovat velky obrazek
|
||||||
|
$img->uploadPhotoOrVideo($_FILES['qqfile'], ($_REQUEST['qqfilename'] ?? false) ? $_REQUEST['qqfilename'] : '');
|
||||||
|
|
||||||
|
// ID nove fotky
|
||||||
|
$IDph = $img->getID();
|
||||||
|
|
||||||
|
if ($this->photo_nametype == 'Product') {
|
||||||
|
$img->{"insert{$this->photo_nametype}Relation"}($IDph, $ID, 'N', 'Y');
|
||||||
|
} else {
|
||||||
|
$img->insertRelation($this->relation_table_name, $IDph, $this->tablefield, $ID, 'N');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
header('Content-type: text/plain');
|
||||||
|
exit('{"success":true}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleDeleteRelationPhoto($IDph)
|
||||||
|
{
|
||||||
|
$IDpr = $this->getID();
|
||||||
|
|
||||||
|
sqlQuery("DELETE FROM {$this->relation_table_name} WHERE id_photo='{$IDph}' AND {$this->tablefield}=:IDpr", ['IDpr' => $IDpr]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleDeletePhoto()
|
||||||
|
{
|
||||||
|
$IDph = getVal('IDph');
|
||||||
|
|
||||||
|
sqlQuery('DELETE FROM photos WHERE id=:IDph', ['IDph' => $IDph]);
|
||||||
|
|
||||||
|
$this->returnOK();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleInsertPhoto()
|
||||||
|
{
|
||||||
|
$errors = [];
|
||||||
|
$data = getVal('data');
|
||||||
|
$id_photos = explode(',', $data['id_photo']);
|
||||||
|
$count = sqlQueryBuilder()->select('COUNT(*)')
|
||||||
|
->from($this->relation_table_name)
|
||||||
|
->where(\Query\Operator::equals([$this->tablefield => $this->getID()]))
|
||||||
|
->execute()
|
||||||
|
->fetchColumn();
|
||||||
|
foreach ($id_photos as $id_photo) {
|
||||||
|
$data = [
|
||||||
|
$this->tablefield => $this->getID(),
|
||||||
|
'id_photo' => $id_photo,
|
||||||
|
'date_added' => date('Y-m-d H:i:s'),
|
||||||
|
];
|
||||||
|
|
||||||
|
if (empty($data['id_photo'])) {
|
||||||
|
$this->returnError('Nevybrána žádna fotografie!');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sqlQueryBuilder()->select('COUNT(*)')
|
||||||
|
->from($this->relation_table_name)
|
||||||
|
->where(\Query\Operator::equals(['id_photo' => $id_photo, $this->tablefield => $data[$this->tablefield]]))
|
||||||
|
->execute()
|
||||||
|
->fetchColumn()) {
|
||||||
|
$errors[] = "Fotografie s ID {$data['id_photo']} je již přiřazena!";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
$this->insertSQL($this->relation_table_name, $data);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
switch (intval($e->getPrevious()->errorInfo[1])) {
|
||||||
|
case 1062:
|
||||||
|
$errors[] = "Fotografie s ID {$data['id_photo']} je již přiřazena!";
|
||||||
|
// no break
|
||||||
|
default:
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->updateSQL(
|
||||||
|
$this->relation_table_name,
|
||||||
|
['position' => $count, 'show_in_lead' => $count == 0 ? 'Y' : 'N'],
|
||||||
|
[$this->tablefield => $data[$this->tablefield], 'id_photo' => $data['id_photo']]
|
||||||
|
);
|
||||||
|
$count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($errors) {
|
||||||
|
$this->returnError(join(' ', $errors));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->returnOK();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleCopyPhotos()
|
||||||
|
{
|
||||||
|
$data = getVal('data');
|
||||||
|
$data['ID'] = $this->getID();
|
||||||
|
|
||||||
|
$data['count'] = returnSQLResult("SELECT COUNT(*) FROM {$this->relation_table_name} WHERE {$this->tablefield}=:field", ['field' => $this->getID()]);
|
||||||
|
|
||||||
|
sqlQuery("REPLACE INTO {$this->relation_table_name}
|
||||||
|
(id_photo, {$this->tablefield}, date_added, show_in_lead, position)
|
||||||
|
SELECT id_photo, :ID, NOW(), 'N', position+:count
|
||||||
|
FROM {$this->relation_table_name}
|
||||||
|
WHERE {$this->tablefield}=:{$this->tablefield}", $data);
|
||||||
|
|
||||||
|
Photos::checkLeadPhoto($this->relation_table_name, $this->tablefield, $this->getID());
|
||||||
|
|
||||||
|
$this->returnOK('Obrázky byly zkopírovány');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleMovePhoto()
|
||||||
|
{
|
||||||
|
$item = getVal('moved_item');
|
||||||
|
|
||||||
|
if (!empty($item)) {
|
||||||
|
Photos::checkLeadPhoto($this->relation_table_name, $this->tablefield, $item[$this->tablefield]);
|
||||||
|
|
||||||
|
sqlQuery("UPDATE {$this->relation_table_name} SET position=position+1000 WHERE position >= :position AND {$this->tablefield}=:id", ['id' => $item[$this->tablefield], 'position' => $item['position']]);
|
||||||
|
|
||||||
|
sqlQuery("UPDATE {$this->relation_table_name} SET position=:position WHERE id_photo=:id_photo AND {$this->tablefield}=:id", ['id' => $item[$this->tablefield], 'position' => $item['position'], 'id_photo' => $item['id_photo']]);
|
||||||
|
|
||||||
|
Photos::checkLeadPhoto($this->relation_table_name, $this->tablefield, $item[$this->tablefield]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function checkPhotos($table, $id_field, $id_photo)
|
||||||
|
{
|
||||||
|
$sql = sqlQuery("SELECT {$id_field} FROM {$table} WHERE id_photo=:idph", ['idph' => $id_photo]);
|
||||||
|
$array = sqlFetchAll($sql, [$id_field => $id_field]);
|
||||||
|
sqlQuery("DELETE FROM {$table} WHERE id_photo=:idph", ['idph' => $id_photo]);
|
||||||
|
|
||||||
|
foreach ($array as $ID) {
|
||||||
|
Photos::checkLeadPhoto($table, $id_field, $ID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
51
admin/class/class.BaseAdminSectionsRelations.php
Normal file
51
admin/class/class.BaseAdminSectionsRelations.php
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use KupShop\AdminBundle\Util\AdminSectionTree;
|
||||||
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||||
|
|
||||||
|
class BaseAdminSectionsRelations extends \Frame
|
||||||
|
{
|
||||||
|
protected $template = 'sectionsRelations.tpl';
|
||||||
|
|
||||||
|
protected AdminSectionTree $adminSectionTree;
|
||||||
|
|
||||||
|
protected string $label;
|
||||||
|
protected string $tableName;
|
||||||
|
protected string $column;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->adminSectionTree = ServiceContainer::getService(AdminSectionTree::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_vars()
|
||||||
|
{
|
||||||
|
$vars = parent::get_vars();
|
||||||
|
|
||||||
|
$pageVars['tree'] = $this->adminSectionTree->getCategories();
|
||||||
|
$pageVars['category0'] = $this->adminSectionTree->getCategory0();
|
||||||
|
$pageVars['selected'] = $this->adminSectionTree->getSelected($this->getID(), $this->tableName, $this->label, $this->column);
|
||||||
|
$this->adminSectionTree->getOpened($pageVars['tree']);
|
||||||
|
$pageVars['opened'] = $this->adminSectionTree->opened;
|
||||||
|
|
||||||
|
$vars['body'] = $pageVars;
|
||||||
|
$vars['body']['data']['id'] = $this->getID();
|
||||||
|
$vars['body']['ID'] = $this->getID();
|
||||||
|
|
||||||
|
return $vars;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
parent::handle();
|
||||||
|
|
||||||
|
if (getVal('isSubmitted')) {
|
||||||
|
$this->handleSubmit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function handleSubmit(): void
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('Not implemented!');
|
||||||
|
}
|
||||||
|
}
|
||||||
556
admin/class/class.ExportProducts.php
Normal file
556
admin/class/class.ExportProducts.php
Normal file
@@ -0,0 +1,556 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by PhpStorm.
|
||||||
|
* User: hanz
|
||||||
|
* Date: 9/2/15
|
||||||
|
* Time: 8:30 AM.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use KupShop\AdminBundle\Exception\ExportException;
|
||||||
|
use KupShop\AdminBundle\Util\ActivityLog;
|
||||||
|
use KupShop\CatalogBundle\Section\SectionTree;
|
||||||
|
use KupShop\CatalogBundle\Util\ProductsFilterSpecs;
|
||||||
|
use KupShop\KupShopBundle\Config;
|
||||||
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||||
|
use KupShop\KupShopBundle\Util\Excel\ExcelGenerator;
|
||||||
|
use KupShop\StoresBundle\Query\StoresQuery;
|
||||||
|
use KupShop\StoresBundle\Utils\StoresInStore;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Cell\DataType;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
|
||||||
|
use Query\Operator;
|
||||||
|
use Query\QueryBuilder;
|
||||||
|
|
||||||
|
class ExportProducts
|
||||||
|
{
|
||||||
|
use \KupShop\AdminBundle\Util\CategoryTree;
|
||||||
|
|
||||||
|
public function getFile()
|
||||||
|
{
|
||||||
|
while (ob_get_level()) {
|
||||||
|
ob_end_clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
increaseMemoryLimit(1024);
|
||||||
|
ini_set('max_execution_time', '600');
|
||||||
|
|
||||||
|
$filename = 'Products-'.date('Y-m-d_H-i').'.xlsx';
|
||||||
|
try {
|
||||||
|
$this->checkItemsCount();
|
||||||
|
$generator = new ExcelGenerator();
|
||||||
|
$this->defineHeader();
|
||||||
|
$generator->generateExcel($this->getHeader(), $this->getData(), $filename);
|
||||||
|
} catch (ExportException $e) {
|
||||||
|
redirect('launch.php?s=board.php&type=export_products&ErrStr='.urlencode($e->getMessage()));
|
||||||
|
} catch (Exception $exception) {
|
||||||
|
$sentry = getRaven();
|
||||||
|
$sentry->captureException($exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
addActivityLog(
|
||||||
|
ActivityLog::SEVERITY_NOTICE,
|
||||||
|
ActivityLog::TYPE_COMMUNICATION,
|
||||||
|
sprintf('Export produktů: %s', $filename)
|
||||||
|
);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected $fields = 'p.id,p.campaign, p.title, p.guarantee, pr.name as producer, p.short_descr, p.long_descr,
|
||||||
|
ps.id_section, v.vat, p.discount, p.show_in_feed, p.max_cpc, p.parameters, p.delivery_time, p.pieces_sold,
|
||||||
|
p.meta_title, p.meta_description, p.meta_keywords, GROUP_CONCAT(DISTINCT pa.link) AS attachments, p.date_added,
|
||||||
|
p.figure, pv.figure figure_variation,
|
||||||
|
COALESCE(pv.width, p.width) as width,
|
||||||
|
COALESCE(pv.height, p.height) as height,
|
||||||
|
COALESCE(pv.depth, p.depth) as depth';
|
||||||
|
|
||||||
|
protected $column_names = [
|
||||||
|
'code' => ['name' => 'Kód'],
|
||||||
|
'title' => ['name' => 'Název'],
|
||||||
|
'campaign' => ['name' => 'kampaně'],
|
||||||
|
'producer' => ['name' => 'Výrobce'],
|
||||||
|
'supplier_code' => ['name' => 'Kód dodavatele'],
|
||||||
|
'section' => ['name' => 'Sekce'],
|
||||||
|
'short_descr' => ['name' => 'Anotace'],
|
||||||
|
'long_descr' => ['name' => 'Popis'],
|
||||||
|
'parameters' => ['name' => 'Parametry'],
|
||||||
|
'photo' => ['name' => 'Fotografie'],
|
||||||
|
'vat' => ['name' => 'Sazba DPH', 'type' => DataType::TYPE_NUMERIC],
|
||||||
|
'price_without_vat' => ['name' => 'cena bez DPH [Kč]', 'type' => DataType::TYPE_NUMERIC, 'format' => '0.00'],
|
||||||
|
'price_with_vat' => ['name' => 'cena s DPH [Kč]', 'type' => DataType::TYPE_NUMERIC, 'format' => '0.00'],
|
||||||
|
'discount' => ['name' => 'sleva [%]', 'type' => DataType::TYPE_NUMERIC],
|
||||||
|
'price_for_discount' => ['name' => 'cena pro slevu', 'type' => DataType::TYPE_NUMERIC],
|
||||||
|
'discount_price_without_vat' => ['name' => 'cena po slevě bez DPH [Kč]', 'type' => DataType::TYPE_NUMERIC],
|
||||||
|
'discount_price_with_vat' => ['name' => 'cena po slevě s DPH [Kč]', 'type' => DataType::TYPE_NUMERIC],
|
||||||
|
'in_store' => ['name' => 'skladem [ks]', 'type' => DataType::TYPE_NUMERIC],
|
||||||
|
'in_store_min' => ['name' => 'Minimálně skladem [ks]', 'type' => DataType::TYPE_NUMERIC],
|
||||||
|
'delivery_time' => ['name' => 'Dostupnost', 'type' => DataType::TYPE_NUMERIC],
|
||||||
|
'guarantee' => ['name' => 'záruka [měs.]', 'type' => DataType::TYPE_NUMERIC],
|
||||||
|
'show_in_feed' => ['name' => 'Zobrazovat ve srovnávačích'],
|
||||||
|
'max_cpc' => ['name' => 'cena za proklik [Kč]', 'type' => DataType::TYPE_NUMERIC, 'format' => '0.00'],
|
||||||
|
'ean' => ['name' => 'Kód EAN'],
|
||||||
|
'pieces_sold' => ['name' => 'Počet prodaných kusů', 'type' => DataType::TYPE_NUMERIC, 'format' => '0'],
|
||||||
|
'id' => ['name' => 'ID produktu', 'type' => DataType::TYPE_NUMERIC],
|
||||||
|
'meta_title' => ['name' => 'SEO Titulek'],
|
||||||
|
'meta_description' => ['name' => 'SEO Popis'],
|
||||||
|
'attachments' => ['name' => 'Přílohy'],
|
||||||
|
'weight' => ['name' => 'Hmotnost', 'type' => DataType::TYPE_NUMERIC],
|
||||||
|
'width' => ['name' => 'Šířka', 'type' => DataType::TYPE_NUMERIC],
|
||||||
|
'height' => ['name' => 'Výška', 'type' => DataType::TYPE_NUMERIC],
|
||||||
|
'depth' => ['name' => 'Hloubka', 'type' => DataType::TYPE_NUMERIC],
|
||||||
|
'date_added' => ['name' => 'Datum vytvoření', 'type' => DataType::TYPE_ISO_DATE, 'format' => NumberFormat::FORMAT_DATE_DDMMYYYY],
|
||||||
|
'figure' => ['name' => 'Viditelné - produkt'],
|
||||||
|
'figure_variation' => ['name' => 'Viditelné - varianta'],
|
||||||
|
];
|
||||||
|
|
||||||
|
public function addFields($fields)
|
||||||
|
{
|
||||||
|
$this->fields = $this->fields.$fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFields()
|
||||||
|
{
|
||||||
|
return $this->column_names;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHeader($array = null)
|
||||||
|
{
|
||||||
|
if (!$array) {
|
||||||
|
$array = $this->getFields();
|
||||||
|
}
|
||||||
|
|
||||||
|
$fields = [];
|
||||||
|
|
||||||
|
foreach ($array as $key => $field) {
|
||||||
|
if (array_key_exists('sub', $field)) {
|
||||||
|
foreach ($field['sub'] as $subkey => $subfield) {
|
||||||
|
$fields[$subkey] = $subfield;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$fields[$key] = $field;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function checkItemsCount()
|
||||||
|
{
|
||||||
|
$data = $this->prepareQuery()->execute();
|
||||||
|
|
||||||
|
$items_count = $data->rowCount();
|
||||||
|
if ($items_count == 0) {
|
||||||
|
throw new ExportException('Export se nepodařil, protože zadanému filtru neodpovídá žádná položka');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function prepareQuery(): QueryBuilder
|
||||||
|
{
|
||||||
|
$qb = $this->getBaseQueryBuilder();
|
||||||
|
|
||||||
|
if (findModule(Modules::PRODUCTS, Modules::SUB_NOTE)) {
|
||||||
|
if (findModule(Modules::PRODUCTS_VARIATIONS)) {
|
||||||
|
$qb->addSelect('COALESCE(pv.note, p.note) as note');
|
||||||
|
} else {
|
||||||
|
$qb->addSelect('p.note');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (findModule('products', 'price_common')) {
|
||||||
|
$qb->addSelect('p.price_common');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (findModule(Modules::PRODUCTS, Modules::SUB_PRICE_BUY)) {
|
||||||
|
if (findModule('products_variations')) {
|
||||||
|
$qb->addSelect('COALESCE(pv.price_buy, p.price_buy) as price_buy');
|
||||||
|
} else {
|
||||||
|
$qb->addSelect('p.price_buy');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (findModule(Modules::PRODUCTS, Modules::SUB_WEIGHT)) {
|
||||||
|
if (findModule(Modules::PRODUCTS_VARIATIONS)) {
|
||||||
|
$qb->addSelect('COALESCE(pv.weight, p.weight) as weight');
|
||||||
|
} else {
|
||||||
|
$qb->addSelect('p.weight as weight');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$qb->joinVariationsOnProducts();
|
||||||
|
$qb->addSelect('COALESCE(pv.id, 0) as id_variation');
|
||||||
|
if (findModule('products_variations')) {
|
||||||
|
if (findModule('products_variations', 'variationCode')) {
|
||||||
|
$qb->addSelect('COALESCE(pv.code, p.code) as code');
|
||||||
|
} else {
|
||||||
|
$qb->addSelect('p.code as code');
|
||||||
|
}
|
||||||
|
|
||||||
|
$qb->addSelect('COALESCE(pv.ean, p.ean) as ean, COALESCE(pv.price, p.price) as price_without_vat,
|
||||||
|
COALESCE(pv.in_store, p.in_store) as in_store');
|
||||||
|
|
||||||
|
if (findModule(\Modules::MISSING_PRODUCTS)) {
|
||||||
|
$qb->addSelect('COALESCE(pv.in_store_min, p.in_store_min) as in_store_min');
|
||||||
|
}
|
||||||
|
|
||||||
|
$qb->addSelect("GROUP_CONCAT(DISTINCT CONCAT(pvc.id_label, ':', pvc.id_value) SEPARATOR ';') as `variation_combination`");
|
||||||
|
$qb->leftJoin('p', 'products_variations_combination', 'pvc', 'pv.id=pvc.id_variation');
|
||||||
|
|
||||||
|
$qb->addGroupBy('pv.id');
|
||||||
|
} else {
|
||||||
|
$qb->addSelect('p.code as code, p.ean as ean, p.price as price_without_vat, p.in_store as in_store');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (findModule('photos')) {
|
||||||
|
$qb->addSelect("(SELECT GROUP_CONCAT(CONCAT(ph.source, ph.image_2) SEPARATOR ';') FROM photos_products_relation as ppr
|
||||||
|
LEFT JOIN photos as ph ON ph.id=ppr.id_photo WHERE ppr.id_product=p.id ORDER BY ppr.position ASC ) as photos");
|
||||||
|
}
|
||||||
|
|
||||||
|
$filterSpecs = null;
|
||||||
|
$productsFilterSpecs = ServiceContainer::getService(ProductsFilterSpecs::class);
|
||||||
|
$filter = getval('filter');
|
||||||
|
if ($filter) {
|
||||||
|
$filterSpecs = $productsFilterSpecs->getSpecs($filter);
|
||||||
|
if ($filterSpecs) {
|
||||||
|
$qb->andWhere($filterSpecs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (findModule(Modules::SUPPLIERS)) {
|
||||||
|
if (findModule(Modules::PRODUCTS_VARIATIONS)) {
|
||||||
|
$qb->addSelect('pos.code as supplier_code')
|
||||||
|
->leftJoin('pv', 'products_of_suppliers', 'pos', 'p.id = pos.id_product AND pv.id <=> pos.id_variation');
|
||||||
|
} else {
|
||||||
|
$qb->addSelect('pos.code as supplier_code')
|
||||||
|
->leftJoin('p', 'products_of_suppliers', 'pos', 'p.id=pos.id_product');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (findModule(\Modules::PRICE_HISTORY)) {
|
||||||
|
$qb->addSelect('p.price_for_discount as price_for_discount');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $qb;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getProducts(): Generator
|
||||||
|
{
|
||||||
|
$qb = $this->prepareQuery();
|
||||||
|
|
||||||
|
$limit = 5000;
|
||||||
|
$from = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
$qb->setFirstResult($from);
|
||||||
|
$qb->setMaxResults($limit);
|
||||||
|
$batch = $qb->execute();
|
||||||
|
yield $batch;
|
||||||
|
$from = $from + $limit;
|
||||||
|
} while ($batch->rowCount() == $limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getBaseQueryBuilder(): Query\QueryBuilder
|
||||||
|
{
|
||||||
|
return sqlQueryBuilder()->select($this->fields)
|
||||||
|
->fromProducts()
|
||||||
|
->leftJoin('p', 'producers', 'pr', 'p.producer = pr.id')
|
||||||
|
->joinVatsOnProducts()
|
||||||
|
->leftJoin('p', 'products_in_sections', 'ps', 'p.id = ps.id_product')
|
||||||
|
->leftJoin('p', 'attachments', 'pa', 'pa.id_product = p.id')
|
||||||
|
->groupBy('p.id');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function defineHeader()
|
||||||
|
{
|
||||||
|
$parameters = [];
|
||||||
|
$variants = [];
|
||||||
|
$pricelists = [];
|
||||||
|
|
||||||
|
if (findModule(Modules::PRODUCTS, Modules::SUB_NOTE)) {
|
||||||
|
$this->column_names['note']['name'] = 'Poznámka';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (findModule('products', 'price_common')) {
|
||||||
|
$this->column_names['price_common'] = ['name' => 'Škrtlá cena [Kč]', 'type' => DataType::TYPE_NUMERIC];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (findModule(Modules::PRODUCTS, Modules::SUB_PRICE_BUY)) {
|
||||||
|
$this->column_names['price_buy'] = ['name' => 'Nákupní cena', 'type' => DataType::TYPE_NUMERIC];
|
||||||
|
}
|
||||||
|
if (findModule(Modules::STORES) && $this->isExportOptionEnabled('exportStoresInStore')) {
|
||||||
|
$this->column_names['in_store']['sub']['in_store'] = $this->column_names['in_store'];
|
||||||
|
foreach (ServiceContainer::getService(StoresInStore::class)->getStoresNames() as $key => $name) {
|
||||||
|
$this->column_names['in_store']['sub']['store'.$key.'_in_store'] = ['name' => 'sklad '.$name, 'type' => DataType::TYPE_NUMERIC];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$SQL = sqlQuery('SELECT pvc.id_label, pvcl.label, pvc.id_value, pvcv.value
|
||||||
|
FROM products_variations_combination AS pvc
|
||||||
|
LEFT JOIN products_variations_choices_labels AS pvcl ON pvc.id_label=pvcl.id
|
||||||
|
LEFT JOIN products_variations_choices_values AS pvcv ON pvc.id_label = pvcv.id_label AND pvc.id_value = pvcv.id
|
||||||
|
GROUP BY pvc.id_value');
|
||||||
|
foreach ($SQL as $row) {
|
||||||
|
$variants['var'.$row['id_label']][$row['id_value']] = $row['value'];
|
||||||
|
$this->column_names['variants']['sub']['var'.$row['id_label']]['name'] = 'Varianta: '.$row['label'];
|
||||||
|
}
|
||||||
|
if (findModule('products_parameters') && $this->isExportOptionEnabled('exportParameters')) {
|
||||||
|
$iterParams = sqlQuery('SELECT pp.id_parameter, pp.value_list, pp.value_char, pp.value_float, p.name, p.value_type
|
||||||
|
FROM parameters_products AS pp
|
||||||
|
LEFT JOIN parameters AS p ON p.id=pp.id_parameter
|
||||||
|
LEFT JOIN parameters_list AS pl ON pl.id=pp.value_list
|
||||||
|
GROUP BY pl.id, p.id
|
||||||
|
ORDER BY p.id');
|
||||||
|
foreach ($iterParams as $row) {
|
||||||
|
$this->column_names['prod_parameters']['sub']['par'.$row['id_parameter']]['name'] = 'Parametr: '.$row['name'];
|
||||||
|
$parameters['par'.$row['id_parameter']] = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!findModule(\Modules::PRICE_HISTORY)) {
|
||||||
|
unset($this->column_names['price_for_discount']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!findModule(\Modules::MISSING_PRODUCTS)) {
|
||||||
|
unset($this->column_names['in_store_min']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (findModule(Modules::PRICELISTS) && ($exportPricelists = $this->getExportOptions()['exportPricelists'] ?? null)) {
|
||||||
|
$exportPricelists = array_filter($exportPricelists);
|
||||||
|
if ($exportPricelists) {
|
||||||
|
$pricelists = sqlQueryBuilder()->select('CONCAT("pl", id), id, name, currency')->from('pricelists')
|
||||||
|
->where(Operator::inIntArray($exportPricelists, 'id'))
|
||||||
|
->execute()->fetchAllAssociativeIndexed();
|
||||||
|
foreach ($pricelists as $key => $row) {
|
||||||
|
$name = 'Ceník: '.$row['name'];
|
||||||
|
$this->column_names['prod_pricelists']['sub'][$key] = ['name' => $name.": cena bez DPH ({$row['currency']})", 'type' => DataType::TYPE_NUMERIC];
|
||||||
|
$this->column_names['prod_pricelists']['sub'][$key.'discount'] = ['name' => $name.': sleva (%)', 'type' => DataType::TYPE_NUMERIC];
|
||||||
|
if (findModule(\Modules::PRICE_HISTORY)) {
|
||||||
|
$this->column_names['prod_pricelists']['sub'][$key.'price_for_discount'] = ['name' => $name.": cena pro slevu ({$row['currency']})", 'type' => DataType::TYPE_NUMERIC];
|
||||||
|
}
|
||||||
|
$this->column_names['prod_pricelists']['sub'][$key.'final'] = ['name' => $name.": finální cena bez DPH ({$row['currency']})", 'type' => DataType::TYPE_NUMERIC];
|
||||||
|
$this->column_names['prod_pricelists']['sub'][$key.'final_with_vat'] = ['name' => $name.": finální cena s DPH ({$row['currency']})", 'type' => DataType::TYPE_NUMERIC];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$maxPhotos = sqlQueryBuilder()
|
||||||
|
->select('COUNT(ppr.id_photo) as cnt')
|
||||||
|
->from('photos_products_relation', 'ppr')
|
||||||
|
->groupBy('ppr.id_product')
|
||||||
|
->orderBy('cnt', 'DESC')
|
||||||
|
->setMaxResults(1)
|
||||||
|
->execute()
|
||||||
|
->fetchColumn();
|
||||||
|
for ($i = 1; $i <= $maxPhotos; $i++) {
|
||||||
|
$this->column_names['photos']['sub']['photo'.$i]['name'] = 'Fotografie '.$i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ['variants' => $variants, 'parameters' => $parameters ?? [], 'pricelists' => $pricelists ?? []];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getData(): Generator
|
||||||
|
{
|
||||||
|
$cfg = Config::get();
|
||||||
|
$sectionTree = ServiceContainer::getService(SectionTree::class);
|
||||||
|
$fromHeader = $this->defineHeader();
|
||||||
|
$variants = $fromHeader['variants'];
|
||||||
|
$parameters = $fromHeader['parameters'];
|
||||||
|
|
||||||
|
foreach ($this->getProducts() as $batch) {
|
||||||
|
$sheet = [];
|
||||||
|
$foto = [];
|
||||||
|
$idProducts = [];
|
||||||
|
$idVariations = [];
|
||||||
|
foreach ($batch as $row) {
|
||||||
|
$idProduct = $row['id'];
|
||||||
|
$idVariation = $row['id_variation'];
|
||||||
|
$row['price_with_vat'] = toDecimal($row['price_without_vat'])->addVat(toDecimal($row['vat']))->printFloatValue(2);
|
||||||
|
$row['discount_price_without_vat'] = toDecimal($row['price_without_vat'])->addDiscount($row['discount'])->printFloatValue(4);
|
||||||
|
$row['discount_price_with_vat'] = toDecimal($row['price_with_vat'])->addDiscount($row['discount'])->printFloatValue(2);
|
||||||
|
$row['section'] = $sectionTree->getFullPath($row['id_section']);
|
||||||
|
|
||||||
|
$row['campaign'] = join(', ', array_map(function ($char) use ($cfg) {
|
||||||
|
return getVal($char, $cfg['Products']['Flags'], ['plural' => $char])['plural'];
|
||||||
|
}, explode(',', $row['campaign'])));
|
||||||
|
|
||||||
|
$attachments = $row['attachments'] ? explode(',', $row['attachments']) : [];
|
||||||
|
$attachments = array_map(function ($el) use ($cfg) {
|
||||||
|
return rtrim($cfg['Addr']['full'], '/').trim($el);
|
||||||
|
}, array_filter($attachments, function ($el) { return !empty(trim($el)); }));
|
||||||
|
$row['attachments'] = join(', ', $attachments);
|
||||||
|
|
||||||
|
$fotorow = [];
|
||||||
|
$output_row = [];
|
||||||
|
foreach ($this->column_names as $key => $name) {
|
||||||
|
if ($key == 'variants') {
|
||||||
|
$combination = null;
|
||||||
|
if (!empty($row['variation_combination'])) {
|
||||||
|
$variation_combination = explode(';', $row['variation_combination']);
|
||||||
|
foreach ($variation_combination as $item) {
|
||||||
|
$variation = explode(':', $item);
|
||||||
|
$combination['var'.$variation[0]] = $variation[1]; // id_label => id_value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach ($name['sub'] ?? [] as $id_label => $label) {
|
||||||
|
if ($combination) {
|
||||||
|
if (array_key_exists($id_label, $combination)) {
|
||||||
|
$output_row[$id_label] = $variants[$id_label][$combination[$id_label]];
|
||||||
|
} else {
|
||||||
|
$output_row[$id_label] = '';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$output_row[$id_label] = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} elseif ($key == 'photos') {
|
||||||
|
$photos = explode(';', $row['photos'] ?? '');
|
||||||
|
foreach ($name['sub'] as $pkey => $pvalue) {
|
||||||
|
$photoIndex = str_replace('photo', '', $pkey) - 1;
|
||||||
|
if (!empty($photos[$photoIndex])) {
|
||||||
|
$fotorow[$pkey] = $cfg['Addr']['full'].'data/photos/'.$photos[$photoIndex];
|
||||||
|
} else {
|
||||||
|
$fotorow[$pkey] = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} elseif ($key == 'in_store') {
|
||||||
|
if (findModule(Modules::STORES) && $this->isExportOptionEnabled('exportStoresInStore')) {
|
||||||
|
foreach ($name['sub'] as $subkey => $label) {
|
||||||
|
if (!empty($row[$subkey])) {
|
||||||
|
$output_row[$subkey] = (float) $row[$subkey];
|
||||||
|
} else {
|
||||||
|
$output_row[$subkey] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!empty($row[$key])) {
|
||||||
|
$output_row[$key] = (float) $row[$key];
|
||||||
|
} else {
|
||||||
|
$output_row[$key] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} elseif (!empty($row[$key])) {
|
||||||
|
$output_row[$key] = mb_strcut($row[$key], 0, 32767);
|
||||||
|
} elseif ($key == 'prod_parameters') {
|
||||||
|
foreach ($name['sub'] as $subkey => $label) {
|
||||||
|
$output_row[$subkey] = '';
|
||||||
|
}
|
||||||
|
} elseif ($key == 'prod_pricelists') {
|
||||||
|
foreach ($name['sub'] as $subkey => $label) {
|
||||||
|
$output_row[$subkey] = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$output_row[$key] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$idProducts[] = $idProduct;
|
||||||
|
if ($idVariation) {
|
||||||
|
$idVariations[$idProduct][] = $idVariation;
|
||||||
|
} else {
|
||||||
|
$idVariations[$idProduct] = null;
|
||||||
|
}
|
||||||
|
$sheet[$idProduct][$idVariation] = $output_row;
|
||||||
|
$foto[$idProduct][$idVariation] = $fotorow;
|
||||||
|
}
|
||||||
|
if (findModule('products_parameters') && $this->isExportOptionEnabled('exportParameters')) {
|
||||||
|
$parqb = sqlQueryBuilder()->select('pp.id_parameter, pp.id_product, GROUP_CONCAT(COALESCE(pl.value, pp.value_char, pp.value_float) ORDER BY pl.position,pl.id) as parvalue')
|
||||||
|
->from('parameters_products', 'pp')
|
||||||
|
->leftJoin('pp', 'parameters_list', 'pl', 'pl.id=pp.value_list')
|
||||||
|
->where(Operator::inIntArray($idProducts, 'pp.id_product'))
|
||||||
|
->groupBy('pp.id_parameter, pp.id_product')
|
||||||
|
->orderBy('pp.id_product')
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
foreach ($parqb as $par) {
|
||||||
|
foreach ($sheet[$par['id_product']] as &$row) {
|
||||||
|
$row['par'.$par['id_parameter']] = $par['parvalue'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (findModule(Modules::STORES) && $this->isExportOptionEnabled('exportStoresInStore')) {
|
||||||
|
$filter = getVal('filter');
|
||||||
|
$storeIds = null;
|
||||||
|
if (isset($filter['stores'])) {
|
||||||
|
$storeIds = $filter['stores'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$storeQuery = sqlQueryBuilder()
|
||||||
|
->select('p.id id_product, pv.id id_variation')
|
||||||
|
->fromProducts()
|
||||||
|
->joinVariationsOnProducts()
|
||||||
|
->andWhere(Operator::inIntArray($idProducts, 'p.id'))
|
||||||
|
->andWhere(StoresQuery::addStoresInStoreAmounts($storeIds, addMinQuantity: false));
|
||||||
|
|
||||||
|
if (!empty($filter['variations'])) {
|
||||||
|
// ad limit for variations based on filter[variations]
|
||||||
|
$idVariations = sqlQueryBuilder()
|
||||||
|
->select('id_variation')
|
||||||
|
->from('products_variations_combination')
|
||||||
|
->andWhere(Operator::inIntArray($filter['variations'], 'id_value'))
|
||||||
|
->execute()->fetchFirstColumn();
|
||||||
|
|
||||||
|
$storeQuery->andWhere(Operator::inIntArray($idVariations, 'pv.id'));
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($storeQuery->execute() as $storesRow) {
|
||||||
|
$id_product = $storesRow['id_product'];
|
||||||
|
$id_variation = $storesRow['id_variation'] ?? 0;
|
||||||
|
|
||||||
|
unset($storesRow['id_product'], $storesRow['id_variation']);
|
||||||
|
|
||||||
|
foreach ($storesRow as $key => $value) {
|
||||||
|
$sheet[$id_product][$id_variation][$key] = intval($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($pricelists = $fromHeader['pricelists']) {
|
||||||
|
$plIDs = implode(',', array_column($pricelists, 'id'));
|
||||||
|
// pouze data (ceny a slevy) vyplnene v ceniku, neni potreba COALESCE(prlv.price, pv.price, prlp.price, p.price) atd. jako na FE
|
||||||
|
$plqb = sqlQueryBuilder()
|
||||||
|
->select('p.id as id_product, pv.id as id_variation, v.vat, prl.id as id_pricelist,
|
||||||
|
COALESCE(prlv.price, prlp.price, pv.price, p.price) as price, COALESCE(prlv.discount, prlp.discount) as discount')
|
||||||
|
->fromProducts()->joinVariationsOnProducts()
|
||||||
|
->leftJoin('p', 'vats', 'v', 'v.id = p.vat')
|
||||||
|
->leftJoin('p', 'pricelists', 'prl', "prl.id IN ({$plIDs})")
|
||||||
|
->leftJoin('p', 'pricelists_products', 'prlp', 'prl.id = prlp.id_pricelist AND prlp.id_product = p.id AND prlp.id_variation IS NULL')
|
||||||
|
->leftJoin('p', 'pricelists_products', 'prlv', 'prl.id = prlv.id_pricelist AND prlv.id_product = p.id AND prlv.id_variation = pv.id')
|
||||||
|
->andWhere(\Query\Product::productsAndVariationsIds($idVariations))
|
||||||
|
->groupBy('p.id, pv.id, prl.id');
|
||||||
|
|
||||||
|
if (findModule(\Modules::PRICE_HISTORY)) {
|
||||||
|
$plqb->addSelect(['COALESCE(prlv.price_for_discount, prlp.price_for_discount, pv.price_for_discount, p.price_for_discount) as price_for_discount']);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($plqb->execute() as $pl_row) {
|
||||||
|
$id_product = $pl_row['id_product'];
|
||||||
|
$id_variation = $pl_row['id_variation'] ?? 0;
|
||||||
|
$col = 'pl'.$pl_row['id_pricelist'];
|
||||||
|
$sheet[$id_product][$id_variation][$col] = $pl_row['price'];
|
||||||
|
$sheet[$id_product][$id_variation][$col.'discount'] = $pl_row['discount'];
|
||||||
|
if (findModule(\Modules::PRICE_HISTORY)) {
|
||||||
|
$sheet[$id_product][$id_variation][$col.'price_for_discount'] = $pl_row['price_for_discount'];
|
||||||
|
}
|
||||||
|
if ($pl_row['price']) {
|
||||||
|
$sheet[$id_product][$id_variation][$col.'final'] = $pl_row['price'];
|
||||||
|
if ($pl_row['discount']) {
|
||||||
|
$sheet[$id_product][$id_variation][$col.'final'] = $pl_row['price'] * (100 - $pl_row['discount']) / 100;
|
||||||
|
}
|
||||||
|
$sheet[$id_product][$id_variation][$col.'final_with_vat'] = toDecimal($sheet[$id_product][$id_variation][$col.'final'] * ((100 + $pl_row['vat']) / 100))->printFloatValue(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach ($sheet as $idProd => $product) {
|
||||||
|
foreach ($product as $idVar => $variant) {
|
||||||
|
yield array_merge($variant, $foto[$idProd][$idVar] ?? []);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function isExportOptionEnabled(string $option): bool
|
||||||
|
{
|
||||||
|
return ($this->getExportOptions()[$option] ?? false) === 'Y';
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getExportOptions(): array
|
||||||
|
{
|
||||||
|
return getVal('options', null, []);
|
||||||
|
}
|
||||||
|
}
|
||||||
240
admin/class/class.Frame.php
Normal file
240
admin/class/class.Frame.php
Normal file
@@ -0,0 +1,240 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use KupShop\I18nBundle\Util\TranslationUtil;
|
||||||
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||||
|
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
|
||||||
|
|
||||||
|
#[AllowDynamicProperties]
|
||||||
|
class Frame extends Base
|
||||||
|
{
|
||||||
|
protected $ID;
|
||||||
|
protected $errors = [];
|
||||||
|
protected $htmlErrors = [];
|
||||||
|
|
||||||
|
public function get_vars()
|
||||||
|
{
|
||||||
|
$vars = parent::get_vars();
|
||||||
|
|
||||||
|
$ErrStr = getVal('ErrStr');
|
||||||
|
if (!empty($ErrStr)) {
|
||||||
|
$this->errors[] = $ErrStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
$vars['ErrStr'] = join(',', $this->getErrors());
|
||||||
|
|
||||||
|
if ($vars['ErrStr'] && $vars['ErrStr'] != translate('saved', 'status')) {
|
||||||
|
header('admin-error: '.urlencode(mb_strcut($vars['ErrStr'], 0, 1024)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($this->getHTMLErrors())) {
|
||||||
|
$error = '';
|
||||||
|
foreach ($this->getHTMLErrors() as $HTMLError) {
|
||||||
|
$error .= '<p>'.$HTMLError.'</p>';
|
||||||
|
}
|
||||||
|
header('admin-html-error: '.urlencode(mb_strcut($error, 0, 1024)));
|
||||||
|
}
|
||||||
|
|
||||||
|
$OkStr = getVal('OkStr');
|
||||||
|
if (!empty($OkStr)) {
|
||||||
|
$vars['OkStr'] = $OkStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($this->getHTMLErrors())) {
|
||||||
|
$vars['htmlErrors'] = $this->getHTMLErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
$header = getVal('header', $vars, []);
|
||||||
|
|
||||||
|
$header['date'] = date('Ymd');
|
||||||
|
|
||||||
|
if (getVal('hdrType') != null) {
|
||||||
|
$header['hdrType'] = getVal('hdrType');
|
||||||
|
}
|
||||||
|
|
||||||
|
$header['refresh'] = getVal('refresh');
|
||||||
|
|
||||||
|
$vars['header'] = $header;
|
||||||
|
|
||||||
|
return $vars;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function tryRights($acn = '')
|
||||||
|
{
|
||||||
|
// Musim mit budto prava na pozadovanou akci, nebo READ prava
|
||||||
|
if (!UserRights::hasRights($this->getRightsType(), $acn) && !UserRights::hasRights($this->getRightsType(), 'READ')) {
|
||||||
|
throw new AccessDeniedException('');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getRightsType()
|
||||||
|
{
|
||||||
|
$type = getVal('s');
|
||||||
|
if (!$type || $type == 'list.php') {
|
||||||
|
$type = getVal('type');
|
||||||
|
|
||||||
|
if (!$type) {
|
||||||
|
$type = lcfirst($this->getClassName());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$type = substr($type, 0, -4);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $type;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getAction()
|
||||||
|
{
|
||||||
|
if (empty($this->action)) {
|
||||||
|
$acn = getVal('acn');
|
||||||
|
if (empty($acn)) {
|
||||||
|
$acn = 'add';
|
||||||
|
}
|
||||||
|
$this->action = $acn;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->action;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getID()
|
||||||
|
{
|
||||||
|
if (empty($this->ID)) {
|
||||||
|
$ID = getVal('ID');
|
||||||
|
/*if(empty($ID))
|
||||||
|
logError(__FILE__, __LINE__, "Empty ID");*/
|
||||||
|
$this->setID($ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setID($id)
|
||||||
|
{
|
||||||
|
$this->ID = $id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return substr(getVal('s'), 0, -4);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function returnError($ErrStr, $parentRefresh = '', $ID = null)
|
||||||
|
{
|
||||||
|
if (empty($ID)) {
|
||||||
|
$ID = $this->getID();
|
||||||
|
}
|
||||||
|
if ($parentRefresh) {
|
||||||
|
if ($refresh = getVal('refresh')) {
|
||||||
|
$parentRefresh = "&refresh={$refresh}";
|
||||||
|
} else {
|
||||||
|
$parentRefresh = '&refresh=parent';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (getVal('autoclose')) {
|
||||||
|
$parentRefresh .= '&refresh=close';
|
||||||
|
}
|
||||||
|
$type = getVal('type');
|
||||||
|
if ($type) {
|
||||||
|
$parentRefresh .= '&type='.$type;
|
||||||
|
}
|
||||||
|
redirect("launch.php?s={$this->getName()}.php&acn=edit{$parentRefresh}&flap=".getVal('flap')."&ID={$ID}&ErrStr=".urlencode($ErrStr));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addError($ErrStr = null)
|
||||||
|
{
|
||||||
|
$this->errors[] = $ErrStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addHTMLError($error)
|
||||||
|
{
|
||||||
|
$this->htmlErrors[] = $error;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHTMLErrors()
|
||||||
|
{
|
||||||
|
return array_unique($this->htmlErrors);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getErrors()
|
||||||
|
{
|
||||||
|
return array_unique($this->errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function returnOK($ErrStr = null, $parentRefresh = false, $params = [])
|
||||||
|
{
|
||||||
|
if (empty($ErrStr)) {
|
||||||
|
$this->returnError($GLOBALS['txt_str']['status']['saved'], true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($parentRefresh) {
|
||||||
|
$params['refresh'] = 'parent';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getVal('type')) {
|
||||||
|
$params['type'] = getVal('type');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getVal('flap')) {
|
||||||
|
$params['flap'] = getVal('flap');
|
||||||
|
}
|
||||||
|
|
||||||
|
$params['OkStr'] = $ErrStr;
|
||||||
|
|
||||||
|
if (empty($params['acn'])) {
|
||||||
|
$params['acn'] = 'edit';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->redirect($params);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function redirect($params = [])
|
||||||
|
{
|
||||||
|
$params = array_merge($_GET, $params);
|
||||||
|
|
||||||
|
return redirect('launch.php?'.http_build_query($params));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function unserializeCustomData(&$data)
|
||||||
|
{
|
||||||
|
if (!isset($data['data'])) {
|
||||||
|
$data['data'] = [];
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_string($data['data'])) {
|
||||||
|
$data['data'] = json_decode($data['data'], true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($data['data']) && !is_object($data['data'])) {
|
||||||
|
$data['data'] = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function serializeCustomData(&$data)
|
||||||
|
{
|
||||||
|
if (empty($data['data'])) {
|
||||||
|
$data['data'] = null;
|
||||||
|
} else {
|
||||||
|
$data['data'] = json_encode($data['data']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function isDuplicate()
|
||||||
|
{
|
||||||
|
return getVal('Duplicate');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getTranslationUtil(): ?TranslationUtil
|
||||||
|
{
|
||||||
|
if (!findModule(\Modules::TRANSLATIONS)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
static $translationUtil;
|
||||||
|
|
||||||
|
if (!$translationUtil) {
|
||||||
|
$translationUtil = ServiceContainer::getService(TranslationUtil::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $translationUtil;
|
||||||
|
}
|
||||||
|
}
|
||||||
28
admin/class/class.Menu.php
Normal file
28
admin/class/class.Menu.php
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Menu extends Frame
|
||||||
|
{
|
||||||
|
public function getTemplate()
|
||||||
|
{
|
||||||
|
if (!($template = $this->template)) {
|
||||||
|
$template = './menu/'.getVal('type').'.tpl';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->smarty->templateExists($template)) {
|
||||||
|
return $template;
|
||||||
|
}
|
||||||
|
|
||||||
|
return './menu.tpl';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_vars()
|
||||||
|
{
|
||||||
|
$vars = parent::get_vars();
|
||||||
|
|
||||||
|
return array_merge($vars, [
|
||||||
|
'dateToday' => date('Y-m-d'),
|
||||||
|
'dateFrom' => date('Y-m-d', time() - (14 * 86400)),
|
||||||
|
'type' => getVal('type'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
0
admin/class/class.OrdersMassProcess.php
Normal file
0
admin/class/class.OrdersMassProcess.php
Normal file
390
admin/class/class.StockInImport.php
Normal file
390
admin/class/class.StockInImport.php
Normal file
@@ -0,0 +1,390 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use KupShop\AdminBundle\Util\StockInProductOfSupplierService;
|
||||||
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||||
|
use KupShop\KupShopBundle\Util\Functional\Mapping;
|
||||||
|
use Query\Operator;
|
||||||
|
|
||||||
|
class StockInImport
|
||||||
|
{
|
||||||
|
use DatabaseCommunication;
|
||||||
|
|
||||||
|
public $type;
|
||||||
|
|
||||||
|
public $errors = [];
|
||||||
|
public $default_settings = [
|
||||||
|
'type' => 'xlsx',
|
||||||
|
'fields' => [0 => 'code', 1 => 'name', 2 => 'quantity', 3 => 'ean', 4 => 'price', 5 => 'supplier_code'],
|
||||||
|
'search_in_products' => true,
|
||||||
|
'isdoc_search_in_ean' => true,
|
||||||
|
'encoding' => 'UTF-8',
|
||||||
|
'skip' => '1',
|
||||||
|
'piece_price' => true,
|
||||||
|
'default' => true,
|
||||||
|
];
|
||||||
|
public $supplier_settings;
|
||||||
|
protected $separator = ';';
|
||||||
|
protected $skip = 0;
|
||||||
|
protected $encoding;
|
||||||
|
protected $fields = [];
|
||||||
|
protected $stock_in;
|
||||||
|
protected $check_file_name = false;
|
||||||
|
protected $only_visible = false;
|
||||||
|
protected $search_in_products = false;
|
||||||
|
protected $multiple = 1;
|
||||||
|
protected $cut_code;
|
||||||
|
protected $ignore_code = false;
|
||||||
|
|
||||||
|
protected $stockInIndex;
|
||||||
|
protected StockInProductOfSupplierService $stockInProductOfSupplierService;
|
||||||
|
|
||||||
|
public function __construct($stock_in, $stockInIndex = 'invoice')
|
||||||
|
{
|
||||||
|
$this->stock_in = $stock_in;
|
||||||
|
$this->supplier_settings = sqlQueryBuilder()->select('s.import_settings')
|
||||||
|
->from('suppliers', 's')
|
||||||
|
->where(Operator::equals(['id' => $stock_in['id_supplier']]))
|
||||||
|
->execute()
|
||||||
|
->fetchColumn();
|
||||||
|
$this->stockInIndex = $stockInIndex;
|
||||||
|
|
||||||
|
/* @var StockInProductOfSupplierService $supplierService */
|
||||||
|
$this->stockInProductOfSupplierService = ServiceContainer::getService(StockInProductOfSupplierService::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function load_supplier_settings()
|
||||||
|
{
|
||||||
|
$settings = $this->supplier_settings != null ? json_decode($this->supplier_settings, true) : $this->default_settings;
|
||||||
|
if ($this->supplier_settings && json_last_error()) {
|
||||||
|
throw new Exception('Nelze nacist nastaveni importu: '.json_last_error_msg());
|
||||||
|
}
|
||||||
|
foreach ((array) $settings as $key => $value) {
|
||||||
|
$this->$key = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function import($file)
|
||||||
|
{
|
||||||
|
if ($this->check_file_name) {
|
||||||
|
$name = pathinfo($file['name'], PATHINFO_FILENAME);
|
||||||
|
|
||||||
|
if ($name != $this->stock_in['code']) {
|
||||||
|
return $this->add_error("Nesedí jméno souboru s číslem faktury: {$name} != {$this->stock_in['code']}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($file['tmp_name'])) {
|
||||||
|
return $this->add_error('Nebyl nahrán žádný soubor!');
|
||||||
|
}
|
||||||
|
|
||||||
|
$method = "import_{$this->type}";
|
||||||
|
|
||||||
|
sqlStartTransaction();
|
||||||
|
|
||||||
|
$ret = $this->$method($file['tmp_name']);
|
||||||
|
|
||||||
|
sqlFinishTransaction();
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function import_isdoc($file)
|
||||||
|
{
|
||||||
|
$xml = simplexml_load_file($file);
|
||||||
|
|
||||||
|
$factorage = [
|
||||||
|
'date_issued' => (string) $xml->IssueDate,
|
||||||
|
'note' => (string) $xml->note,
|
||||||
|
'date_expiration' => (string) $xml->PaymentMeans->Payment->Details->PaymentDueDate,
|
||||||
|
'total_price' => (string) $xml->LegalMonetaryTotal->TaxExclusiveAmount,
|
||||||
|
];
|
||||||
|
if (!$this->ignore_code) {
|
||||||
|
$factorage['code'] = (string) $xml->ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->updateSQL(
|
||||||
|
'stock_in',
|
||||||
|
$factorage,
|
||||||
|
[
|
||||||
|
'id' => $this->stock_in['id'],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($xml->InvoiceLines->InvoiceLine as $invoiceLine) {
|
||||||
|
$item = [
|
||||||
|
'code' => (string) $invoiceLine->Item->SellersItemIdentification->ID,
|
||||||
|
'name' => (string) $invoiceLine->Item->Description,
|
||||||
|
'quantity' => (string) $invoiceLine->InvoicedQuantity,
|
||||||
|
'price' => (string) $invoiceLine->LineExtensionAmount,
|
||||||
|
'vat' => (string) $invoiceLine->ClassifiedTaxCategory->Percent,
|
||||||
|
];
|
||||||
|
|
||||||
|
if ($this->isdoc_search_in_ean ?? false) {
|
||||||
|
$ean = array_filter([
|
||||||
|
(int) $invoiceLine->Item->CatalogueItemIdentification->ID ?? '', // tady by mel byt EAN dle dokumentace
|
||||||
|
(int) $invoiceLine->Item->SellersItemIdentification->ID ?? '', // nekdo ma EAN tady
|
||||||
|
]);
|
||||||
|
if ($ean) {
|
||||||
|
$ean = (count($ean) == 1 ? reset($ean) : $ean);
|
||||||
|
$item['ean'] = $ean;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($item['quantity'] < 0) {
|
||||||
|
$item['price'] = (string) $invoiceLine->UnitPrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->add_item($item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function import_isdocx($file)
|
||||||
|
{
|
||||||
|
$za = new ZipArchive();
|
||||||
|
$res = $za->open($file);
|
||||||
|
if ($res !== true) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// finds the first .isdoc file and returns it or false
|
||||||
|
$findIsdoc = function ($zipArchive) {
|
||||||
|
// loop through all files in zip
|
||||||
|
for ($i = 0; $i < $zipArchive->numFiles; $i++) {
|
||||||
|
$stat = $zipArchive->statIndex($i);
|
||||||
|
|
||||||
|
// if extension is .isdoc return the filename
|
||||||
|
if (preg_match('/(.*\.isdoc)/', $stat['name']) === 1) {
|
||||||
|
return $stat['name'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
$fileName = 'zip://'.$file.'#'.$findIsdoc($za);
|
||||||
|
$za->close();
|
||||||
|
|
||||||
|
return $this->import_isdoc($fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function fopen_convert($fileName)
|
||||||
|
{
|
||||||
|
$fc = iconv($this->encoding, 'utf-8', file_get_contents($fileName));
|
||||||
|
$handle = fopen('php://memory', 'rw');
|
||||||
|
fwrite($handle, $fc);
|
||||||
|
fseek($handle, 0);
|
||||||
|
|
||||||
|
return $handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function import_xlsx($file)
|
||||||
|
{
|
||||||
|
$xlsx = new AutomaticImportTransform($file);
|
||||||
|
$data = $xlsx->GetXml();
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
foreach ($data->item as $row) {
|
||||||
|
if ($i < $this->skip) {
|
||||||
|
$i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$arr = json_decode(json_encode($row), true)['col'];
|
||||||
|
$arr = array_pad($arr, count($this->fields), null);
|
||||||
|
$item = array_combine($this->fields, array_slice($arr, 0, count($this->fields)));
|
||||||
|
|
||||||
|
// kontrola prázdného řádku
|
||||||
|
if (!empty($item) && !is_array($item['quantity'])) {
|
||||||
|
$this->add_item($item);
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function import_csv($file)
|
||||||
|
{
|
||||||
|
if ($this->encoding) {
|
||||||
|
$file = $this->fopen_convert($file);
|
||||||
|
} else {
|
||||||
|
$file = fopen($file, 'r');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$file) {
|
||||||
|
exit('Nelze načíst soubor');
|
||||||
|
}
|
||||||
|
|
||||||
|
$count = count($this->fields);
|
||||||
|
|
||||||
|
while ($this->skip-- > 0) {
|
||||||
|
fgetcsv($file, null, $this->separator);
|
||||||
|
}
|
||||||
|
|
||||||
|
while ($row = fgetcsv($file, null, $this->separator)) {
|
||||||
|
$row = array_combine($this->fields, array_slice($row, 0, $count));
|
||||||
|
$this->add_item($row);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function add_item($item)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Funkce na uříznutí X počtu znaků z kodu. Stačí zadat v importu/exportu "cut" = 'začátek';'konec'
|
||||||
|
* */
|
||||||
|
if ($this->cut_code) {
|
||||||
|
$cut = explode(';', $this->cut_code);
|
||||||
|
$item['code'] = substr($item['code'], $cut[0], $cut[1] ?? (strlen($item['code']) - $cut[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
$mapping = [];
|
||||||
|
if (!empty($item['code'])) {
|
||||||
|
$mapping = ['code' => $item['code']];
|
||||||
|
}
|
||||||
|
if (!empty($item['ean'])) {
|
||||||
|
$mapping['ean'] = $item['ean'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($mapping)) {
|
||||||
|
$qb = sqlQueryBuilder()->select('pos.id_product', 'pos.id_variation', 'pos.import_multiplier', 'p.vat as id_vat')
|
||||||
|
->from('products_of_suppliers', 'pos')
|
||||||
|
->leftJoin('pos', 'products', 'p', 'pos.id_product=p.id')
|
||||||
|
->where(Operator::equals(['pos.id_supplier' => $this->stock_in['id_supplier']]));
|
||||||
|
if ($this->only_visible) {
|
||||||
|
$qb->andWhere(Operator::equals(['p.figure' => 'Y']));
|
||||||
|
}
|
||||||
|
|
||||||
|
$operators = array_map(function ($key, $value) {
|
||||||
|
if (is_array($value)) {
|
||||||
|
return Operator::inIntArray($value, "pos.{$key}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Operator::equals(["pos.{$key}" => $value]);
|
||||||
|
}, array_keys($mapping), $mapping);
|
||||||
|
$qb->andWhere(Operator::orX($operators));
|
||||||
|
|
||||||
|
$product = $qb->execute()->fetch();
|
||||||
|
|
||||||
|
if (!$product && $this->search_in_products) {
|
||||||
|
$qb = sqlQueryBuilder()->select('p.id AS id_product, pv.id AS id_variation')
|
||||||
|
->fromProducts()
|
||||||
|
->joinVariationsOnProducts();
|
||||||
|
|
||||||
|
$productsMapping = array_merge(
|
||||||
|
Mapping::mapKeys($mapping, function ($key, $value) {return ["p.{$key}", $value]; }),
|
||||||
|
Mapping::mapKeys($mapping, function ($key, $value) {return ["pv.{$key}", $value]; })
|
||||||
|
);
|
||||||
|
if (isset($productsMapping['pv.code']) && !findModule(Modules::PRODUCTS_VARIATIONS, Modules::SUB_CODE)) {
|
||||||
|
unset($productsMapping['pv.code']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$operators = array_map(function ($key, $value) {
|
||||||
|
if (is_array($value)) {
|
||||||
|
return Operator::inStringArray($value, $key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Operator::equals([$key => $value]);
|
||||||
|
}, array_keys($productsMapping), $productsMapping);
|
||||||
|
$qb->andWhere(Operator::orX($operators));
|
||||||
|
|
||||||
|
if ($this->only_visible) {
|
||||||
|
$qb->andWhere(Operator::equals(['p.figure' => 'Y']));
|
||||||
|
}
|
||||||
|
$product = $qb->execute()->fetch();
|
||||||
|
|
||||||
|
if ($product) {
|
||||||
|
$product['import_multiplier'] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$product = null;
|
||||||
|
$mapping['code'] = translate('unknown');
|
||||||
|
$mapping['ean'] = translate('unknown');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$product || $product['import_multiplier'] == 0) {
|
||||||
|
$product = ['id_product' => null, 'id_variation' => null, 'name' => "{$item['name']} (kód: {$mapping['code']}, ean: {$mapping['ean']})", 'import_multiplier' => 1, 'id_vat' => 0];
|
||||||
|
} else {
|
||||||
|
$product['name'] = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$product['id_stock_in'] = $this->stock_in['id'];
|
||||||
|
|
||||||
|
$product['quantity'] = round((float) $item['quantity'] * (float) $product['import_multiplier'] * (float) $this->multiple);
|
||||||
|
|
||||||
|
$product['vat'] = empty($item['vat']) ? getVat($product['id_vat']) : $item['vat'];
|
||||||
|
|
||||||
|
if (empty($item['price']) && !empty($item['price_with_vat'])) {
|
||||||
|
$price = toDecimal($this->preparePrice($item['price_with_vat']))->removeVat($product['vat']);
|
||||||
|
} else {
|
||||||
|
$price = toDecimal($this->preparePrice($item['price']));
|
||||||
|
}
|
||||||
|
|
||||||
|
// if isset price multiplier
|
||||||
|
if (isset($this->stock_in['multiplier'])) {
|
||||||
|
$price = $price->mul(toDecimal($this->stock_in['multiplier']));
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($product['id_vat']);
|
||||||
|
|
||||||
|
if (isset($this->piece_price)) {
|
||||||
|
$product['price'] = $price;
|
||||||
|
} else {
|
||||||
|
$product['price'] = $product['quantity'] > 0 ? $price->div(toDecimal($product['quantity'])) : $price;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->insertSQL('stock_in_items', $product, ['import_multiplier']) <= 0) {
|
||||||
|
return $this->add_error('Cannot add '.print_r($product, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($product['id_product'] > 0 && !in_array($this->stockInIndex, ['future', 'preorder'])) {
|
||||||
|
$prod = new Product($product['id_product']);
|
||||||
|
$prod->storeIn($product['id_variation'], $product['quantity']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$product['supplier_code'] = !empty($item['supplier_code']) ? trim($item['supplier_code']) : null;
|
||||||
|
$stockInData = getVal('data');
|
||||||
|
|
||||||
|
try {
|
||||||
|
$this->stockInProductOfSupplierService->updateOrInsertProductSupplier($product, $stockInData);
|
||||||
|
} catch (Exception|\Doctrine\DBAL\Driver\Exception) {
|
||||||
|
$this->add_error("Nepodařilo se uložit kód dodavatele '{$item['code']}' položky: {$item['name']}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function add_error($string)
|
||||||
|
{
|
||||||
|
$this->errors[] = $string;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!function_exists('json_last_error_msg')) {
|
||||||
|
function json_last_error_msg()
|
||||||
|
{
|
||||||
|
switch (json_last_error()) {
|
||||||
|
case JSON_ERROR_NONE:
|
||||||
|
return 'No errors';
|
||||||
|
case JSON_ERROR_DEPTH:
|
||||||
|
return 'Maximum stack depth exceeded';
|
||||||
|
case JSON_ERROR_STATE_MISMATCH:
|
||||||
|
return 'Underflow or the modes mismatch';
|
||||||
|
case JSON_ERROR_CTRL_CHAR:
|
||||||
|
return 'Unexpected control character found';
|
||||||
|
case JSON_ERROR_SYNTAX:
|
||||||
|
return 'Syntax error, malformed JSON';
|
||||||
|
case JSON_ERROR_UTF8:
|
||||||
|
return 'Malformed UTF-8 characters, possibly incorrectly encoded';
|
||||||
|
default:
|
||||||
|
return 'Unknown error';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
742
admin/class/class.UserRights.php
Normal file
742
admin/class/class.UserRights.php
Normal file
@@ -0,0 +1,742 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use KupShop\AdminBundle\AdminRegister\AdminRegisterLocator;
|
||||||
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||||
|
|
||||||
|
class UserRights
|
||||||
|
{
|
||||||
|
private static $adminRegisterLocator;
|
||||||
|
|
||||||
|
public static function getAdminRegisterLocator(): AdminRegisterLocator
|
||||||
|
{
|
||||||
|
if (!isset(self::$adminRegisterLocator)) {
|
||||||
|
self::$adminRegisterLocator = ServiceContainer::getService(AdminRegisterLocator::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$adminRegisterLocator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function hasRights($type, $specific = '')
|
||||||
|
{
|
||||||
|
$item = self::getAdminRegisterLocator()->getPermissions($type) ?? getVal($type, self::$rights);
|
||||||
|
|
||||||
|
if (!$item) {
|
||||||
|
// logError(__FILE__, __LINE__, "Nonexisting user right: $type");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($item['superadmin']) && !isSuperuser()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($item['modules']) || !empty($item['submodules'])) {
|
||||||
|
$allow = false;
|
||||||
|
foreach ($item['modules'] ?? [] as $module) {
|
||||||
|
if (findModule($module)) {
|
||||||
|
$allow |= true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($item['submodules'] ?? [] as $module => $submodule) {
|
||||||
|
if (findModule($module, $submodule)) {
|
||||||
|
$allow |= true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$allow) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($item['rights'])) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($item['rights'] as $right) {
|
||||||
|
if (substr($right, -1) == '_') {
|
||||||
|
if (findRight($right.$specific)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} elseif (findRight($right)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function isOnlySuperadmin($type)
|
||||||
|
{
|
||||||
|
$item = self::getAdminRegisterLocator()->getPermissions($type) ?? getVal($type, self::$rights);
|
||||||
|
if (!$item) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($item['superadmin']) && $item['superadmin'] === true) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addRights($list, $rights = [])
|
||||||
|
{
|
||||||
|
self::$rights[$list] = $rights;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static $rights = [
|
||||||
|
'productsRelatedTypes' => [
|
||||||
|
'submodules' => [
|
||||||
|
Modules::PRODUCTS_RELATED => Modules::SUB_TYPES,
|
||||||
|
],
|
||||||
|
'superadmin' => true,
|
||||||
|
],
|
||||||
|
'products' => [
|
||||||
|
'modules' => [
|
||||||
|
'products',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'PROD_',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'productsMassModification' => [
|
||||||
|
'modules' => [
|
||||||
|
'products',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'PROD_EDIT',
|
||||||
|
'PROD_ERASE',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'parameters' => [
|
||||||
|
'modules' => [
|
||||||
|
'products_parameters',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'PARAM',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'productsVarLabels' => [
|
||||||
|
'modules' => [
|
||||||
|
'products_variations',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'VARIANT_LABELS',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'sections' => [
|
||||||
|
'modules' => [
|
||||||
|
'products_sections',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'SEC_',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'producers' => [
|
||||||
|
'modules' => [
|
||||||
|
'producers',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'PRODCR',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'orders' => [
|
||||||
|
'modules' => [
|
||||||
|
'orders',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'ORDER_',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'ProductsSerialNumbers' => [
|
||||||
|
'modules' => [
|
||||||
|
'products_serial_numbers',
|
||||||
|
'stock_in',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'PSERNUM',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'ProductsBatches' => [
|
||||||
|
'modules' => [
|
||||||
|
Modules::PRODUCTS_BATCHES,
|
||||||
|
Modules::WAREHOUSE,
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'PBATCHES',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'users' => [
|
||||||
|
'modules' => [
|
||||||
|
'eshop_users',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'USR_',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
'discounts' => [
|
||||||
|
'modules' => [
|
||||||
|
'order_discount',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'DISCNT',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'ordersMassProcess' => [
|
||||||
|
'modules' => [
|
||||||
|
'orders_mass_process',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'ORDER',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'photos' => [
|
||||||
|
'modules' => [
|
||||||
|
'photos',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'PHOTOS_',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'fileBrowser' => [
|
||||||
|
'rights' => [
|
||||||
|
'FILE_BROWSER_USE',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'stockIn' => [
|
||||||
|
'modules' => [
|
||||||
|
'stock_in',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'INSTORE_STOCKIN',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'suppliers' => [
|
||||||
|
'modules' => [
|
||||||
|
'products_suppliers',
|
||||||
|
'automatic_import',
|
||||||
|
'suppliers',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'INSTORE_STOCKIN',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'stockInMissing' => [
|
||||||
|
'modules' => [
|
||||||
|
'missing_products',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'INSTORE_MISSING',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'InfoPanelList' => [
|
||||||
|
'modules' => [
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'INFOPANEL',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'shopStore' => [
|
||||||
|
'modules' => [
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'MODULOVNA',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'ReturnDelivery' => [
|
||||||
|
'modules' => [
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'RETURNS',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'LabelsList' => [
|
||||||
|
'modules' => [
|
||||||
|
Modules::LABELS,
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'LABELS',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
'templatesMenu' => [
|
||||||
|
'modules' => [
|
||||||
|
'templates',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'PRODUCT_TEMPLATES',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'BonusProgramExchange' => [
|
||||||
|
'submodules' => [
|
||||||
|
Modules::BONUS_PROGRAM => Modules::SUB_POINTS_EXCHANGE,
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'BONUS_PROGRAM_EXCHANGE',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
'Sales' => [
|
||||||
|
'modules' => [
|
||||||
|
Modules::SALES,
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'SALES',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
'productsOfSuppliers' => [
|
||||||
|
'modules' => [
|
||||||
|
'stock_in',
|
||||||
|
'products_suppliers',
|
||||||
|
'suppliers',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'INSTORE_STOCKIN',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'inventory' => [
|
||||||
|
'modules' => [
|
||||||
|
'inventory',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'INVENTORY',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'productsPrices' => [
|
||||||
|
'submodules' => [
|
||||||
|
Modules::PRODUCTS => Modules::SUB_PRICE_BUY,
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'INVENTORY',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'stockManual' => [
|
||||||
|
'modules' => [
|
||||||
|
'stock_in',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'INSTORE_STOCKIN',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'pages' => [
|
||||||
|
'modules' => [
|
||||||
|
'menulinks',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'MENU_LINKS',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'menu' => [
|
||||||
|
'modules' => [
|
||||||
|
'menulinks',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'MENU_LINKS',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'sliders' => [
|
||||||
|
'modules' => [
|
||||||
|
'sliders',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'SLIDERS',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'articles' => [
|
||||||
|
'modules' => [
|
||||||
|
'articles',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'ART_',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'artsections' => [
|
||||||
|
'modules' => [
|
||||||
|
'articles_sections',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'ART_SEC_',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'articlesTags' => [
|
||||||
|
'modules' => [
|
||||||
|
'articles',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'ART_',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'artauthors' => [
|
||||||
|
'modules' => [
|
||||||
|
Modules::ARTICLES_AUTHORS,
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'ART_AUTH_',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'dbbackup' => [
|
||||||
|
'modules' => [
|
||||||
|
'dbbackup',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'OTH_BACKUP_',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'stats' => [
|
||||||
|
'modules' => [
|
||||||
|
'stats',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'STAT',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'import-generic' => [
|
||||||
|
'modules' => [
|
||||||
|
'products',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'IMPRT',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'import_automatic' => [
|
||||||
|
'modules' => [
|
||||||
|
'automatic_import',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'IMPRT',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'import-xml_feed' => [
|
||||||
|
'modules' => [
|
||||||
|
'products',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'IMPRT',
|
||||||
|
],
|
||||||
|
'superadmin' => true,
|
||||||
|
],
|
||||||
|
'import-xml_feed_new' => [
|
||||||
|
'modules' => [
|
||||||
|
'products',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'IMPRT',
|
||||||
|
],
|
||||||
|
// 'superadmin' => true,
|
||||||
|
],
|
||||||
|
'orderPayment' => [
|
||||||
|
'modules' => [
|
||||||
|
'order_payment',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'ORDER_PAYMENT',
|
||||||
|
'POS_',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'admins' => [
|
||||||
|
'modules' => [
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'OTH_ADM_',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'settings' => [
|
||||||
|
'modules' => [
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'OTH_SET_',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'delivery_type' => [
|
||||||
|
'modules' => [
|
||||||
|
'eshop_delivery',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'DELVR',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'deliveryDelivery' => [
|
||||||
|
'modules' => [
|
||||||
|
'eshop_delivery',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'DELVR',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'deliveryPayment' => [
|
||||||
|
'modules' => [
|
||||||
|
'eshop_delivery',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'DELVR',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'vats' => [
|
||||||
|
'modules' => [
|
||||||
|
'products',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'VAT',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'priceLevels' => [
|
||||||
|
'modules' => [
|
||||||
|
'price_levels',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'PRICELEVELS',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'currencies' => [
|
||||||
|
'modules' => [
|
||||||
|
'currencies',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'CURRENCY',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'automatic_import' => [
|
||||||
|
'modules' => [
|
||||||
|
'automatic_import',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'IMPRT',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'export_orders' => [
|
||||||
|
'modules' => [
|
||||||
|
'orders',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'EXPRT',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'export_products' => [
|
||||||
|
'modules' => [
|
||||||
|
'export',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'EXPRT',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'export_selling_products' => [
|
||||||
|
'modules' => [
|
||||||
|
'orders',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'EXPRT',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'export_users' => [
|
||||||
|
'modules' => [
|
||||||
|
'eshop_users',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'EXPRT',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'ordersOfSuppliers' => [
|
||||||
|
'modules' => [
|
||||||
|
'orders_of_suppliers',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'INSTORE_STOCKIN',
|
||||||
|
],
|
||||||
|
// 'superadmin' => true,
|
||||||
|
],
|
||||||
|
'replacement' => [
|
||||||
|
'modules' => [
|
||||||
|
'replacement',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'ORDER_',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'templates' => [
|
||||||
|
'modules' => [
|
||||||
|
'templates',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'PROD_',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'templatesCategories' => [
|
||||||
|
'modules' => [
|
||||||
|
'templates',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'PROD_',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'templatesProducts' => [
|
||||||
|
'modules' => [
|
||||||
|
'templates',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'PROD_',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'pos' => [
|
||||||
|
'rights' => [
|
||||||
|
'POS_',
|
||||||
|
],
|
||||||
|
'modules' => [
|
||||||
|
'new_pos',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'old_pos' => [
|
||||||
|
'rights' => [
|
||||||
|
'POS_',
|
||||||
|
],
|
||||||
|
'modules' => [
|
||||||
|
'pos',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'usersGroups' => [
|
||||||
|
'modules' => [
|
||||||
|
'eshop_users',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'USER_GROUPS',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'cleaning' => [
|
||||||
|
'superadmin' => true,
|
||||||
|
],
|
||||||
|
'htmlComponents' => [
|
||||||
|
'superadmin' => true,
|
||||||
|
],
|
||||||
|
'languageCheckAdmin' => [
|
||||||
|
'superadmin' => true,
|
||||||
|
],
|
||||||
|
'balikonos' => [
|
||||||
|
'rights' => [
|
||||||
|
'ORDER_',
|
||||||
|
],
|
||||||
|
'modules' => [
|
||||||
|
'balikonos',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'balikobot' => [
|
||||||
|
'rights' => [
|
||||||
|
'BALIKOBOT',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'BalikonosOrders' => [
|
||||||
|
'rights' => [
|
||||||
|
'ORDER_',
|
||||||
|
],
|
||||||
|
'modules' => [
|
||||||
|
'balikonos',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'restrictions' => [
|
||||||
|
'rights' => [
|
||||||
|
'RESTR',
|
||||||
|
],
|
||||||
|
'modules' => [
|
||||||
|
'restrictions',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'reviews' => [
|
||||||
|
'rights' => [
|
||||||
|
'REVIEWS',
|
||||||
|
],
|
||||||
|
'modules' => [
|
||||||
|
'reviews',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'sellers' => [
|
||||||
|
'rights' => [
|
||||||
|
'SELLERS',
|
||||||
|
],
|
||||||
|
'modules' => [
|
||||||
|
'sellers',
|
||||||
|
'sellers_old',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'margins' => [
|
||||||
|
'rights' => [
|
||||||
|
'MARGINS',
|
||||||
|
],
|
||||||
|
'modules' => [
|
||||||
|
'margins',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'preOrders' => [
|
||||||
|
'rights' => [
|
||||||
|
'ORDER_',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'emails' => [
|
||||||
|
'modules' => [
|
||||||
|
'orders',
|
||||||
|
'forms',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'OTH_EMAILS_',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'fulltext' => [
|
||||||
|
'modules' => [
|
||||||
|
'eshop_search',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'FULLTEXT_SEARCH',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'translate' => [
|
||||||
|
'rights' => [
|
||||||
|
'TRANSLATE_',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'translationsStats' => [
|
||||||
|
'rights' => [
|
||||||
|
'TRANSLATE_',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'countries' => [
|
||||||
|
'rights' => [
|
||||||
|
'COUNTRY',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'languages' => [
|
||||||
|
'superadmin' => true,
|
||||||
|
'rights' => [
|
||||||
|
'LANGUAGE',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'feeds' => [
|
||||||
|
'modules' => [
|
||||||
|
'feeds',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'FEEDS',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'pricelist' => [
|
||||||
|
'rights' => [
|
||||||
|
'PRICELISTS',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'invoices' => [
|
||||||
|
'modules' => [
|
||||||
|
'invoices',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'ORDER_INVOICE', // fakturovat objednavky
|
||||||
|
'INVOICE', // spravovat fakturacni rady
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'LlmPrompt' => [
|
||||||
|
'modules' => [
|
||||||
|
'llm',
|
||||||
|
],
|
||||||
|
'rights' => [
|
||||||
|
'LLM_',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
735
admin/class/class.Window.php
Normal file
735
admin/class/class.Window.php
Normal file
@@ -0,0 +1,735 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Types\Type;
|
||||||
|
use KupShop\AdminBundle\Admin\Actions\ActionsLocator;
|
||||||
|
use KupShop\AdminBundle\Event\WindowTabsEvent;
|
||||||
|
use KupShop\AdminBundle\Util\ActivityLog;
|
||||||
|
use KupShop\AdminBundle\Util\WindowTabLocator;
|
||||||
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||||
|
use KupShop\KupShopBundle\Util\Logging\SentryLogger;
|
||||||
|
use Query\Operator;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
|
|
||||||
|
class Window extends Frame
|
||||||
|
{
|
||||||
|
use DatabaseCommunication;
|
||||||
|
|
||||||
|
public const RIGHT_DELETE = 'delete';
|
||||||
|
public const RIGHT_DUPLICATE = 'duplicate';
|
||||||
|
public const RIGHT_SAVE = 'save';
|
||||||
|
|
||||||
|
protected $nameField = 'name';
|
||||||
|
|
||||||
|
protected $fields = [];
|
||||||
|
protected $defaults = [];
|
||||||
|
protected $required = [];
|
||||||
|
protected $types = [];
|
||||||
|
protected $uniques;
|
||||||
|
protected $tableName;
|
||||||
|
|
||||||
|
// Type of item to display on web
|
||||||
|
protected $show_on_web;
|
||||||
|
|
||||||
|
protected $action;
|
||||||
|
protected $ID;
|
||||||
|
protected $type;
|
||||||
|
|
||||||
|
protected $tabs;
|
||||||
|
protected $custom_data;
|
||||||
|
|
||||||
|
protected $processedData;
|
||||||
|
|
||||||
|
public function getTemplate()
|
||||||
|
{
|
||||||
|
if (empty($this->template)) {
|
||||||
|
$name = lcfirst($this->getClassName());
|
||||||
|
|
||||||
|
return "window/{$name}.tpl";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->template;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createSQLFields($tablename)
|
||||||
|
{
|
||||||
|
$defaults = [];
|
||||||
|
$required = [];
|
||||||
|
$fields = [];
|
||||||
|
$types = [];
|
||||||
|
|
||||||
|
$conn = $this->getDbalConnection();
|
||||||
|
$tm = $conn->getSchemaManager();
|
||||||
|
|
||||||
|
$columns = $tm->listTableColumns($tablename);
|
||||||
|
foreach ($columns as $column) {
|
||||||
|
$name = $column->getName();
|
||||||
|
$fields[] = $name;
|
||||||
|
$defaults[$name] = $column->getDefault();
|
||||||
|
$required[$name] = ($column->getNotNull() && is_null($defaults[$name]));
|
||||||
|
$types[$name] = $column->getType()->getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->defaults = array_merge($defaults, $this->defaults);
|
||||||
|
$this->required = array_merge($required, $this->required);
|
||||||
|
$this->fields = array_merge($fields, $this->fields);
|
||||||
|
$this->types = array_merge($types, $this->types);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function collectVariables()
|
||||||
|
{
|
||||||
|
$acn = $this->getAction();
|
||||||
|
|
||||||
|
if ($acn == 'erased') {
|
||||||
|
return self::get_vars();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->get_vars();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_vars()
|
||||||
|
{
|
||||||
|
$vars = parent::get_vars();
|
||||||
|
|
||||||
|
$acn = $this->getAction();
|
||||||
|
|
||||||
|
$pageVars = [
|
||||||
|
'acn' => $acn,
|
||||||
|
];
|
||||||
|
|
||||||
|
$ID = $this->getID();
|
||||||
|
|
||||||
|
if (($acn == 'edit' && !empty($ID)) || $acn == 'add') {
|
||||||
|
if ($acn == 'edit' || ($acn == 'add' && $this->isDuplicate() && !empty($ID))) {
|
||||||
|
$pageVars['data'] = $this->getObject();
|
||||||
|
|
||||||
|
if (getVal('Submit')) {
|
||||||
|
$data = $this->getProcessedData();
|
||||||
|
$pageVars['data'] = array_merge($pageVars['data'], $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($this->isDuplicate())) {
|
||||||
|
$this->getFields();
|
||||||
|
$this->duplicateObject($pageVars['data']);
|
||||||
|
$pageVars['duplicate'] = true;
|
||||||
|
}
|
||||||
|
} elseif ($acn == 'add') {
|
||||||
|
$pageVars['data'] = $this->createObject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$vars['type'] = $this->getType();
|
||||||
|
|
||||||
|
$flap = getVal('flap', null, 1);
|
||||||
|
$vars['header']['flap'] = empty($flap) ? 1 : $flap;
|
||||||
|
$vars['header']['flap_next'] = getVal('flap_next');
|
||||||
|
$vars['header']['force_resize'] = getVal('force_resize');
|
||||||
|
|
||||||
|
$vars['tabs'] = $this->getTabs();
|
||||||
|
|
||||||
|
$vars['body'] = $pageVars;
|
||||||
|
|
||||||
|
$vars['actionsLocator'] = ServiceContainer::getService(ActionsLocator::class);
|
||||||
|
|
||||||
|
return $vars;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getType()
|
||||||
|
{
|
||||||
|
if (empty($this->type)) {
|
||||||
|
$type = getVal('s');
|
||||||
|
if (!$type) {
|
||||||
|
$type = lcfirst($this->getClassName());
|
||||||
|
} else {
|
||||||
|
$type = substr($type, 0, -4);
|
||||||
|
}
|
||||||
|
$this->type = $type;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setType($type)
|
||||||
|
{
|
||||||
|
$this->type = $type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function translateType()
|
||||||
|
{
|
||||||
|
// try to translate type to czech/english
|
||||||
|
$type = $this->getType();
|
||||||
|
|
||||||
|
// preferred:
|
||||||
|
// e.g. $txt_str['deliveryPriceLists']['navigation'] = 'Ceníky dopravy'
|
||||||
|
if ($typeName = translate('navigation', $type, true)) {
|
||||||
|
return $typeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// e.g. $txt_str['navigation']['deliveryDelivery'] = 'Dopravy'
|
||||||
|
if ($typeName = translate($type, 'navigation', true)) {
|
||||||
|
return $typeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $type;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getFields()
|
||||||
|
{
|
||||||
|
if (empty($this->fields)) {
|
||||||
|
$this->createSQLFields($this->getTableName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getUniques($table = null)
|
||||||
|
{
|
||||||
|
if (!is_null($this->uniques)) {
|
||||||
|
return $this->uniques;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($table)) {
|
||||||
|
$table = $this->getTableName();
|
||||||
|
}
|
||||||
|
|
||||||
|
$conn = $this->getDbalConnection();
|
||||||
|
$tm = $conn->getSchemaManager();
|
||||||
|
|
||||||
|
$indexes = $tm->listTableIndexes($table);
|
||||||
|
|
||||||
|
$this->uniques = [$this->nameField => true];
|
||||||
|
foreach ($indexes as $index) {
|
||||||
|
if ($index->isUnique() == true && $index->getName() != 'PRIMARY') {
|
||||||
|
if (isset($index->getColumns()[1])) {
|
||||||
|
$this->uniques[$index->getColumns()[1]] = true;
|
||||||
|
} else {
|
||||||
|
$this->uniques[$index->getName()] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->uniques;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getData()
|
||||||
|
{
|
||||||
|
$data = getVal('data', null, []);
|
||||||
|
|
||||||
|
if (!empty($data)) {
|
||||||
|
$data['ID'] = getVal('ID');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Process all POSTed data from form. Transform data to SQL fields array */
|
||||||
|
public function processFormData()
|
||||||
|
{
|
||||||
|
return $this->getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function getProcessedData()
|
||||||
|
{
|
||||||
|
if (isset($this->processedData)) {
|
||||||
|
return $this->processedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->processedData = $this->processFormData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setCustomData($data)
|
||||||
|
{
|
||||||
|
$this->updateSQL($this->getTableName(), [
|
||||||
|
'data' => empty($data) ? null : json_encode($data),
|
||||||
|
], ['id' => $this->getID()]);
|
||||||
|
|
||||||
|
// reset custom data cache
|
||||||
|
$this->custom_data = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCustomData()
|
||||||
|
{
|
||||||
|
if (empty($this->custom_data)) {
|
||||||
|
$object = $this->getObject();
|
||||||
|
$this->unserializeCustomData($object);
|
||||||
|
$this->custom_data = $object['data'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->custom_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTableName()
|
||||||
|
{
|
||||||
|
if (empty($this->tableName)) {
|
||||||
|
$this->tableName = strtolower($this->getClassName());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->tableName;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function duplicateObject(&$data)
|
||||||
|
{
|
||||||
|
$uniques = $this->getUniques();
|
||||||
|
foreach ($uniques as $key => $value) {
|
||||||
|
if (isset($data[$key])) {
|
||||||
|
if ($this->required[$key] == false) {
|
||||||
|
$data[$key] = null;
|
||||||
|
} else {
|
||||||
|
$data[$key] = stringCopy(trim($data[$key]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function createObject()
|
||||||
|
{
|
||||||
|
$data = $this->getData();
|
||||||
|
|
||||||
|
return array_merge($this->defaults, $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getObject()
|
||||||
|
{
|
||||||
|
$object = $this->fetchObject($this->getTableName(), $this->getID());
|
||||||
|
if (!$object && $this->getAction() !== 'add') {
|
||||||
|
$errStr = sprintf(translate('errorNotFound', 'base'), $this->translateType(), $this->getID());
|
||||||
|
throw new NotFoundHttpException($errStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getObjectData()
|
||||||
|
{
|
||||||
|
return $this->getObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vypisovani aktivit
|
||||||
|
protected function activityMessage($name, array $additionalData = [])
|
||||||
|
{
|
||||||
|
$acn = $this->getAction();
|
||||||
|
if ($acn == 'add') {
|
||||||
|
addActivityLog(ActivityLog::SEVERITY_NOTICE, ActivityLog::TYPE_CHANGE, sprintf(translate('activityAdded'), $name),
|
||||||
|
[
|
||||||
|
...ActivityLog::addObjectData([$this->getID() => $name], $this->getType()),
|
||||||
|
...$additionalData,
|
||||||
|
]);
|
||||||
|
} elseif ($acn == 'edit') {
|
||||||
|
addActivityLog(ActivityLog::SEVERITY_NOTICE, ActivityLog::TYPE_CHANGE, sprintf(translate('activityEdited'), $name),
|
||||||
|
[
|
||||||
|
...ActivityLog::addObjectData([$this->getID() => $name], $this->getType()),
|
||||||
|
...$additionalData,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getAdditionalActivityData(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$acn = $this->getAction();
|
||||||
|
$ID = $this->getID();
|
||||||
|
|
||||||
|
if ($acn == 'add') {
|
||||||
|
$this->tryRights('ADD');
|
||||||
|
}
|
||||||
|
if ($acn == 'edit') {
|
||||||
|
$this->tryRights('EDIT');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((($acn == 'edit' && (strlen($ID) > 0)) || $acn == 'add') && getVal('Submit')) {
|
||||||
|
$data = $this->getProcessedData();
|
||||||
|
$missing = $this->checkRequired($data);
|
||||||
|
if (!$missing) {
|
||||||
|
$activityAdditionalData = $this->getAdditionalActivityData();
|
||||||
|
$SQL = $this->handleUpdate();
|
||||||
|
if ($SQL) {
|
||||||
|
if ((empty($this->getErrors()) && empty($this->getHTMLErrors())) || $acn == 'add') {
|
||||||
|
if (isset($data[$this->nameField])) {
|
||||||
|
$this->activityMessage($data[$this->nameField], $activityAdditionalData);
|
||||||
|
}
|
||||||
|
$this->returnOK();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$ErrStr = getTextString('status', 'scripterror');
|
||||||
|
$this->returnError($ErrStr);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$ErrStr = getTextString('base', 'errorNotAllValid');
|
||||||
|
$ErrStr .= join(',', $missing);
|
||||||
|
$this->addError($ErrStr);
|
||||||
|
}
|
||||||
|
} elseif ($acn == 'erase' && !empty($ID)) {
|
||||||
|
$this->tryRights('ERASE');
|
||||||
|
$this->handleDelete();
|
||||||
|
} else {
|
||||||
|
$this->handleTabs();
|
||||||
|
parent::handle();
|
||||||
|
}
|
||||||
|
} catch (Doctrine\DBAL\DBALException $e) {
|
||||||
|
$this->handleException($e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleException($e)
|
||||||
|
{
|
||||||
|
if (intval($e->getPrevious()->errorInfo[1]) === 1062) {
|
||||||
|
$ErrStr = 'Duplicitní ';
|
||||||
|
$badFields = $this->getBadValues($this->getTableName(), ['id' => $this->ID]);
|
||||||
|
foreach ($badFields as $value) {
|
||||||
|
$ErrStr .= '{'.$value.'} ';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$badFields) {
|
||||||
|
$ErrStr = "Duplicitní záznam: \n".$e->getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->addError($ErrStr);
|
||||||
|
} elseif (intval($e->getPrevious()->getCode()) === 45000) {
|
||||||
|
$msg = $e->getPrevious()->getMessage();
|
||||||
|
$this->addError(mb_substr($msg, mb_strpos($msg, 'EAN')));
|
||||||
|
} elseif (in_array(intval($e->getPrevious()->getErrorCode()), [1205, 1213])) {
|
||||||
|
$this->addError('Chyba při zpracování požadavku. Zkuste to prosím znovu.');
|
||||||
|
$sentryLogger = ServiceContainer::getService(SentryLogger::class);
|
||||||
|
$data = json_encode($this->getAllSQLProcesses());
|
||||||
|
$sentryLogger->captureException(new Exception('Deadlock v administraci!', 1205, $e), ['extra' => ['processes' => $data]]);
|
||||||
|
} else {
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kontroluje, jestli v datech z formulare jsou vsechny povinne polozky
|
||||||
|
public function checkRequired($data)
|
||||||
|
{
|
||||||
|
$this->getFields();
|
||||||
|
$required = [];
|
||||||
|
foreach ($data as $key => $value) {
|
||||||
|
if (!is_array($value)) {
|
||||||
|
$value = trim($value);
|
||||||
|
}
|
||||||
|
if (isset($this->required[$key])
|
||||||
|
&& $this->required[$key] == true
|
||||||
|
&& $value === ''
|
||||||
|
&& ((@$this->types[$key] != 'string' && @$this->types[$key] != 'simple_array' && @$this->types[$key] != 'text') || $key == $this->nameField)
|
||||||
|
) {
|
||||||
|
$required[] = $key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $required;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obecna funkce pro update & insert
|
||||||
|
public function handleUpdate()
|
||||||
|
{
|
||||||
|
$acn = $this->getAction();
|
||||||
|
$SQL = null;
|
||||||
|
|
||||||
|
if ($acn == 'add') {
|
||||||
|
$sqlFields = $this->getSQLFields();
|
||||||
|
$this->insertSQL($this->getTableName(), $sqlFields);
|
||||||
|
$SQL = true;
|
||||||
|
if (empty($ID)) {
|
||||||
|
if (isset($sqlFields['id'])) {
|
||||||
|
$this->setID($sqlFields['id']);
|
||||||
|
} else {
|
||||||
|
$this->setID(sqlInsertID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} elseif ($acn == 'edit') {
|
||||||
|
$sqlFields = $this->getSQLFields();
|
||||||
|
$this->updateSQL($this->getTableName(), $sqlFields, ['id' => $this->getID()]);
|
||||||
|
|
||||||
|
if (isset($sqlFields['id'])) {
|
||||||
|
$this->setID($sqlFields['id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$SQL = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset custom data cache
|
||||||
|
$this->custom_data = null;
|
||||||
|
|
||||||
|
$this->handleTabs(true);
|
||||||
|
|
||||||
|
return $SQL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function forceUpdate()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// get actual action
|
||||||
|
$action = $this->getAction();
|
||||||
|
|
||||||
|
// change action to edit
|
||||||
|
$this->action = 'edit';
|
||||||
|
// do update
|
||||||
|
$_REQUEST['Submit'] = 'OK';
|
||||||
|
$this->createSQLFields($this->getTableName());
|
||||||
|
$result = $this->handleUpdate();
|
||||||
|
// return action
|
||||||
|
$this->action = $action;
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
} catch (Doctrine\DBAL\DBALException $e) {
|
||||||
|
$this->handleException($e);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIdFromDatabase($field)
|
||||||
|
{
|
||||||
|
$id = returnSQLResult('SELECT id FROM '.getTableName($this->getTableName())." WHERE {$field[0]}='{$field[1]}' ");
|
||||||
|
|
||||||
|
return $id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSQLFields($data = null, $fields = null, $defaults = null, $types = null)
|
||||||
|
{
|
||||||
|
if ($data == null) {
|
||||||
|
$data = $this->getProcessedData();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($fields == null) {
|
||||||
|
$fields = $this->fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($defaults == null) {
|
||||||
|
$defaults = $this->defaults;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($types == null) {
|
||||||
|
$types = $this->types;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sqlField = [];
|
||||||
|
foreach ($fields as $row) {
|
||||||
|
if (array_key_exists($row, $data) && !is_array($data[$row])) {
|
||||||
|
if (!is_null($data[$row])) {
|
||||||
|
$data[$row] = trim($data[$row]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists($row, $types)) {
|
||||||
|
$type = $types[$row];
|
||||||
|
if (($type == Type::DECIMAL) || ($type == Type::FLOAT)) {
|
||||||
|
$this->preparePrice($data[$row]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($data[$row]) && ($data[$row] === '') && (@$defaults[$row] === null) && @!$this->required[$row]) {
|
||||||
|
$sqlField[$row] = null;
|
||||||
|
} else {
|
||||||
|
$sqlField[$row] = $data[$row];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $sqlField;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Smazani polozky
|
||||||
|
public function handleDelete()
|
||||||
|
{
|
||||||
|
if ($this->nameField) {
|
||||||
|
$name = sqlQueryBuilder()->select($this->nameField)->from($this->getTableName())
|
||||||
|
->andWhere(Operator::equals(['id' => $this->getID()]))
|
||||||
|
->execute()->fetchOne();
|
||||||
|
if ($logMessage = translate('activityDeleted', $this->getType(), true)) {
|
||||||
|
$logMessage = sprintf($logMessage, $name);
|
||||||
|
} else {
|
||||||
|
$logMessage = translate('activityDeleted', 'status'); // 'Deleted %s: %s'
|
||||||
|
$logMessage = sprintf($logMessage, $this->getType(), $name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$res = sqlQueryBuilder()->delete($this->getTableName())
|
||||||
|
->andWhere(Operator::equals(['id' => $this->getID()]))
|
||||||
|
->execute();
|
||||||
|
if ($res && !empty($logMessage)) {
|
||||||
|
addActivityLog(ActivityLog::SEVERITY_WARNING, ActivityLog::TYPE_CHANGE, $logMessage);
|
||||||
|
}
|
||||||
|
} catch (Doctrine\DBAL\DBALException $e) {
|
||||||
|
switch (intval($e->getPrevious()->errorInfo[1])) {
|
||||||
|
case 1451:
|
||||||
|
$ErrStr = 'Tento objekt je použit a nelze ho smazat.';
|
||||||
|
$this->returnError($ErrStr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
$this->handleException($e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \KupShop\KupShopBundle\Exception\RedirectException("launch.php?s={$this->getName()}.php&acn=erased");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasRights($name = null)
|
||||||
|
{
|
||||||
|
switch ($name) {
|
||||||
|
case self::RIGHT_DUPLICATE:
|
||||||
|
if ($this->getAction() == 'edit' && $this->getID() != null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case self::RIGHT_SAVE:
|
||||||
|
// Kdyz mam READ a nemam EDIT, tak nezobrazim save button
|
||||||
|
if (UserRights::hasRights($this->getRightsType(), 'READ') && !UserRights::hasRights($this->getRightsType(), 'EDIT')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getBadValues($table = null, $rowIdentifier = [])
|
||||||
|
{
|
||||||
|
if (!empty($table)) {
|
||||||
|
$uniques = $this->getUniques($table);
|
||||||
|
} else {
|
||||||
|
$table = $this->getTableName();
|
||||||
|
$uniques = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$where = '';
|
||||||
|
foreach ($rowIdentifier as $key => $value) {
|
||||||
|
$where .= " AND {$key}!=:{$key}";
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $this->getData();
|
||||||
|
$badFields = [];
|
||||||
|
foreach ($uniques as $key => $value) {
|
||||||
|
if ($value) {
|
||||||
|
if (isset($data[$key])) {
|
||||||
|
$SQL = returnSQLResult('SELECT COUNT(*) FROM '.getTableName($table)." WHERE {$key}=:{$key} {$where}",
|
||||||
|
array_merge($data, $rowIdentifier));
|
||||||
|
if ($SQL > 0) {
|
||||||
|
$badFields[] = $key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $badFields;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function redirect($params = [])
|
||||||
|
{
|
||||||
|
parent::redirect(array_merge(['ID' => $this->getID(), 'acn' => 'edit'], $params));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getShowOnWeb()
|
||||||
|
{
|
||||||
|
if ($this->show_on_web == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->getID() === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ['type' => $this->show_on_web, 'id' => $this->getID()];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getNameField()
|
||||||
|
{
|
||||||
|
return $this->nameField;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleTabs($update = false)
|
||||||
|
{
|
||||||
|
$tabs = $this->getTabs();
|
||||||
|
foreach ($tabs as $tab) {
|
||||||
|
$tab->setID($this->getID());
|
||||||
|
|
||||||
|
if ($update) {
|
||||||
|
$tab->handleUpdate();
|
||||||
|
// reset custom data cache
|
||||||
|
$this->custom_data = null;
|
||||||
|
} else {
|
||||||
|
$tab->handle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return WindowTabs.
|
||||||
|
*/
|
||||||
|
protected function getTabs()
|
||||||
|
{
|
||||||
|
if (!is_null($this->tabs)) {
|
||||||
|
return $this->tabs;
|
||||||
|
}
|
||||||
|
|
||||||
|
$windowTabLocator = ServiceContainer::getService(WindowTabLocator::class, 0);
|
||||||
|
|
||||||
|
$dispatcher = ServiceContainer::getService('event_dispatcher');
|
||||||
|
$tabsEvent = new WindowTabsEvent();
|
||||||
|
$dispatcher->dispatch($tabsEvent, WindowTabsEvent::NAME_PREFIX.$this->getType());
|
||||||
|
|
||||||
|
$tabs = array_merge(
|
||||||
|
$windowTabLocator ? $windowTabLocator->getTabs($this->getType()) : [],
|
||||||
|
$tabsEvent->getTabs()
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($tabs as &$tab) {
|
||||||
|
$tab->setWindow($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->tabs = $tabs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleGetActionSnippet()
|
||||||
|
{
|
||||||
|
$actionName = getVal('action');
|
||||||
|
/** @var $massActionsLocator ActionsLocator */
|
||||||
|
$actionsLocator = ServiceContainer::getService(ActionsLocator::class);
|
||||||
|
$action = $actionsLocator->getServiceByActionClassName($actionName);
|
||||||
|
$smarty = createSmarty(true, true);
|
||||||
|
$smarty->assign($action->getVars());
|
||||||
|
$smarty->display($action->getTemplate());
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleExecuteAction()
|
||||||
|
{
|
||||||
|
$actionName = getVal('action');
|
||||||
|
/** @var $massActionsLocator ActionsLocator */
|
||||||
|
$actionsLocator = ServiceContainer::getService(ActionsLocator::class);
|
||||||
|
$action = $actionsLocator->getServiceByActionClassName($actionName);
|
||||||
|
$action->setWindow($this);
|
||||||
|
$data = $this->getData();
|
||||||
|
$result = $action->execute($data, getVal('config', $_POST, []), $this->getType());
|
||||||
|
if ($result->isSuccessful()) {
|
||||||
|
if ($result->getHTMLMessage()) {
|
||||||
|
$this->action = 'edit';
|
||||||
|
$this->addHTMLError($result->getHTMLMessage());
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$params = ['action' => null];
|
||||||
|
if ($result->getRedirect()) {
|
||||||
|
$params = array_merge($params, $result->getRedirect());
|
||||||
|
}
|
||||||
|
$this->returnOK(!empty($result->getMsg()) ? $result->getMsg() : ('Akce ['.$action->getName().'] byla provedena.'),
|
||||||
|
false,
|
||||||
|
$params);
|
||||||
|
} else {
|
||||||
|
$this->redirect(['acn' => 'edit',
|
||||||
|
'action' => null,
|
||||||
|
'ErrStr' => !empty($result->getMsg()) ? $result->getMsg() : ('Akce ['.$action->getName().'] se nezdařila.')]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getAllSQLProcesses()
|
||||||
|
{
|
||||||
|
return sqlQuery('SHOW FULL PROCESSLIST')->fetchAllAssociative();
|
||||||
|
}
|
||||||
|
}
|
||||||
22
admin/class/smarty_plugins/function.find_module.php
Normal file
22
admin/class/smarty_plugins/function.find_module.php
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty plugin.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty {find_module} plugin.
|
||||||
|
*
|
||||||
|
* Type: function<br>
|
||||||
|
* Name: url<br>
|
||||||
|
* Purpose: finding module
|
||||||
|
*
|
||||||
|
* @param array $params parameters
|
||||||
|
* @param Smarty_Internal_Template $smarty
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function smarty_function_find_module($params, &$smarty)
|
||||||
|
{
|
||||||
|
return findModule($params['name']);
|
||||||
|
}
|
||||||
29
admin/class/smarty_plugins/function.find_right.php
Normal file
29
admin/class/smarty_plugins/function.find_right.php
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty plugin.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty {find_right} plugin.
|
||||||
|
*
|
||||||
|
* Type: function<br>
|
||||||
|
* Name: url<br>
|
||||||
|
* Purpose: finding rights
|
||||||
|
*
|
||||||
|
* @param array $params parameters
|
||||||
|
* @param Smarty_Internal_Template $smarty
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function smarty_function_find_right($params, &$smarty)
|
||||||
|
{
|
||||||
|
$var = null;
|
||||||
|
$name = '';
|
||||||
|
extract($params);
|
||||||
|
if (empty($name)) {
|
||||||
|
throw new InvalidArgumentException('find_right: \'name\' parameter empty');
|
||||||
|
}
|
||||||
|
|
||||||
|
return findRight($name, $var);
|
||||||
|
}
|
||||||
27
admin/class/smarty_plugins/function.get_named_vats.php
Normal file
27
admin/class/smarty_plugins/function.get_named_vats.php
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||||
|
use KupShop\OrderingBundle\Util\Order\OrderInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty plugin.
|
||||||
|
*/
|
||||||
|
function smarty_function_get_named_vats($params, &$smarty)
|
||||||
|
{
|
||||||
|
if (!isset($params['vats'])) {
|
||||||
|
throw new InvalidArgumentException('Parameter \'vats\' is required!');
|
||||||
|
}
|
||||||
|
if (!is_array($params['vats'])) {
|
||||||
|
throw new InvalidArgumentException('Parameter \'vats\' must be of type array!');
|
||||||
|
}
|
||||||
|
|
||||||
|
$orderInfo = ServiceContainer::getService(OrderInfo::class);
|
||||||
|
|
||||||
|
$namedVats = $orderInfo->getNamedVats($params['vats']);
|
||||||
|
|
||||||
|
if (!empty($params['assign'])) {
|
||||||
|
$smarty->assign($params['assign'], $namedVats);
|
||||||
|
} else {
|
||||||
|
return $namedVats;
|
||||||
|
}
|
||||||
|
}
|
||||||
28
admin/class/smarty_plugins/function.get_statuses.php
Normal file
28
admin/class/smarty_plugins/function.get_statuses.php
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty plugin.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty {get_statuses} plugin.
|
||||||
|
*
|
||||||
|
* Type: function<br>
|
||||||
|
* Name: url<br>
|
||||||
|
* Purpose: get statuses
|
||||||
|
*
|
||||||
|
* @param array $params parameters
|
||||||
|
* @param Smarty_Internal_Template $smarty
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function smarty_function_get_statuses($params, &$smarty)
|
||||||
|
{
|
||||||
|
$statuses = getStatuses($params['name']);
|
||||||
|
|
||||||
|
if (!empty($params['assign'])) {
|
||||||
|
$smarty->assign($params['assign'], $statuses);
|
||||||
|
} else {
|
||||||
|
return $statuses;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty plugin.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty {get_statuses} plugin.
|
||||||
|
*
|
||||||
|
* Type: function<br>
|
||||||
|
* Name: url<br>
|
||||||
|
* Purpose: get statuses
|
||||||
|
*
|
||||||
|
* @param array $params parameters
|
||||||
|
* @param Smarty_Internal_Template $smarty
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function smarty_function_get_today_selled_items($params, &$smarty)
|
||||||
|
{
|
||||||
|
$last_item = end($params['items']);
|
||||||
|
|
||||||
|
if (empty($last_item['date'])) {
|
||||||
|
return $params['items'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$last_datetime = (new DateTime($last_item['date']))->modify('-1 hours');
|
||||||
|
|
||||||
|
$items = [];
|
||||||
|
foreach ($params['items'] as $item) {
|
||||||
|
$datetime = new DateTime($item['date']);
|
||||||
|
if ($last_datetime < $datetime) {
|
||||||
|
$items[] = $item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($items)) {
|
||||||
|
return $params['items'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($params['assign'])) {
|
||||||
|
$smarty->assign($params['assign'], $items);
|
||||||
|
} else {
|
||||||
|
return $items;
|
||||||
|
}
|
||||||
|
}
|
||||||
23
admin/class/smarty_plugins/function.get_user.php
Normal file
23
admin/class/smarty_plugins/function.get_user.php
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty plugin.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty {get_user} plugin.
|
||||||
|
*
|
||||||
|
* Type: function<br>
|
||||||
|
* Name: get_user<br>
|
||||||
|
* Purpose: get User ID
|
||||||
|
*
|
||||||
|
* @return number
|
||||||
|
*/
|
||||||
|
function smarty_function_get_user($params, &$smarty)
|
||||||
|
{
|
||||||
|
if (!empty($GLOBALS['adminID'])) {
|
||||||
|
return $GLOBALS['adminID'];
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
function smarty_function_helpscout_beacon_identity()
|
||||||
|
{
|
||||||
|
$admin = getAdminUser();
|
||||||
|
|
||||||
|
return json_encode([
|
||||||
|
'name' => $admin['name'] ?? $admin['login'],
|
||||||
|
'email' => $admin['email'],
|
||||||
|
'company' => getShopUniqueName(),
|
||||||
|
'signature' => hash_hmac(
|
||||||
|
'sha256',
|
||||||
|
$admin['email'],
|
||||||
|
'MjodsaAdWfVlVXSiOnas0qgE7CQzbRrdjTEEXLR0RUY='
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
function smarty_function_insert_autocomplete_form($params, $smarty)
|
||||||
|
{
|
||||||
|
static $instance = 0;
|
||||||
|
|
||||||
|
$defaults = [
|
||||||
|
'instance' => $instance,
|
||||||
|
];
|
||||||
|
|
||||||
|
$params = array_merge($defaults, $params);
|
||||||
|
|
||||||
|
$requiredParams = ['type', 'searchInput', 'inputName', 'items'];
|
||||||
|
foreach ($requiredParams as $requiredParam) {
|
||||||
|
if (!array_key_exists($requiredParam, $params)) {
|
||||||
|
throw new InvalidArgumentException(
|
||||||
|
sprintf('Missing required parameter "%s"', $requiredParam)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo $smarty->_subTemplateRender('autocomplete-form/'.$params['type'].'.tpl', $smarty->cache_id, $smarty->compile_id, 0, null, $params, 0, false);
|
||||||
|
|
||||||
|
$instance++;
|
||||||
|
}
|
||||||
118
admin/class/smarty_plugins/function.insert_calendar.php
Normal file
118
admin/class/smarty_plugins/function.insert_calendar.php
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty plugin.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty {insert_calendar} plugin.
|
||||||
|
*
|
||||||
|
* Type: function<br>
|
||||||
|
* Name: url<br>
|
||||||
|
* Purpose: insert calendar to field
|
||||||
|
*
|
||||||
|
* @param array $params parameters
|
||||||
|
* @param Smarty_Internal_Template $template template object
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function smarty_function_insert_calendar($params, $template)
|
||||||
|
{
|
||||||
|
$selector = null;
|
||||||
|
$format = 'date';
|
||||||
|
$figureFormat = true;
|
||||||
|
$czechformat = '';
|
||||||
|
$used = false;
|
||||||
|
|
||||||
|
extract($params);
|
||||||
|
|
||||||
|
if (empty($selector)) {
|
||||||
|
throw new InvalidArgumentException('insert_calendar: \'selector\' parameter empty');
|
||||||
|
}
|
||||||
|
|
||||||
|
echo openCalenderButton($selector, $format, $figureFormat, $czechformat, $used);
|
||||||
|
}
|
||||||
|
|
||||||
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
|
||||||
|
function openCalenderButton($selector, $dateFormat, $figureFormat = true, $czechformat = null, $param_used = false)
|
||||||
|
{
|
||||||
|
global $cfg;
|
||||||
|
|
||||||
|
static $used = false;
|
||||||
|
|
||||||
|
$used = $used || $param_used;
|
||||||
|
|
||||||
|
/*$format = "dd-mm-yy";
|
||||||
|
$timeFormat = "";
|
||||||
|
|
||||||
|
if ($dateFormat == 'datetime')
|
||||||
|
$timeFormat = "hh:mm:ss";
|
||||||
|
*/
|
||||||
|
|
||||||
|
// if (!empty($czechformat)){
|
||||||
|
$format = calendarDateFormat();
|
||||||
|
$timeFormat = '';
|
||||||
|
if ($dateFormat == 'datetime') {
|
||||||
|
$timeFormat = calendarTimeFormat();
|
||||||
|
}
|
||||||
|
// }
|
||||||
|
|
||||||
|
$ret = "<script>
|
||||||
|
$(function(){
|
||||||
|
openCalenderIFrame('{$selector}', '{$format}', '{$timeFormat}');
|
||||||
|
});
|
||||||
|
</script>";
|
||||||
|
|
||||||
|
if (!$used) {
|
||||||
|
$used = true;
|
||||||
|
$ret .= '<script src="./static/js/jquery.datetimepicker.js"></script>';
|
||||||
|
$ret .= '<script src="./static/js/jquery-ui.datepicker-cs.js"></script>';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
function calendarDateFormat()
|
||||||
|
{
|
||||||
|
$dbcfg = Settings::getDefault();
|
||||||
|
|
||||||
|
switch ($dbcfg['date_format']) {
|
||||||
|
case '%e.%c.%y':
|
||||||
|
return 'd.m.y';
|
||||||
|
break;
|
||||||
|
case '%d.%m.%Y':
|
||||||
|
return 'dd.mm.yy';
|
||||||
|
break;
|
||||||
|
case '%d/%m/%Y':
|
||||||
|
return 'dd/mm/yy';
|
||||||
|
break;
|
||||||
|
case '%d/%m/%y':
|
||||||
|
return 'dd/mm/y';
|
||||||
|
break;
|
||||||
|
case '%e.%c.%Y':
|
||||||
|
default:
|
||||||
|
return 'd.m.yy';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function calendarTimeFormat()
|
||||||
|
{
|
||||||
|
$dbcfg = Settings::getDefault();
|
||||||
|
|
||||||
|
switch ($dbcfg['time_format']) {
|
||||||
|
case '%k:%i:%s':
|
||||||
|
return 'h:mm:ss';
|
||||||
|
break;
|
||||||
|
case '%H:%i':
|
||||||
|
return 'hh:mm';
|
||||||
|
break;
|
||||||
|
case '%k:%i':
|
||||||
|
return 'h:mm';
|
||||||
|
break;
|
||||||
|
case '%H:%i:%s':
|
||||||
|
default:
|
||||||
|
return 'hh:mm:ss';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
59
admin/class/smarty_plugins/function.insert_file_browse.php
Normal file
59
admin/class/smarty_plugins/function.insert_file_browse.php
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Smarty plugin.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty {insert_file_browse} plugin.
|
||||||
|
*
|
||||||
|
* Type: function<br>
|
||||||
|
* Name: url<br>
|
||||||
|
* Purpose: insert file browser
|
||||||
|
*
|
||||||
|
* @param array $params parameters
|
||||||
|
* @param Smarty_Internal_Template $template template object
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function smarty_function_insert_file_browse($params, $template)
|
||||||
|
{
|
||||||
|
static $inserted = false;
|
||||||
|
if (!$inserted) {
|
||||||
|
?>
|
||||||
|
<script src="/web/bundles/cksourceckfinder/ckfinder/ckfinder.js"></script>
|
||||||
|
<script type="application/javascript">
|
||||||
|
CKFinder.config({connectorPath: '/ckfinder/connector'});
|
||||||
|
CKFinder.basePath = '/web/bundles/cksourceckfinder/ckfinder/';
|
||||||
|
//############### BROWSE FILES #####################//
|
||||||
|
$(document).on('click', '[data-file-browse]', function () {
|
||||||
|
var $input = $(this).closest('.input-group').find('input');
|
||||||
|
if (!$input)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
CKFinder.popup({
|
||||||
|
language: 'cs',
|
||||||
|
resourceType: 'Soubory',
|
||||||
|
chooseFiles: true,
|
||||||
|
width: 800,
|
||||||
|
height: 600,
|
||||||
|
onInit: function (finder) {
|
||||||
|
finder.config.resourceType = 'Soubory';
|
||||||
|
finder.on('files:choose', function (evt) {
|
||||||
|
var file = evt.data.files.first();
|
||||||
|
$input.val(decodeURIComponent(file.getUrl()));
|
||||||
|
$input.change();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<?php
|
||||||
|
$inserted = true;
|
||||||
|
} ?>
|
||||||
|
<a class="btn btn-primary btn-sm" data-file-browse href="#" title="<?php echo getTextString('products', 'findFile'); ?>">
|
||||||
|
<span class="glyphicon glyphicon-folder-open"></span>
|
||||||
|
</a>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
45
admin/class/smarty_plugins/function.insert_llm_button.php
Normal file
45
admin/class/smarty_plugins/function.insert_llm_button.php
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty plugin.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty {insert_llm_button} plugin.
|
||||||
|
*
|
||||||
|
* Purpose: Insert llm button
|
||||||
|
*
|
||||||
|
* @param array $params parameters
|
||||||
|
* @param Smarty_Internal_Template $smarty template object
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function smarty_function_insert_llm_button($params, $smarty)
|
||||||
|
{
|
||||||
|
if (!findModule(Modules::LLM)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$textObjectUtil = \KupShop\KupShopBundle\Util\Compat\ServiceContainer::getService(\KupShop\LLMBundle\Util\TextObjectUtil::class);
|
||||||
|
|
||||||
|
$params['actions'] = [];
|
||||||
|
|
||||||
|
foreach ($textObjectUtil->getObjectLabelPrompts($params['type']) as $id => $prompt) {
|
||||||
|
$json = [
|
||||||
|
'entityType' => $params['entityType'] ?? substr(getVal('s'), 0, -4),
|
||||||
|
'entityId' => $params['entityId'] ?? getVal('ID'),
|
||||||
|
'target' => $params['target'],
|
||||||
|
'promptId' => $id,
|
||||||
|
'objectLabel' => $params['type'] ?? '',
|
||||||
|
'title' => $prompt->getTitle(),
|
||||||
|
];
|
||||||
|
|
||||||
|
$params['actions'][] = [
|
||||||
|
'id' => $id,
|
||||||
|
'title' => $prompt->getTitle(),
|
||||||
|
'json' => $json,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
echo $smarty->_subTemplateRender('llm/text-dropdown.tpl', $smarty->cache_id, $smarty->compile_id, 0, null, $params, 0, false);
|
||||||
|
}
|
||||||
37
admin/class/smarty_plugins/function.insert_wysiwyg.php
Normal file
37
admin/class/smarty_plugins/function.insert_wysiwyg.php
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty plugin.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty {insert_wysiwyg} plugin.
|
||||||
|
*
|
||||||
|
* Type: function<br>
|
||||||
|
* Name: url<br>
|
||||||
|
* Purpose: insert wysiwyg editor
|
||||||
|
*
|
||||||
|
* @param array $params parameters
|
||||||
|
* @param Smarty_Internal_Template $smarty template object
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function smarty_function_insert_wysiwyg($params, $smarty)
|
||||||
|
{
|
||||||
|
static $index = 0;
|
||||||
|
|
||||||
|
$defaults = [
|
||||||
|
'type' => 'BasicTable',
|
||||||
|
'index' => $index,
|
||||||
|
];
|
||||||
|
|
||||||
|
$params = array_merge($defaults, $params);
|
||||||
|
|
||||||
|
if (empty($params['target'])) {
|
||||||
|
throw new InvalidArgumentException('insert_wysiwyg: \'target\' parameter empty');
|
||||||
|
}
|
||||||
|
|
||||||
|
echo $smarty->_subTemplateRender('utils/wysiwyg.tpl', $smarty->cache_id, $smarty->compile_id, 0, null, $params, 0, false);
|
||||||
|
|
||||||
|
$index++;
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
function smarty_function_print_delivery_settings($params, &$smarty)
|
||||||
|
{
|
||||||
|
if (!empty($params['template'])) {
|
||||||
|
$_smarty_tpl_vars = $smarty->tpl_vars;
|
||||||
|
echo $smarty->_subTemplateRender($params['template'], $smarty->cache_id, $smarty->compile_id, 0, null, $params, 0, false);
|
||||||
|
$smarty->tpl_vars = $_smarty_tpl_vars;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($params['assign'])) {
|
||||||
|
$smarty->assign($params['assign'], $params);
|
||||||
|
}
|
||||||
|
}
|
||||||
52
admin/class/smarty_plugins/function.print_select.php
Normal file
52
admin/class/smarty_plugins/function.print_select.php
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Smarty plugin.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty {print_select} plugin.
|
||||||
|
*
|
||||||
|
* Type: function<br>
|
||||||
|
* Name: url<br>
|
||||||
|
* Purpose: print select
|
||||||
|
*
|
||||||
|
* @param array $params parameters
|
||||||
|
* @param Smarty_Internal_Template $smarty
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function smarty_function_print_select($params, &$smarty)
|
||||||
|
{
|
||||||
|
$name = '';
|
||||||
|
$var = [];
|
||||||
|
$selected = '';
|
||||||
|
$param = '';
|
||||||
|
$class = 'selecter';
|
||||||
|
$keep_value = false;
|
||||||
|
|
||||||
|
extract($params);
|
||||||
|
|
||||||
|
if (!is_array($selected)) {
|
||||||
|
$selected = [$selected => true];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($keep_value) {
|
||||||
|
foreach ($selected as $key => $value) {
|
||||||
|
if (!array_key_exists($key, $var)) {
|
||||||
|
$var[$key] = $key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} ?>
|
||||||
|
<select class="<?php echo $class; ?>" data-filter-type="<?php echo (strpos($param, 'multiple') !== false) ? 'multiselect' : 'select'; ?>" name="<?php echo $name; ?>" <?php echo $param; ?>>
|
||||||
|
<?php
|
||||||
|
foreach ($var as $index => $value) {
|
||||||
|
?>
|
||||||
|
<option value="<?php echo $index; ?>"
|
||||||
|
<?php echo (isset($selected[$index]) && ($selected[$index] || $selected[$index] == '0')) ? 'selected' : ''; ?>>
|
||||||
|
<?php echo $value; ?>
|
||||||
|
</option>
|
||||||
|
<?php
|
||||||
|
} ?>
|
||||||
|
</select>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
71
admin/class/smarty_plugins/function.print_toggle.php
Normal file
71
admin/class/smarty_plugins/function.print_toggle.php
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty plugin.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty {print_toggle} plugin.
|
||||||
|
*
|
||||||
|
* Type: function<br>
|
||||||
|
* Name: url<br>
|
||||||
|
* Purpose: print toggle with hidden button for get Y/N value
|
||||||
|
*
|
||||||
|
* @param array $params parameters
|
||||||
|
* @param Smarty_Internal_Template $smarty
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function smarty_function_print_toggle($params, &$smarty)
|
||||||
|
{
|
||||||
|
$name = null;
|
||||||
|
$nameRaw = null;
|
||||||
|
$disabled = null;
|
||||||
|
$class = '';
|
||||||
|
$attrs = '';
|
||||||
|
$value = null;
|
||||||
|
$numeric = false;
|
||||||
|
$onOff = false;
|
||||||
|
|
||||||
|
extract($params);
|
||||||
|
|
||||||
|
if (empty($name) && empty($nameRaw)) {
|
||||||
|
throw new InvalidArgumentException('print_toggle: \'name\' parameter empty');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_null($value)) {
|
||||||
|
$data = $smarty->getTemplateVars('body');
|
||||||
|
|
||||||
|
if (!empty($data['data'])) {
|
||||||
|
$data = $data['data'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$value = getVal($name, $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
$class .= ' toggle';
|
||||||
|
|
||||||
|
if ($disabled) {
|
||||||
|
$attrs .= ' disabled ';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($value == 'Y' || $value == '1') {
|
||||||
|
$attrs .= 'checked="checked" ';
|
||||||
|
}
|
||||||
|
|
||||||
|
$attrName = $name ? "data[{$name}]" : $nameRaw;
|
||||||
|
|
||||||
|
if ($onOff) {
|
||||||
|
$valueTrue = 'ON';
|
||||||
|
$valueFalse = 'OFF';
|
||||||
|
} else {
|
||||||
|
$valueTrue = $numeric ? 1 : 'Y';
|
||||||
|
$valueFalse = $numeric ? 0 : 'N';
|
||||||
|
}
|
||||||
|
|
||||||
|
$ret = "<input type='hidden' name='{$attrName}' value='{$valueFalse}'/>
|
||||||
|
<label class='{$class}'><input name='{$attrName}' type='checkbox' {$attrs} value='{$valueTrue}'/>
|
||||||
|
<span class=\"handle\"></span></label>";
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
19
admin/class/smarty_plugins/modifier.format_datee.php
Normal file
19
admin/class/smarty_plugins/modifier.format_datee.php
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty plugin.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty {format_date} function plugin.
|
||||||
|
*/
|
||||||
|
function smarty_modifier_format_date($string, $value = null)
|
||||||
|
{
|
||||||
|
if (empty($string)) {
|
||||||
|
return '';
|
||||||
|
} else {
|
||||||
|
$datetime = new DateTime($string);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $datetime->format(Settings::getDateFormat());
|
||||||
|
}
|
||||||
25
admin/class/smarty_plugins/modifier.format_datetime.php
Normal file
25
admin/class/smarty_plugins/modifier.format_datetime.php
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty plugin.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty {format_datetime} function plugin.
|
||||||
|
*/
|
||||||
|
function smarty_modifier_format_datetime($string, $value = null)
|
||||||
|
{
|
||||||
|
if ($string == '-0001-11-30') {
|
||||||
|
return '00-00-0000';
|
||||||
|
} elseif ($string instanceof \DateTime) {
|
||||||
|
$datetime = $string;
|
||||||
|
} elseif (empty($string)) {
|
||||||
|
return '';
|
||||||
|
} else {
|
||||||
|
$datetime = new DateTime($string);
|
||||||
|
}
|
||||||
|
|
||||||
|
$format = Settings::getDateFormat().' '.Settings::getTimeFormat();
|
||||||
|
|
||||||
|
return $datetime->format($format);
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty plugin.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty {format_editable_price} function plugin.
|
||||||
|
*
|
||||||
|
* @param Decimal $decimal - value to format
|
||||||
|
* @param null $precision - how many decimal places to use. Use negative numbers to pretty print rounded values (strip trailing zeros)
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function smarty_modifier_format_editable_price(Decimal $decimal, $precision = null)
|
||||||
|
{
|
||||||
|
return $decimal->printFloatValue($precision ?: 2);
|
||||||
|
}
|
||||||
549
admin/cleaning.php
Normal file
549
admin/cleaning.php
Normal file
@@ -0,0 +1,549 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use KupShop\AdminBundle\Util\Script\ScriptLocator;
|
||||||
|
use KupShop\CatalogBundle\Search\FulltextInterface;
|
||||||
|
use KupShop\KupShopBundle\Config;
|
||||||
|
use KupShop\KupShopBundle\Context\ContextManager;
|
||||||
|
use KupShop\KupShopBundle\Context\LanguageContext;
|
||||||
|
use KupShop\KupShopBundle\Event\CronEvent;
|
||||||
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||||
|
|
||||||
|
$main_class = 'Cleaning';
|
||||||
|
|
||||||
|
class Cleaning extends Window
|
||||||
|
{
|
||||||
|
public $success = 0;
|
||||||
|
public $failed = 0;
|
||||||
|
|
||||||
|
// Cache
|
||||||
|
public function handleCacheImages()
|
||||||
|
{
|
||||||
|
global $cfg;
|
||||||
|
|
||||||
|
foreach (glob($cfg['Path']['data'].'tmp/[0-9]*/*/*.*') as $file) {
|
||||||
|
if (@unlink($file)) {
|
||||||
|
$this->success++;
|
||||||
|
} else {
|
||||||
|
$this->failed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$path = realpath($cfg['Path']['data'].'tmp/');
|
||||||
|
|
||||||
|
$objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
|
||||||
|
$folders = [];
|
||||||
|
foreach ($objects as $path => $object) {
|
||||||
|
$folder_name = substr($path, strrpos($path, '/') + 1, strlen($path));
|
||||||
|
if (ctype_digit($folder_name) && strlen($folder_name) == 1) {
|
||||||
|
$folders[] = $path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$folders = array_reverse($folders);
|
||||||
|
|
||||||
|
foreach ($folders as $folder) {
|
||||||
|
@rmdir($folder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleImageVersionUpgrade()
|
||||||
|
{
|
||||||
|
$dbcfg = Settings::getDefault();
|
||||||
|
|
||||||
|
$lastImageVersion = $dbcfg->loadValue('image_version');
|
||||||
|
|
||||||
|
$dbcfg->saveValue('image_version', $lastImageVersion ? $lastImageVersion + 1 : 2);
|
||||||
|
$dbcfg->clearCache();
|
||||||
|
|
||||||
|
$this->success++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleCacheSections()
|
||||||
|
{
|
||||||
|
clearCache('sections', true);
|
||||||
|
$this->success++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleCacheRuntime()
|
||||||
|
{
|
||||||
|
clearCache('', true);
|
||||||
|
$this->success++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleCacheTemplates()
|
||||||
|
{
|
||||||
|
global $cfg;
|
||||||
|
|
||||||
|
foreach (glob($cfg['Path']['data'].'tmp/templates/*') as $file) {
|
||||||
|
if (@unlink($file)) {
|
||||||
|
$this->success++;
|
||||||
|
} else {
|
||||||
|
$this->failed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleCacheFeeds()
|
||||||
|
{
|
||||||
|
global $cfg;
|
||||||
|
|
||||||
|
foreach (glob($cfg['Path']['data'].'tmp/feed_*_*') as $file) {
|
||||||
|
if (@unlink($file)) {
|
||||||
|
$this->success++;
|
||||||
|
} else {
|
||||||
|
$this->failed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleCacheSitemap()
|
||||||
|
{
|
||||||
|
$cfg = Config::get();
|
||||||
|
|
||||||
|
foreach (glob($cfg['Path']['data'].'tmp/sitemap*') as $file) {
|
||||||
|
if (@unlink($file)) {
|
||||||
|
$this->success++;
|
||||||
|
} else {
|
||||||
|
$this->failed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleCacheStatic()
|
||||||
|
{
|
||||||
|
global $cfg;
|
||||||
|
|
||||||
|
foreach (glob($cfg['Path']['data'].'tmp/cache/*') as $file) {
|
||||||
|
if (@unlink($file)) {
|
||||||
|
$this->success++;
|
||||||
|
} else {
|
||||||
|
$this->failed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->handleCacheRuntime();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Photos
|
||||||
|
public function getImagesUnused()
|
||||||
|
{
|
||||||
|
$SQL = sqlQuery('SELECT id
|
||||||
|
FROM photos p
|
||||||
|
LEFT JOIN photos_products_relation ppr ON p.id = ppr.id_photo
|
||||||
|
LEFT JOIN photos_articles_relation ppa ON p.id = ppa.id_photo
|
||||||
|
LEFT JOIN photos_menu_relation par ON p.id = par.id_photo
|
||||||
|
LEFT JOIN photos_blocks_relation blo ON p.id = blo.id_photo
|
||||||
|
LEFT JOIN photos_blocks_new_relation bln ON p.id = bln.id_photo
|
||||||
|
LEFT JOIN photos_sections_relation psr ON p.id = psr.id_photo
|
||||||
|
WHERE ppr.id_product IS NULL AND ppa.id_art IS NULL AND par.id_menu IS NULL
|
||||||
|
AND blo.id_block IS NULL AND bln.id_block IS NULL AND psr.id_section IS NULL');
|
||||||
|
$files = sqlFetchAll($SQL);
|
||||||
|
|
||||||
|
return $files;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleCacheImagesType()
|
||||||
|
{
|
||||||
|
if (($type = getVal('type')) !== null) {
|
||||||
|
$this->clearImageTypeCache($type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear cache only of defined photo type
|
||||||
|
public function clearImageTypeCache($type)
|
||||||
|
{
|
||||||
|
$cfg = Config::get();
|
||||||
|
|
||||||
|
if (!isset($cfg['Photo']['id_to_type'][$type])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (glob($cfg['Path']['data'].'tmp/'.$type.'/*/*.*') as $file) {
|
||||||
|
if (@unlink($file)) {
|
||||||
|
$this->success++;
|
||||||
|
} else {
|
||||||
|
$this->failed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$path = realpath($cfg['Path']['data'].'tmp/'.$type.'/');
|
||||||
|
|
||||||
|
$objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
|
||||||
|
$folders = [];
|
||||||
|
foreach ($objects as $path => $object) {
|
||||||
|
$folder_name = substr($path, strrpos($path, '/') + 1, strlen($path));
|
||||||
|
if (ctype_digit($folder_name) && strlen($folder_name) == 1) {
|
||||||
|
$folders[] = $path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$folders = array_reverse($folders);
|
||||||
|
|
||||||
|
foreach ($folders as $folder) {
|
||||||
|
@rmdir($folder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleImagesUnused()
|
||||||
|
{
|
||||||
|
$files = $this->getImagesUnused();
|
||||||
|
|
||||||
|
$img = new Photos('product');
|
||||||
|
|
||||||
|
foreach ($files as $file) {
|
||||||
|
if ($img->erasePhoto($file['id'])) {
|
||||||
|
$this->success++;
|
||||||
|
} else {
|
||||||
|
$this->failed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getImagesFiles()
|
||||||
|
{
|
||||||
|
global $cfg;
|
||||||
|
$dir = $cfg['Path']['photos'];
|
||||||
|
|
||||||
|
$dirIterator = new RecursiveDirectoryIterator($dir, FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::CURRENT_AS_PATHNAME | FilesystemIterator::SKIP_DOTS);
|
||||||
|
$dirIterator = new RecursiveCallbackFilterIterator($dirIterator, function ($current, $key, $iterator) use ($dir) {
|
||||||
|
// Avoid sliders folder
|
||||||
|
if ($key === $dir.'sliders') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
$files = iterator_to_array(new RecursiveIteratorIterator($dirIterator));
|
||||||
|
|
||||||
|
$db_images = sqlQuery('SELECT CONCAT(:dir, source, image_2) AS path FROM `photos`', ['dir' => $dir]);
|
||||||
|
$db_images = sqlFetchAll($db_images, ['path' => 'path']);
|
||||||
|
|
||||||
|
$files = array_filter($files, function ($file) use ($db_images) {
|
||||||
|
return !isset($db_images[$file]);
|
||||||
|
});
|
||||||
|
|
||||||
|
return $files;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleImagesFiles()
|
||||||
|
{
|
||||||
|
$files = $this->getImagesFiles();
|
||||||
|
|
||||||
|
foreach ($files as $file) {
|
||||||
|
if (@unlink($file)) {
|
||||||
|
$this->success++;
|
||||||
|
} else {
|
||||||
|
$this->failed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleImagesCorrupted()
|
||||||
|
{
|
||||||
|
global $cfg;
|
||||||
|
$db_images = sqlQuery('SELECT CONCAT(:dir, source, image_2) AS path, id FROM `photos`', ['dir' => $cfg['Path']['photos']]);
|
||||||
|
|
||||||
|
$corrupted_id = [];
|
||||||
|
foreach ($db_images as $file) {
|
||||||
|
if (!file_exists($file['path']) || filesize($file['path']) <= 0/* && wpj_open_image($source) */) {
|
||||||
|
$corrupted_id[] = $file['id'];
|
||||||
|
$this->success++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($corrupted_id)) {
|
||||||
|
sqlQuery('DELETE FROM `photos` WHERE id IN ('.join(', ', $corrupted_id).')');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getImagesMissingMain()
|
||||||
|
{
|
||||||
|
return sqlFetchAll(sqlQuery('SELECT id_product FROM photos_products_relation GROUP BY id_product HAVING MAX(show_in_lead)=\'N\''), 'id_product');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleImagesMissingMain()
|
||||||
|
{
|
||||||
|
$IDs = $this->getImagesMissingMain();
|
||||||
|
|
||||||
|
foreach ($IDs as $id_product => $_) {
|
||||||
|
Photos::checkLeadPhoto('photos_products_relation', 'id_product', $id_product);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Products
|
||||||
|
public function handleProductsAll()
|
||||||
|
{
|
||||||
|
$this->success = $this->deleteSQL('products', ['1' => '1']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleProductsAnnotation()
|
||||||
|
{
|
||||||
|
foreach (sqlQuery('SELECT id, short_descr FROM products') as $product) {
|
||||||
|
$product['short_descr'] = trim(html_entity_decode(strip_tags($product['short_descr'])));
|
||||||
|
|
||||||
|
$this->success += $this->updateSQL('products', $product, ['id' => $product['id']], ['id']);
|
||||||
|
}
|
||||||
|
if (findModule(\Modules::TRANSLATIONS)) {
|
||||||
|
foreach (sqlQuery('SELECT id, short_descr FROM products_translations') as $product) {
|
||||||
|
$product['short_descr'] = trim(html_entity_decode(strip_tags($product['short_descr'])));
|
||||||
|
|
||||||
|
$this->success += $this->updateSQL('products_translations', $product, ['id' => $product['id']], ['id']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleProductsDescriptions()
|
||||||
|
{
|
||||||
|
foreach (sqlQuery('SELECT id, short_descr, long_descr FROM products') as $product) {
|
||||||
|
$product['short_descr'] = trim(html_entity_decode(strip_tags($product['short_descr'])));
|
||||||
|
$product['long_descr'] = trim(html_entity_decode(strip_tags($product['long_descr'])));
|
||||||
|
|
||||||
|
$this->success += $this->updateSQL('products', $product, ['id' => $product['id']], ['id']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parameters
|
||||||
|
public function handleParameters()
|
||||||
|
{
|
||||||
|
$this->success = $this->deleteSQL('parameters', ['1' => '1']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleParametersValues()
|
||||||
|
{
|
||||||
|
$this->success = $this->deleteSQL('parameters_list', ['1' => '1']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sections
|
||||||
|
public function handleSections()
|
||||||
|
{
|
||||||
|
$this->success = $this->deleteSQL('sections', ['(id = 0)' => 'FALSE']);
|
||||||
|
clearCache('sections', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleSectionsEmpty()
|
||||||
|
{
|
||||||
|
$SQL = sqlQuery('DELETE s FROM sections s
|
||||||
|
LEFT JOIN products_in_sections ps ON ps.id_section = s.id
|
||||||
|
LEFT JOIN sections_relation sr ON sr.id_topsection = s.id
|
||||||
|
WHERE ps.id_product IS NULL AND sr.id_section IS NULL
|
||||||
|
AND s.id <> 0 ');
|
||||||
|
$this->success = sqlNumRows($SQL);
|
||||||
|
|
||||||
|
MenuSectionTree::invalidateCache();
|
||||||
|
clearCache('sections', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Producers
|
||||||
|
public function handleProducers()
|
||||||
|
{
|
||||||
|
$this->success = $this->deleteSQL('producers', ['1' => '1']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Orders
|
||||||
|
public function handleOrders()
|
||||||
|
{
|
||||||
|
$this->success = $this->deleteSQL('orders', ['1' => '1']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Articles
|
||||||
|
public function handleArticles()
|
||||||
|
{
|
||||||
|
$this->success = $this->deleteSQL('articles', ['1' => '1']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Users
|
||||||
|
public function handleUsers()
|
||||||
|
{
|
||||||
|
$this->success = $this->deleteSQL('users', ['1' => '1']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Variations
|
||||||
|
public function handleVariationsDuplicates()
|
||||||
|
{
|
||||||
|
$duplicates = sqlQuery('SELECT t.id_product, GROUP_CONCAT(t.id ORDER BY t.id SEPARATOR \',\') id_variations
|
||||||
|
FROM (
|
||||||
|
SELECT pv.id, pv.id_product, GROUP_CONCAT(pvc.id_value ORDER BY pvc.id_value SEPARATOR \'-\') vals
|
||||||
|
FROM products_variations pv
|
||||||
|
JOIN products_variations_combination pvc ON pv.id = pvc.id_variation
|
||||||
|
GROUP BY pv.id
|
||||||
|
) AS t
|
||||||
|
GROUP BY t.id_product, t.vals
|
||||||
|
HAVING COUNT(*) > 1');
|
||||||
|
|
||||||
|
foreach ($duplicates as $duplicate) {
|
||||||
|
$variations = explode(',', $duplicate['id_variations']);
|
||||||
|
array_shift($variations);
|
||||||
|
$this->success += sqlQueryBuilder()->delete('products_variations')->where(\Query\Operator::inIntArray($variations, 'id'))->execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleRegenerateVariationsTitles()
|
||||||
|
{
|
||||||
|
Variations::updateTitle();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleFulltextUpdate()
|
||||||
|
{
|
||||||
|
$fulltext = ServiceContainer::getService(FulltextInterface::class);
|
||||||
|
$contextManager = ServiceContainer::getService(ContextManager::class);
|
||||||
|
|
||||||
|
$languages = $fulltext->getFulltextLanguages();
|
||||||
|
if ($lang = getVal('fulltext_language')) {
|
||||||
|
$languages = [$lang => $languages[$lang]];
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($languages as $language => $_) {
|
||||||
|
$contextManager->activateContexts([LanguageContext::class => $language], function () use ($fulltext) {
|
||||||
|
$fulltext->updateIndex(getVal('fulltext_index'));
|
||||||
|
$this->success++;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reviews
|
||||||
|
public function handleReviewsImport()
|
||||||
|
{
|
||||||
|
$reviews = ServiceContainer::getService(\KupShop\CatalogBundle\Util\ReviewsUtil::class);
|
||||||
|
$this->success = $reviews->importReviews();
|
||||||
|
if ($reviews->getError()) {
|
||||||
|
$this->returnError($reviews->getError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleReviewsAutoConfirm()
|
||||||
|
{
|
||||||
|
$reviews = ServiceContainer::getService(\KupShop\CatalogBundle\Util\ReviewsUtil::class);
|
||||||
|
$this->success = $reviews->autoConfirm();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleCronFrequent()
|
||||||
|
{
|
||||||
|
$this->handleCron('FREQUENT');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleCronNormal()
|
||||||
|
{
|
||||||
|
$this->handleCron('NORMAL');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleCronExpensive()
|
||||||
|
{
|
||||||
|
$this->handleCron('EXPENSIVE');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function handleCron(string $type)
|
||||||
|
{
|
||||||
|
/** @var \Symfony\Component\EventDispatcher\EventDispatcher $dispatcher */
|
||||||
|
$dispatcher = ServiceContainer::getService('event_dispatcher');
|
||||||
|
$event = new CronEvent($type);
|
||||||
|
$dispatcher->dispatch($event, constant('KupShop\KupShopBundle\Event\CronEvent::RUN_'.$type));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleRunScript()
|
||||||
|
{
|
||||||
|
$script = getVal('script');
|
||||||
|
if ($script) {
|
||||||
|
ServiceContainer::getService(ScriptLocator::class)->runScript($script, getVal('script_parameters'));
|
||||||
|
exit("\n============ DONE ==============");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCounts()
|
||||||
|
{
|
||||||
|
global $cfg;
|
||||||
|
|
||||||
|
$counts = [];
|
||||||
|
|
||||||
|
// Cache
|
||||||
|
$counts['cacheImages'] = ['count' => count(glob($cfg['Path']['data'].'tmp/*/*/*.*'))];
|
||||||
|
$counts['cacheSections'] = ['count' => 1];
|
||||||
|
$counts['cacheTemplates'] = ['count' => count(glob($cfg['Path']['data'].'tmp/templates/*'))];
|
||||||
|
$counts['cacheStatic'] = ['count' => count(glob($cfg['Path']['data'].'tmp/cache/*'))];
|
||||||
|
|
||||||
|
// Photos
|
||||||
|
$files = $this->getImagesUnused();
|
||||||
|
$counts['imagesUnused'] = ['count' => count($files), 'links' => array_map(function ($file) {
|
||||||
|
return "javascript:nw('photos', {$file['id']})";
|
||||||
|
}, array_slice($files, 0, 10, true) + array_slice($files, -10, 10, true))];
|
||||||
|
|
||||||
|
$files = $this->getImagesFiles();
|
||||||
|
$counts['imagesFiles'] = ['count' => count($files), 'links' => array_slice($files, 0, 10, true) + array_slice($files, -10, 10, true)];
|
||||||
|
|
||||||
|
$images = $this->getImagesMissingMain();
|
||||||
|
$counts['imagesMissingMain'] = ['count' => count($images)];
|
||||||
|
|
||||||
|
return $counts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_vars()
|
||||||
|
{
|
||||||
|
$vars = parent::get_vars();
|
||||||
|
|
||||||
|
if (getVal('calculate')) {
|
||||||
|
$vars['counts'] = $this->getCounts();
|
||||||
|
}
|
||||||
|
|
||||||
|
$vars['scripts'] = ServiceContainer::getService(ScriptLocator::class)->getScripts();
|
||||||
|
|
||||||
|
$indexes = ServiceContainer::getService(FulltextInterface::class)->getIndexTypes();
|
||||||
|
$vars['fulltext']['indexes'] = array_combine($indexes, $indexes);
|
||||||
|
|
||||||
|
return $vars;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
ini_set('max_execution_time', 600);
|
||||||
|
ini_set('memory_limit', '512M');
|
||||||
|
|
||||||
|
parent::handle();
|
||||||
|
|
||||||
|
if (getVal('acn') != 'edit' && getVal('acn') != 'add') {
|
||||||
|
$this->returnOK("Upraveno {$this->success} položek. Selhalo {$this->failed} položek");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not try to handle exceptions - hides some DB errors
|
||||||
|
public function handleException($e)
|
||||||
|
{
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasRights($name = null)
|
||||||
|
{
|
||||||
|
switch ($name) {
|
||||||
|
case Window::RIGHT_SAVE:
|
||||||
|
case Window::RIGHT_DELETE:
|
||||||
|
case Window::RIGHT_DUPLICATE:
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
return parent::hasRights($name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleDiscounts()
|
||||||
|
{
|
||||||
|
$SQL = sqlQuery('DELETE FROM discounts
|
||||||
|
WHERE condition_type != \'generate_coupon\'');
|
||||||
|
$this->success = sqlNumRows($SQL);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleAllDiscounts()
|
||||||
|
{
|
||||||
|
$this->success = $this->deleteSQL('discounts', ['1' => '1']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Variation labels
|
||||||
|
public function handleLabels()
|
||||||
|
{
|
||||||
|
$this->success = $this->deleteSQL('products_variations_choices_labels', ['1' => '1']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleLabelsEmpty()
|
||||||
|
{
|
||||||
|
$SQL = sqlQuery('DELETE vl FROM products_variations_choices_labels vl
|
||||||
|
LEFT JOIN products_variations_combination pvc ON pvc.id_label = vl.id
|
||||||
|
WHERE pvc.id_variation IS NULL');
|
||||||
|
$this->success = sqlNumRows($SQL);
|
||||||
|
}
|
||||||
|
}
|
||||||
97
admin/common.php
Normal file
97
admin/common.php
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use KupShop\KupShopBundle\Context\CurrencyContext;
|
||||||
|
use KupShop\KupShopBundle\Context\UserContext;
|
||||||
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||||
|
|
||||||
|
header('Cache-Control: no-cache');
|
||||||
|
header('Pragma: no-cache');
|
||||||
|
header('Expires: '.gmdate('D, d M Y H:i:s').' GMT');
|
||||||
|
|
||||||
|
// //////////////////// SOUBOR COMMON.PHP
|
||||||
|
|
||||||
|
// zacit pocitat cas provadeni skriptu
|
||||||
|
setStartTime();
|
||||||
|
|
||||||
|
// ################################################################
|
||||||
|
// SESSION
|
||||||
|
// ################################################################
|
||||||
|
|
||||||
|
$session = ServiceContainer::getService('session');
|
||||||
|
$session->start();
|
||||||
|
|
||||||
|
// ################################################################
|
||||||
|
// ERROR REPORTING
|
||||||
|
// ################################################################
|
||||||
|
|
||||||
|
set_error_handler('error_handler');
|
||||||
|
|
||||||
|
// ################################################################
|
||||||
|
// URCENI, KTERE STRANKY JSOU VOLNE PRISTUPNE
|
||||||
|
// ################################################################
|
||||||
|
|
||||||
|
if (!isset($_GET['s'])) {
|
||||||
|
$_GET['s'] = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ################################################################
|
||||||
|
|
||||||
|
// jestlize se jedna o verejnou stranku, nevyzadovat zalogovanisada
|
||||||
|
if (!isset($publicArea)) {
|
||||||
|
$legacyAdminCredentials = ServiceContainer::getService(\KupShop\AdminBundle\Util\LegacyAdminCredentials::class);
|
||||||
|
$legacyAdminCredentials->setAdminGlobalVars(function () {
|
||||||
|
redirect('index.php?error=4&url='.urlencode($_SERVER['REQUEST_URI']));
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isSuperuser()) {
|
||||||
|
ini_set('display_errors', '1');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ################################################################
|
||||||
|
// SMARTY TEMPLATES
|
||||||
|
// ################################################################
|
||||||
|
|
||||||
|
$ctrl = [];
|
||||||
|
$ctrl['admin'] = true;
|
||||||
|
$ctrl['logged'] = false;
|
||||||
|
$ctrl['currUrl'] = [
|
||||||
|
'Abs' => $cfg['Addr']['full'].$_SERVER['REQUEST_URI'],
|
||||||
|
'Rel' => $_SERVER['REQUEST_URI'],
|
||||||
|
];
|
||||||
|
|
||||||
|
$userContext = ServiceContainer::getService(UserContext::class);
|
||||||
|
$userContext->forceEmpty();
|
||||||
|
|
||||||
|
$txt_str = [];
|
||||||
|
|
||||||
|
// ################################################################
|
||||||
|
// VOLBA JAZYKA
|
||||||
|
// ################################################################
|
||||||
|
|
||||||
|
loadLanguage('base');
|
||||||
|
|
||||||
|
// ################################################################
|
||||||
|
// ZISKANI NASTAVENI Z DATABAZE
|
||||||
|
// ################################################################
|
||||||
|
|
||||||
|
$dbcfg = Settings::getDefault();
|
||||||
|
|
||||||
|
// prevedeni aktivnich modulu pro SMARTY
|
||||||
|
$cfg['module'] = [];
|
||||||
|
foreach ($cfg['Modules'] as $index => $module) {
|
||||||
|
if (is_numeric($index)) {
|
||||||
|
$cfg['module'][$module] = true;
|
||||||
|
} else {
|
||||||
|
$cfg['module'][$index] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (findModule('currencies')) {
|
||||||
|
$currencyContext = ServiceContainer::getService(CurrencyContext::class);
|
||||||
|
$currencyContext->activate($currencyContext->getDefaultId());
|
||||||
|
|
||||||
|
if (empty($ctrl['currency'])) {
|
||||||
|
$ctrl['currency'] = $dbcfg['currency'];
|
||||||
|
}
|
||||||
|
}
|
||||||
7
admin/connection.php
Normal file
7
admin/connection.php
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// pripojeni k databazi
|
||||||
|
$cfg['Connection']['link'] = sqlConnect($cfg['Connection']['host'],
|
||||||
|
$cfg['Connection']['user'],
|
||||||
|
$cfg['Connection']['password'],
|
||||||
|
$cfg['Connection']['database']);
|
||||||
347
admin/dbbackup.php
Normal file
347
admin/dbbackup.php
Normal file
@@ -0,0 +1,347 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
ini_set('memory_limit', '5G');
|
||||||
|
|
||||||
|
global $cfg;
|
||||||
|
|
||||||
|
if (!findRight('OTH_BACKUP_ADD') && !findRight('OTH_BACKUP_EDIT') && !findRight('OTH_BACKUP_ERASE')) {
|
||||||
|
redirect('launch.php?s=error.php&id=1');
|
||||||
|
}
|
||||||
|
|
||||||
|
$acn = getVal('acn');
|
||||||
|
$dbBackup = getVal('dbBackup');
|
||||||
|
|
||||||
|
if (empty($acn)) {
|
||||||
|
$acn = 'show';
|
||||||
|
}
|
||||||
|
|
||||||
|
set_time_limit(6000);
|
||||||
|
ignore_user_abort(true);
|
||||||
|
|
||||||
|
if ($acn == 'do' && !empty($dbBackup)) {
|
||||||
|
$do = getVal('do');
|
||||||
|
|
||||||
|
if ($do == 'erase') {
|
||||||
|
if (!findRight('OTH_BACKUP_ERASE')) {
|
||||||
|
redirect('launch.php?s=error.php&id=1');
|
||||||
|
}
|
||||||
|
|
||||||
|
// funkce na ukladani zalohy do souboru
|
||||||
|
function eraseBackup($filename, &$ErrStr)
|
||||||
|
{
|
||||||
|
global $cfg;
|
||||||
|
|
||||||
|
if (@unlink($cfg['Path']['db_backup'].$filename)) {
|
||||||
|
$ErrStr = 'Záloha databáze byla odstraněna.';
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
$ErrStr = 'Stala se chyba při odstraňování databáze - nepodařilo se smazat soubor.';
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file_exists($cfg['Path']['db_backup'].$dbBackup)) {
|
||||||
|
// pokusit se poprve smazat DB zalohu
|
||||||
|
if (!eraseBackup($dbBackup, $ErrStr)) {
|
||||||
|
// snazi se napravit chybu
|
||||||
|
@chmod($cfg['Path']['db_backup'], octdec(777));
|
||||||
|
// snazi se napravit chybu
|
||||||
|
@chmod($cfg['Path']['db_backup'].$dbBackup, octdec(777));
|
||||||
|
|
||||||
|
if (!eraseBackup($dbBackup, $ErrStr)) {
|
||||||
|
// zalogovat chybu
|
||||||
|
logError(__FILE__, __LINE__, 'Chyba odstraneni zalohy databaze: '.$cfg['Path']['db_backup'].$dbBackup);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
writeDownActivity('záloha DB - příkaz smazat zálohu '.$dbBackup);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$ErrStr = 'Požadovaný soubor se zálohou databáze nebyl nalezen.';
|
||||||
|
}
|
||||||
|
|
||||||
|
redirect('launch.php?s=list.php&type=dbbackup&ErrStr='.urlencode($ErrStr));
|
||||||
|
} elseif ($do == 'restore') {
|
||||||
|
if (!findRight('OTH_BACKUP_REFRESH') || isLive()) {
|
||||||
|
redirect('launch.php?s=error.php&id=1');
|
||||||
|
}
|
||||||
|
|
||||||
|
set_time_limit(0);
|
||||||
|
ob_implicit_flush(1);
|
||||||
|
while (ob_get_level()) {
|
||||||
|
ob_end_clean();
|
||||||
|
}
|
||||||
|
echo 'Obnovuji zálohu databáze...';
|
||||||
|
|
||||||
|
$crlf = "\r\n";
|
||||||
|
$lines = iterateBzipLines($cfg['Path']['db_backup'].$dbBackup);
|
||||||
|
|
||||||
|
$sql = [];
|
||||||
|
$next = true;
|
||||||
|
$count = 0;
|
||||||
|
foreach ($lines as $line) {
|
||||||
|
$count++;
|
||||||
|
if ($count >= 1000) {
|
||||||
|
$count = 0;
|
||||||
|
echo '.';
|
||||||
|
}
|
||||||
|
$wrow = trim($line);
|
||||||
|
if (substr($wrow, 0, 1) == '#') {
|
||||||
|
$wrow = $line = '';
|
||||||
|
}
|
||||||
|
if (substr($wrow, 0, 2) == '--') {
|
||||||
|
$wrow = $line = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($next) {
|
||||||
|
$sql[] = $line;
|
||||||
|
} else {
|
||||||
|
$sql[count($sql) - 1] .= $line;
|
||||||
|
}
|
||||||
|
if (substr($wrow, -1) == ';') {
|
||||||
|
$next = true;
|
||||||
|
} else {
|
||||||
|
$next = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete all tables
|
||||||
|
$tables = sqlQuery('SHOW TABLES')->fetchAll();
|
||||||
|
if ($tables) {
|
||||||
|
$tables = array_map(function ($value) {
|
||||||
|
return reset($value);
|
||||||
|
}, $tables);
|
||||||
|
sqlQuery('SET FOREIGN_KEY_CHECKS=0;');
|
||||||
|
foreach ($tables as $table) {
|
||||||
|
sqlQuery("DROP TABLE `{$table}`");
|
||||||
|
}
|
||||||
|
sqlQuery('SET FOREIGN_KEY_CHECKS=1;');
|
||||||
|
}
|
||||||
|
|
||||||
|
$errNo = 0;
|
||||||
|
$errStr = '';
|
||||||
|
foreach ($sql as $query) {
|
||||||
|
$count++;
|
||||||
|
if ($count >= 1000) {
|
||||||
|
$count = 0;
|
||||||
|
echo '.';
|
||||||
|
}
|
||||||
|
$query = trim($query);
|
||||||
|
if ($query) {
|
||||||
|
$SQL = sqlQuery($query);
|
||||||
|
|
||||||
|
if (!$SQL) {
|
||||||
|
$errNo++;
|
||||||
|
$errStr .= $query;
|
||||||
|
} else {
|
||||||
|
$SQL->free();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($errNo == 0) {
|
||||||
|
$ErrStr = 'Databáze byla obnovena ze zálohy.';
|
||||||
|
} else {
|
||||||
|
// zalogovat chybu
|
||||||
|
logError(__FILE__,
|
||||||
|
__LINE__,
|
||||||
|
'Chyba obnovy zalohy databaze: '.
|
||||||
|
$cfg['Path']['db_backup'].$dbBackup."\r\nchybných SQL příkazů: ".$errNo);
|
||||||
|
|
||||||
|
$ErrStr = 'Vyskytly se chyby při ukládání. Celkem chybných SQL příkazů: '.$errNo;
|
||||||
|
}
|
||||||
|
|
||||||
|
writeDownActivity('záloha DB - příkaz obnovit zálohu '.$dbBackup);
|
||||||
|
|
||||||
|
redirect('launch.php?s=list.php&type=dbbackup&ErrStr='.urlencode($ErrStr));
|
||||||
|
} elseif ($do = 'rename') {
|
||||||
|
$newName = getVal('new_name');
|
||||||
|
if ($newName) {
|
||||||
|
$newName = createScriptURL_Text($newName);
|
||||||
|
|
||||||
|
preg_match('/.sql(.bz2)?/i', $dbBackup, $matches);
|
||||||
|
$ext = $matches[0];
|
||||||
|
|
||||||
|
rename($cfg['Path']['db_backup'].$dbBackup,
|
||||||
|
$cfg['Path']['db_backup'].$newName.$ext);
|
||||||
|
|
||||||
|
$ErrStr = 'Záloha byla přejmenována';
|
||||||
|
redirect('launch.php?s=list.php&type=dbbackup&ErrStr='.urlencode($ErrStr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// funkce na ukladani zalohy do souboru
|
||||||
|
function saveBackup($filename, &$ErrStr)
|
||||||
|
{
|
||||||
|
global $cfg;
|
||||||
|
$fp = bzopen($cfg['Path']['db_backup'].$filename, 'w');
|
||||||
|
if ($fp) {
|
||||||
|
return $fp;
|
||||||
|
} else {
|
||||||
|
$ErrStr = 'Chyba při ukládání do souboru.';
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($acn == 'add') {
|
||||||
|
if (!findRight('OTH_BACKUP_ADD')) {
|
||||||
|
redirect('launch.php?s=error.php&id=1');
|
||||||
|
}
|
||||||
|
|
||||||
|
ini_set('display_errors', '1');
|
||||||
|
|
||||||
|
$filename = getVal('name');
|
||||||
|
if (!$filename) {
|
||||||
|
if (empty($return)) {
|
||||||
|
$filename = 'db'.date('Y-m-d_H-i-s').'.sql.bz2';
|
||||||
|
} elseif ($return == 'logout') {
|
||||||
|
$filename = 'logout_backup.sql.bz2';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$filename = createScriptURL_Text($filename).'.sql.bz2';
|
||||||
|
}
|
||||||
|
|
||||||
|
// pokusit se poprve ulozit DB zalohu
|
||||||
|
$ErrStr = null;
|
||||||
|
$fp = saveBackup($filename, $ErrStr);
|
||||||
|
if (!$fp) {
|
||||||
|
// snazi se napravit chybu
|
||||||
|
@chmod($cfg['Path']['db_backup'], octdec(777));
|
||||||
|
// snazi se napravit chybu
|
||||||
|
@chmod($cfg['Path']['db_backup'].$dbBackup, octdec(777));
|
||||||
|
|
||||||
|
$fp = saveBackup($filename, $ErrStr);
|
||||||
|
if (!$fp) {
|
||||||
|
// zalogovat chybu
|
||||||
|
logError(__FILE__, __LINE__, 'Chyba ukladani zalohy databaze: '.$cfg['Path']['db_backup'].$filename);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$params = [
|
||||||
|
'compress' => Ifsnop\Mysqldump\Mysqldump::BZIP2,
|
||||||
|
'add-drop-table' => true,
|
||||||
|
'single-transaction' => true,
|
||||||
|
'disable-foreign-keys-check' => true,
|
||||||
|
'add-locks' => false,
|
||||||
|
'lock-tables' => false,
|
||||||
|
'skip-triggers' => true,
|
||||||
|
];
|
||||||
|
|
||||||
|
$dump = new Ifsnop\Mysqldump\Mysqldump(
|
||||||
|
"mysql:host={$cfg['Connection']['host']};dbname={$cfg['Connection']['database']}",
|
||||||
|
$cfg['Connection']['user'],
|
||||||
|
$cfg['Connection']['password'],
|
||||||
|
$params
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Prepare blank backup file
|
||||||
|
$filename = realpath($cfg['Path']['db_backup']).'/'.$filename;
|
||||||
|
unlink($filename);
|
||||||
|
|
||||||
|
// prepare for streaming
|
||||||
|
set_time_limit(0);
|
||||||
|
ob_implicit_flush(1);
|
||||||
|
while (ob_get_level()) {
|
||||||
|
ob_end_clean();
|
||||||
|
}
|
||||||
|
$dump->setInfoHook(function ($type, $data) {
|
||||||
|
if (isSuperuser()) {
|
||||||
|
echo "<br>{$data['name']}: {$data['rowCount']}";
|
||||||
|
} else {
|
||||||
|
echo '.';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
echo 'Vytvářím zálohu...';
|
||||||
|
|
||||||
|
$dump->start($filename);
|
||||||
|
|
||||||
|
$ErrStr .= 'Databáze byla v pořádku uložena.';
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$ErrStr .= 'Chyba při ukládání do souboru: '.$e->getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($return)) {
|
||||||
|
redirect('launch.php?s=list.php&type=dbbackup&ErrStr='.urlencode($ErrStr));
|
||||||
|
} elseif ($return == 'logout') {
|
||||||
|
redirect('launch.php?s=logout.php');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// download db backup
|
||||||
|
if ($acn == 'download') {
|
||||||
|
$filename = getVal('file');
|
||||||
|
if ($filename) {
|
||||||
|
downloadBackup($filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// upload db backup for wpjadmin
|
||||||
|
if ($acn == 'upload' && isSuperuser()) {
|
||||||
|
$file = $_FILES['upload_db'];
|
||||||
|
if ($file) {
|
||||||
|
if ($file['type'] == 'application/x-bzip' || pathinfo($file['name'], PATHINFO_EXTENSION) == 'bz2') {
|
||||||
|
uploadBackup($file);
|
||||||
|
} else {
|
||||||
|
$ErrStr = "Nepodporovaný formát {$file['type']}!";
|
||||||
|
redirect('launch.php?s=list.php&type=dbbackup&ErrStr='.urlencode($ErrStr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function uploadBackup($file)
|
||||||
|
{
|
||||||
|
$cfg = \KupShop\KupShopBundle\Config::get();
|
||||||
|
|
||||||
|
$targetLocation = $cfg['Path']['db_backup'].$file['name'];
|
||||||
|
if (move_uploaded_file($file['tmp_name'], $targetLocation)) {
|
||||||
|
$ErrStr = 'Záloha databáze byla nahrána';
|
||||||
|
redirect('launch.php?s=list.php&type=dbbackup&ErrStr='.urlencode($ErrStr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function downloadBackup($filename)
|
||||||
|
{
|
||||||
|
$cfg = \KupShop\KupShopBundle\Config::get();
|
||||||
|
|
||||||
|
$file = $cfg['Path']['db_backup'].$filename;
|
||||||
|
|
||||||
|
header('Content-Description: File Transfer');
|
||||||
|
header('Content-Type: application/x-bzip');
|
||||||
|
header('Content-Disposition: attachment; filename='.basename($file).'');
|
||||||
|
|
||||||
|
readfile($file);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
function iterateBzipLines($file)
|
||||||
|
{
|
||||||
|
$fp = bzopen($file, 'r');
|
||||||
|
|
||||||
|
$data = '';
|
||||||
|
while (!feof($fp)) {
|
||||||
|
$data .= bzread($fp, 4096);
|
||||||
|
|
||||||
|
$row = preg_split("/(\r\n|\n)/", $data);
|
||||||
|
|
||||||
|
$lines = count($row);
|
||||||
|
|
||||||
|
foreach ($row as $index => $line) {
|
||||||
|
// Detect last row
|
||||||
|
if ($index == $lines - 1) {
|
||||||
|
$data = $line;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
yield $line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
yield $data;
|
||||||
|
|
||||||
|
bzclose($fp);
|
||||||
|
}
|
||||||
219
admin/deliveryDelivery.php
Normal file
219
admin/deliveryDelivery.php
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$main_class = 'DeliveryTypesDelivery';
|
||||||
|
|
||||||
|
use KupShop\KupShopBundle\Context\ContextManager;
|
||||||
|
use KupShop\KupShopBundle\Context\CountryContext;
|
||||||
|
use KupShop\KupShopBundle\Context\CurrencyContext;
|
||||||
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||||
|
|
||||||
|
class DeliveryTypesDelivery extends Window
|
||||||
|
{
|
||||||
|
protected $tableName = 'delivery_type_delivery';
|
||||||
|
|
||||||
|
/** @var CurrencyContext */
|
||||||
|
private $currencyContext;
|
||||||
|
|
||||||
|
private $countryContext;
|
||||||
|
|
||||||
|
private $contextManager;
|
||||||
|
|
||||||
|
private $delivery;
|
||||||
|
|
||||||
|
protected $required = ['price' => true];
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->currencyContext = ServiceContainer::getService(CurrencyContext::class);
|
||||||
|
$this->countryContext = ServiceContainer::getService(CountryContext::class);
|
||||||
|
$this->contextManager = ServiceContainer::getService(ContextManager::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_vars()
|
||||||
|
{
|
||||||
|
$vars = parent::get_vars();
|
||||||
|
|
||||||
|
$pageVars = getVal('body', $vars);
|
||||||
|
|
||||||
|
$vat = getAdminVat()['value'];
|
||||||
|
|
||||||
|
$dbcfg = Settings::getDefault();
|
||||||
|
$pageVars['data']['priceWithVat'] = $dbcfg['prod_prefer_price_vat'] == 'Y' || $dbcfg['prod_prefer_price_vat'] == 'F';
|
||||||
|
|
||||||
|
if (isset($pageVars['data']) && !empty($pageVars['data']['price']) && $pageVars['data']['priceWithVat']) {
|
||||||
|
$pageVars['data']['price'] = toDecimal($pageVars['data']['price'])->mul(toDecimal(1 + ($vat / 100)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($pageVars['data']['price_registered'])) {
|
||||||
|
$pageVars['data']['price_registered'] *= 1 + ($vat / 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($pageVars['data']['countries'])) {
|
||||||
|
$pageVars['data']['countries'] = json_decode($pageVars['data']['countries']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (findModule('delivery_pricelist')) {
|
||||||
|
$pageVars['deliveryPricelists'] = $this->getDeliveryPricelists();
|
||||||
|
}
|
||||||
|
|
||||||
|
$pageVars['data']['currencies'] = $this->currencyContext->getAll();
|
||||||
|
|
||||||
|
if ($this->getAction() == 'add') {
|
||||||
|
$pageVars['data']['currency'] = $this->currencyContext->getDefaultId();
|
||||||
|
}
|
||||||
|
|
||||||
|
$pageVars['data']['template'] = $this->getDeliveryObject()->getAdminWindowTemplate();
|
||||||
|
|
||||||
|
$pageVars['data']['custom_data'] = $this->getCustomData();
|
||||||
|
|
||||||
|
$vars['body'] = $pageVars;
|
||||||
|
|
||||||
|
return $vars;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getDeliveryPricelists()
|
||||||
|
{
|
||||||
|
/** @var \Doctrine\ORM\EntityManager $em */
|
||||||
|
$em = \KupShop\KupShopBundle\Util\Compat\ServiceContainer::getService('doctrine.orm.entity_manager');
|
||||||
|
$repository = $em->getRepository(\KupShop\DeliveryPriceListBundle\Entity\PriceList::class);
|
||||||
|
|
||||||
|
return $repository->findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getObject()
|
||||||
|
{
|
||||||
|
$data = parent::getObject();
|
||||||
|
$data['photo_array'] = $this->getDeliveryObject()->getPhoto();
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getData()
|
||||||
|
{
|
||||||
|
global $cfg;
|
||||||
|
$data = parent::getData();
|
||||||
|
|
||||||
|
if (getVal('Submit')) {
|
||||||
|
$data['price'] = $this->prepareVatPrice($data['price']);
|
||||||
|
$data['price_registered'] = $this->prepareVatPrice($data['price_registered']);
|
||||||
|
if (!empty($data['price_buy'])) {
|
||||||
|
$data['price_buy'] = $this->prepareVatPrice($data['price_buy']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($data['countries']) && count(array_diff(array_keys($this->countryContext->getAll()), $data['countries'])) != 0) {
|
||||||
|
$data['countries'] = json_encode($data['countries']);
|
||||||
|
} else {
|
||||||
|
$data['countries'] = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($widgetOptions = $data['custom_data']['widget_options'] ?? false) {
|
||||||
|
if (is_array($widgetOptions)) {
|
||||||
|
$data['custom_data']['widget_options'] = $widgetOptions;
|
||||||
|
} else {
|
||||||
|
$data['custom_data']['widget_options'] = json_decode($widgetOptions, true);
|
||||||
|
if (json_last_error()) {
|
||||||
|
$this->returnError(sprintf(
|
||||||
|
'%s: %s',
|
||||||
|
translate('widgetOptions', 'deliveryDelivery', true, true),
|
||||||
|
json_last_error_msg(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unset($data['custom_data']['widget_options']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($data['custom_data']['users_groups'])) {
|
||||||
|
unset($data['custom_data']['users_groups_invert']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$delivery = Delivery::getClass($data['class'] ?? null);
|
||||||
|
$custom_data = $delivery->processAdminWindowData($data['custom_data'] ?? []);
|
||||||
|
$oldCustomData = $this->getCustomData();
|
||||||
|
if (isset($oldCustomData['restrictions'])) {
|
||||||
|
$custom_data['restrictions'] = $oldCustomData['restrictions']; // preserve restrictions - already saved in DeliveryRestrictions tab
|
||||||
|
}
|
||||||
|
if (isset($oldCustomData['balikobot'])) {
|
||||||
|
$custom_data['balikobot'] = $oldCustomData['balikobot']; // preserve balikobot - already saved in BalikobotDeliveryTab
|
||||||
|
}
|
||||||
|
$this->setCustomData($custom_data);
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleUpdate()
|
||||||
|
{
|
||||||
|
$data = $this->getData();
|
||||||
|
|
||||||
|
$SQL = parent::handleUpdate();
|
||||||
|
|
||||||
|
clearCache('freeDelivery_', true);
|
||||||
|
|
||||||
|
if (findModule('delivery_pricelist')) {
|
||||||
|
// Pricelist id update
|
||||||
|
if ($SQL) {
|
||||||
|
if (!empty($data['pricelist']['id_pricelist'])) {
|
||||||
|
$pricelistId = $data['pricelist']['id_pricelist'];
|
||||||
|
if ($pricelistId == 'null') {
|
||||||
|
$pricelistId = null;
|
||||||
|
}
|
||||||
|
$this->updateSQL($this->getTableName(), ['id_pricelist' => $pricelistId], ['id' => $this->getID()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add photo
|
||||||
|
$img = new Photos('delivery');
|
||||||
|
$img->newImage($this->getID());
|
||||||
|
|
||||||
|
if (!empty($_FILES['photo']['name'])) {
|
||||||
|
$img->uploadImage($_FILES['photo']);
|
||||||
|
|
||||||
|
if ($img->checkFileType()) {
|
||||||
|
$img->insertImageIntoDB();
|
||||||
|
} else {
|
||||||
|
$this->addError(getTextString('producers', 'errorBadPhoto'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear delivery thumbnail
|
||||||
|
$img->clearThumbnails([9]);
|
||||||
|
|
||||||
|
return $SQL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleDelete()
|
||||||
|
{
|
||||||
|
// Delete photo
|
||||||
|
$img = new Photos('delivery');
|
||||||
|
$img->newImage($this->getID());
|
||||||
|
$img->deletePhoto(false);
|
||||||
|
|
||||||
|
parent::handleDelete();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleErasephoto()
|
||||||
|
{
|
||||||
|
// ########################################################################
|
||||||
|
$img = new Photos('delivery');
|
||||||
|
$img->newImage($this->getID());
|
||||||
|
$img->deletePhoto();
|
||||||
|
// ########################################################################
|
||||||
|
|
||||||
|
$this->returnOK();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDeliveryObject()
|
||||||
|
{
|
||||||
|
if (!$this->delivery) {
|
||||||
|
$data = parent::getObject();
|
||||||
|
$this->delivery = Delivery::getClass($data['class'] ?? null);
|
||||||
|
if ($this->getID()) {
|
||||||
|
$this->delivery->createFromArray($data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->delivery;
|
||||||
|
}
|
||||||
|
}
|
||||||
159
admin/deliveryPayment.php
Normal file
159
admin/deliveryPayment.php
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$main_class = 'DeliveryTypesPayment';
|
||||||
|
|
||||||
|
use KupShop\KupShopBundle\Context\CurrencyContext;
|
||||||
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||||
|
use KupShop\OrderingBundle\Exception\PaymentConfigurationException;
|
||||||
|
|
||||||
|
class DeliveryTypesPayment extends Window
|
||||||
|
{
|
||||||
|
protected $tableName = 'delivery_type_payment';
|
||||||
|
|
||||||
|
/** @var CurrencyContext */
|
||||||
|
private $currencyContext;
|
||||||
|
|
||||||
|
private ?Payment $payment = null;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->currencyContext = ServiceContainer::getService(CurrencyContext::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_vars()
|
||||||
|
{
|
||||||
|
$vars = parent::get_vars();
|
||||||
|
|
||||||
|
$pageVars = getVal('body', $vars);
|
||||||
|
|
||||||
|
$payments = Payment::listClasses();
|
||||||
|
$payments[''] = 'Žádná';
|
||||||
|
foreach ($payments as $class => $payment) {
|
||||||
|
$payments[$class] = $payment;
|
||||||
|
}
|
||||||
|
$pageVars['payments'] = $payments;
|
||||||
|
|
||||||
|
$dbcfg = Settings::getDefault();
|
||||||
|
$pageVars['data']['priceWithVat'] = $dbcfg['prod_prefer_price_vat'] == 'Y' || $dbcfg['prod_prefer_price_vat'] == 'F';
|
||||||
|
|
||||||
|
if (!empty($pageVars['data']['price']) && $pageVars['data']['priceWithVat']) {
|
||||||
|
$pageVars['data']['price'] *= 1 + (getAdminVat()['value'] / 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
$pageVars['data']['currencies'] = $this->currencyContext->getAll();
|
||||||
|
|
||||||
|
$this->unserializeCustomData($pageVars['data']);
|
||||||
|
|
||||||
|
$vars['body'] = $pageVars;
|
||||||
|
|
||||||
|
return $vars;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getObject()
|
||||||
|
{
|
||||||
|
$data = parent::getObject();
|
||||||
|
if ($obj = $this->getPaymentObject()) {
|
||||||
|
$data['photo_array'] = $obj->getPhoto($data['photo'], $data['date_updated']);
|
||||||
|
} elseif (!empty($data['photo'])) {
|
||||||
|
// When no payment type specified
|
||||||
|
$data['photo_array'] = getImage(
|
||||||
|
$this->getID(),
|
||||||
|
basename($data['photo']),
|
||||||
|
dirname($data['photo']),
|
||||||
|
8,
|
||||||
|
$data['name'],
|
||||||
|
strtotime($data['date_updated']),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getData()
|
||||||
|
{
|
||||||
|
$data = parent::getData();
|
||||||
|
|
||||||
|
if (getVal('Submit')) {
|
||||||
|
if ($data['priceWithVat'] && $data['price'] > 0) {
|
||||||
|
$data['price'] = $data['price'] / (1 + (getAdminVat()['value'] / 100));
|
||||||
|
}
|
||||||
|
if (!empty($data['price_buy'])) {
|
||||||
|
$data['price_buy'] = $this->prepareVatPrice($data['price_buy']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($data['class'])) {
|
||||||
|
try {
|
||||||
|
$payment = Payment::getClass($data['class']);
|
||||||
|
} catch (PaymentConfigurationException $e) {
|
||||||
|
$this->returnError($e->getMessage());
|
||||||
|
}
|
||||||
|
$data['data'] = $payment->processAdminWindowData($data['data'] ?? []);
|
||||||
|
}
|
||||||
|
$this->serializeCustomData($data);
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleUpdate()
|
||||||
|
{
|
||||||
|
$SQL = parent::handleUpdate();
|
||||||
|
|
||||||
|
// Add photo
|
||||||
|
if (!empty($_FILES['photo']['name'])) {
|
||||||
|
$img = new Photos('payment');
|
||||||
|
$img->newImage($this->getID());
|
||||||
|
$img->uploadImage($_FILES['photo']);
|
||||||
|
|
||||||
|
if ($img->checkFileType()) {
|
||||||
|
$img->insertImageIntoDB();
|
||||||
|
} else {
|
||||||
|
$this->addError(getTextString('producers', 'errorBadPhoto'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear payment thumbnail
|
||||||
|
$img->clearThumbnails([9]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $SQL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleDelete()
|
||||||
|
{
|
||||||
|
// Delete photo
|
||||||
|
$img = new Photos('payment');
|
||||||
|
$img->newImage($this->getID());
|
||||||
|
$img->deletePhoto(false);
|
||||||
|
|
||||||
|
parent::handleDelete();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleErasephoto()
|
||||||
|
{
|
||||||
|
// ########################################################################
|
||||||
|
$img = new Photos('payment');
|
||||||
|
$img->newImage($this->getID());
|
||||||
|
$img->deletePhoto();
|
||||||
|
// ########################################################################
|
||||||
|
|
||||||
|
$this->returnOK();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPaymentObject(): ?Payment
|
||||||
|
{
|
||||||
|
if (!$this->payment) {
|
||||||
|
$data = parent::getObject();
|
||||||
|
|
||||||
|
if (empty($data['class'])) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->payment = Payment::getClass($data['class']);
|
||||||
|
if ($id = $this->getID()) {
|
||||||
|
$this->payment->setID($id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->payment;
|
||||||
|
}
|
||||||
|
}
|
||||||
88
admin/deliverytypes.php
Normal file
88
admin/deliverytypes.php
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$main_class = 'DeliveryTypes';
|
||||||
|
|
||||||
|
use KupShop\KupShopBundle\Context\CurrencyContext;
|
||||||
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||||
|
|
||||||
|
class DeliveryTypes extends Window
|
||||||
|
{
|
||||||
|
protected $tableName = 'delivery_type';
|
||||||
|
protected $nameField;
|
||||||
|
|
||||||
|
/** @var CurrencyContext */
|
||||||
|
private $currencyContext;
|
||||||
|
|
||||||
|
protected $defaults = [
|
||||||
|
'figure' => true,
|
||||||
|
];
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->currencyContext = ServiceContainer::getService(
|
||||||
|
CurrencyContext::class
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_vars()
|
||||||
|
{
|
||||||
|
$vars = parent::get_vars();
|
||||||
|
|
||||||
|
$pageVars = getVal('body', $vars);
|
||||||
|
|
||||||
|
$pageVars['vats'] = \KupShop\KupShopBundle\Context\VatContext::getAdminVats();
|
||||||
|
|
||||||
|
$pageVars['delivery'] = sqlFetchAll($this->selectSQL('delivery_type_delivery', [], ['id', 'COALESCE(name_admin, name) AS name']), ['id' => 'name']);
|
||||||
|
$pageVars['payment'] = sqlFetchAll($this->selectSQL('delivery_type_payment', [], ['id', 'COALESCE(name_admin, name) AS name']), ['id' => 'name']);
|
||||||
|
|
||||||
|
$dbcfg = Settings::getDefault();
|
||||||
|
$pageVars['data']['priceWithVat'] = $dbcfg['prod_prefer_price_vat'] == 'Y' || $dbcfg['prod_prefer_price_vat'] == 'F';
|
||||||
|
|
||||||
|
if (!empty($pageVars['data']['price']) && $pageVars['data']['price'] instanceof Decimal) {
|
||||||
|
$pageVars['data']['price'] = $pageVars['data']['price']->asFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($pageVars['data']['price']) && $pageVars['data']['priceWithVat']) {
|
||||||
|
$pageVars['data']['price'] = round($pageVars['data']['price'] * (1 + ($pageVars['vats'][$pageVars['data']['vat']]['vat'] / 100)), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
$pageVars['data']['currencies'] = $this->currencyContext->getAll();
|
||||||
|
|
||||||
|
$pageVars['data']['custom_data'] = $this->getCustomData();
|
||||||
|
|
||||||
|
$vars['body'] = $pageVars;
|
||||||
|
$vars['type'] = 'deliverytypes';
|
||||||
|
|
||||||
|
return $vars;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleUpdate()
|
||||||
|
{
|
||||||
|
clearCache('freeDelivery_', true);
|
||||||
|
|
||||||
|
return parent::handleUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getData()
|
||||||
|
{
|
||||||
|
$data = parent::getData();
|
||||||
|
|
||||||
|
$data['vatValue'] = getVat($data['vat']);
|
||||||
|
|
||||||
|
if (getVal('Submit')) {
|
||||||
|
$this->preparePrice($data['price']);
|
||||||
|
$this->preparePrice($data['price_dont_countin_from']);
|
||||||
|
|
||||||
|
if ($data['priceWithVat'] && $data['price'] > 0) {
|
||||||
|
$price = toDecimal($data['price']);
|
||||||
|
$data['price'] = $price->removeVat($data['vatValue']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($data['custom_data'])) {
|
||||||
|
$this->setCustomData($data['custom_data']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
360
admin/emails.php
Normal file
360
admin/emails.php
Normal file
@@ -0,0 +1,360 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use KupShop\KupShopBundle\Config;
|
||||||
|
use KupShop\KupShopBundle\Context\LanguageContext;
|
||||||
|
use KupShop\KupShopBundle\Email\EmailGroupTypeEnum;
|
||||||
|
use KupShop\KupShopBundle\Email\OrderMessageEmail;
|
||||||
|
use KupShop\KupShopBundle\Email\UserMessagesInterface;
|
||||||
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||||
|
use KupShop\KupShopBundle\Util\Mail\Email;
|
||||||
|
use KupShop\KupShopBundle\Util\Mail\EmailLocator;
|
||||||
|
use KupShop\KupShopBundle\Util\Mail\EmailSender;
|
||||||
|
use KupShop\KupShopBundle\Util\Mail\SMSSender;
|
||||||
|
use KupShop\OrderingBundle\Util\Attachment\AttachmentLocator;
|
||||||
|
use KupShop\ReturnsBundle\Util\ReturnsUtil;
|
||||||
|
use Symfony\Component\Mime\Exception\RfcComplianceException;
|
||||||
|
|
||||||
|
$main_class = 'AdminEmails';
|
||||||
|
|
||||||
|
class AdminEmails extends Window
|
||||||
|
{
|
||||||
|
protected $template = 'window/emails.tpl';
|
||||||
|
|
||||||
|
private $languageContext;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->languageContext = ServiceContainer::getService(LanguageContext::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasRights($name = null)
|
||||||
|
{
|
||||||
|
switch ($name) {
|
||||||
|
case self::RIGHT_DUPLICATE:
|
||||||
|
case self::RIGHT_DELETE:
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_vars()
|
||||||
|
{
|
||||||
|
$vars = parent::get_vars();
|
||||||
|
|
||||||
|
$settings = Settings::createFromDB();
|
||||||
|
|
||||||
|
$pageVars['data'] = [
|
||||||
|
'order_send_received_mail' => $settings->order_send_received_mail,
|
||||||
|
'order_send_status_mail' => $settings->order_send_status_mail,
|
||||||
|
'order_send_to_shopkeeper' => $settings->order_send_to_shopkeeper,
|
||||||
|
'order_shopkeeper_mail' => $settings->order_shopkeeper_mail,
|
||||||
|
'default_email' => $settings->order_shopkeeper_mail,
|
||||||
|
'smtp' => $settings->smtp ?? [],
|
||||||
|
'email_default_signature' => $settings->email_default_signature ?? [],
|
||||||
|
'email_allowed_recipient_domains' => $settings->email_allowed_recipient_domains ?? '',
|
||||||
|
];
|
||||||
|
|
||||||
|
/** @var Email $email */
|
||||||
|
$email = ServiceContainer::getService(Email::class);
|
||||||
|
$pageVars['email'] = $email;
|
||||||
|
|
||||||
|
/** @var SMSSender $smsSender */
|
||||||
|
$smsSender = ServiceContainer::getService(SMSSender::class);
|
||||||
|
$pageVars['SMSSenderBackend'] = $smsSender->getBackend();
|
||||||
|
|
||||||
|
// Get email groups from enum, so we can display them in right order
|
||||||
|
array_map(function ($enum) use (&$pageVars) {
|
||||||
|
$pageVars['emails_messages'][$enum->value] = ['doNotShow' => true];
|
||||||
|
}, EmailGroupTypeEnum::cases());
|
||||||
|
|
||||||
|
$default_emails = [];
|
||||||
|
foreach ($email->getDefaultTypes() as $type) {
|
||||||
|
$emailService = $email->getServiceByType($type);
|
||||||
|
if ($emailService::getGroup() == EmailGroupTypeEnum::HIDDEN->value) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($emailService instanceof UserMessagesInterface) {
|
||||||
|
// Fetch UserMessage types for group
|
||||||
|
$pageVars['messages_types'][$emailService::getGroup()] = $emailService::getType();
|
||||||
|
$pageVars['emails_messages'][$emailService::getGroup()] = $emailService->getMessages($this->languageContext->getDefaultId());
|
||||||
|
foreach ($pageVars['emails_messages'][$emailService::getGroup()] as &$message) {
|
||||||
|
$message['attachments'] = $this->prepareAttachments($message['attachments']);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$default_emails[$emailService::getGroup()][$type] = $emailService->getEmailTemplate($this->languageContext->getDefaultId());
|
||||||
|
$default_emails[$emailService::getGroup()][$type]['isAnswer'] = $emailService->isAnswer ?? null;
|
||||||
|
if (empty($default_emails[$emailService::getGroup()][$type]['id'])) {
|
||||||
|
$default_emails[$emailService::getGroup()][$type]['id'] = rand(-100, -200);
|
||||||
|
}
|
||||||
|
$default_emails[$emailService::getGroup()][$type]['name'] = $emailService::getName();
|
||||||
|
$default_emails[$emailService::getGroup()][$type]['attachments'] = $this->prepareAttachments($default_emails[$emailService::getGroup()][$type]['attachments']);
|
||||||
|
$default_emails[$emailService::getGroup()][$type]['default_template'] = $emailService->getDefaultEmail();
|
||||||
|
$default_emails[$emailService::getGroup()][$type]['attachmentsGroup'] = $emailService::getGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort groups by desired order
|
||||||
|
$sorted_default_emails = array_merge(array_flip([
|
||||||
|
EmailGroupTypeEnum::ORDER->value,
|
||||||
|
EmailGroupTypeEnum::FORMS->value,
|
||||||
|
EmailGroupTypeEnum::RETURN->value,
|
||||||
|
EmailGroupTypeEnum::RECLAMATION->value,
|
||||||
|
EmailGroupTypeEnum::OTHER->value,
|
||||||
|
]), $default_emails);
|
||||||
|
|
||||||
|
// Filter empty groups
|
||||||
|
$pageVars['emails'] = array_intersect_key($sorted_default_emails, $default_emails);
|
||||||
|
|
||||||
|
if (!empty($pageVars['emails'][EmailGroupTypeEnum::OTHER->value][Email::TYPE_BASIC_TEMPLATE]['email'])) {
|
||||||
|
$pageVars['data']['default_email'] = $pageVars['emails'][EmailGroupTypeEnum::OTHER->value][Email::TYPE_BASIC_TEMPLATE]['email'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$pageVars['statuses'] = [
|
||||||
|
// -100 - hardcoded non existing status for storno, so it can be selected
|
||||||
|
'order' => Config::get()['Order']['Status']['global'] + ['-100' => 'storno'],
|
||||||
|
];
|
||||||
|
|
||||||
|
if (findModule(\Modules::RETURNS)) {
|
||||||
|
$pageVars['statuses']['return'] = ServiceContainer::getService(ReturnsUtil::class)->getStatuses();
|
||||||
|
}
|
||||||
|
|
||||||
|
// attachments
|
||||||
|
$attachmentLocator = ServiceContainer::getService(AttachmentLocator::class);
|
||||||
|
|
||||||
|
$pageVars['attachments'] = $attachmentLocator->getAttachments('ALL');
|
||||||
|
|
||||||
|
$vars['body'] = $pageVars;
|
||||||
|
|
||||||
|
return $vars;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function prepareAttachments($attachments)
|
||||||
|
{
|
||||||
|
if (!empty($attachments)) {
|
||||||
|
return json_decode($attachments, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$this->tryRights('EDIT');
|
||||||
|
|
||||||
|
$data = getVal('data');
|
||||||
|
$Submit = getVal('Submit');
|
||||||
|
$acn = getVal('acn');
|
||||||
|
if (!empty($data) && !empty($Submit)) {
|
||||||
|
$ErrStr = $this->saveSettings($data);
|
||||||
|
|
||||||
|
redirect('launch.php?s=emails.php&acn=edit&flap='.getVal('flap').'&ErrStr='.$ErrStr);
|
||||||
|
} elseif (str_starts_with($acn ?? '', 'SendTestEmail_')) {
|
||||||
|
$this->sendTestEmail(str_replace('SendTestEmail_', '', $acn));
|
||||||
|
} else {
|
||||||
|
Base::handle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handlePlaceholders()
|
||||||
|
{
|
||||||
|
$type = getVal('type');
|
||||||
|
$emailLocator = ServiceContainer::getService(EmailLocator::class);
|
||||||
|
$emailService = $emailLocator->getEmailService($type);
|
||||||
|
|
||||||
|
// TODO: HACK Bez testEmail padají applyPlaceholders, protože v nich lidi šahají na data (->getOrder()), který tam v tohle případě nejsou.
|
||||||
|
// TODO: HACK Proto volám testEmail, abych nasetoval nějaký testovací data a nepadalo to. Ale applyPlaceholders by nemělo záviset na datech.
|
||||||
|
$order_message = getVal('order_message');
|
||||||
|
if ($emailService instanceof OrderMessageEmail) {
|
||||||
|
$emailService->setOrderMessage($order_message);
|
||||||
|
}
|
||||||
|
$emailService->testEmail();
|
||||||
|
|
||||||
|
foreach ($emailLocator->getEmailRegisters() as $register) {
|
||||||
|
$register->applyPlaceholders($emailService);
|
||||||
|
}
|
||||||
|
|
||||||
|
$placeholders = $emailService::getPlaceholders();
|
||||||
|
foreach ($emailService->getEntityPlaceholders() as $placeholder) {
|
||||||
|
$placeholders[$emailService::getType()][$placeholder->code] = ['text' => $placeholder->description];
|
||||||
|
}
|
||||||
|
|
||||||
|
$smarty = createSmarty(true, true);
|
||||||
|
$smarty->assign([
|
||||||
|
'type' => $type,
|
||||||
|
'name' => $emailService::getName(),
|
||||||
|
'placeholders' => $placeholders,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$smarty->display('window/emails.placeholders.tpl');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleTest()
|
||||||
|
{
|
||||||
|
$type = getVal('type');
|
||||||
|
$emailLocator = ServiceContainer::getService(EmailLocator::class);
|
||||||
|
$emailService = $emailLocator->getEmailService($type);
|
||||||
|
$typeTestEmail = $emailService->getTestType();
|
||||||
|
$order_message = getVal('order_message');
|
||||||
|
|
||||||
|
if ($emailService instanceof OrderMessageEmail) {
|
||||||
|
$emailService->setOrderMessage($order_message);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($typeTestEmail && $entityID = getVal('entityID')) {
|
||||||
|
$emailService->setTestEntity($entityID);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if ($type == 'BASIC_TEMPLATE') {
|
||||||
|
$message = ['body' => '<p>Testovací email.</p>', 'subject' => 'Testovací email'];
|
||||||
|
$message = $emailService->renderEmail($message);
|
||||||
|
$message['body'] = replacePlaceholders($message['body'], [], [$emailService, 'replacePlaceholdersItem']);
|
||||||
|
} else {
|
||||||
|
$message = $emailService->testEmail();
|
||||||
|
}
|
||||||
|
} catch (InvalidArgumentException $e) {
|
||||||
|
$this->returnError($e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
$smarty = createSmarty(true, true);
|
||||||
|
$smarty->assign([
|
||||||
|
'type' => $type,
|
||||||
|
'typeTestEmail' => $typeTestEmail,
|
||||||
|
'entityID' => $entityID ?? '',
|
||||||
|
'email' => $message,
|
||||||
|
'order_message' => $order_message,
|
||||||
|
'placeholders' => $emailService::getPlaceholders() ?? '',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$smarty->display('window/emails.preview.tpl');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sendTestEmail($id)
|
||||||
|
{
|
||||||
|
$this->saveSettings(getVal('data'));
|
||||||
|
|
||||||
|
$emailSender = ServiceContainer::getService(EmailSender::class);
|
||||||
|
try {
|
||||||
|
$email = Settings::getDefault()->order_shopkeeper_mail;
|
||||||
|
$testEmail = explode(',', getVal('data')['smtp'][$id]['allowed_senders']);
|
||||||
|
$testEmail = trim(reset($testEmail));
|
||||||
|
if (!$testEmail || $testEmail == '*') {
|
||||||
|
$testEmail = $email;
|
||||||
|
}
|
||||||
|
$message = $emailSender->createMessage($testEmail, $email, 'Testovací email', 'Testovací email pro kontrolu nastavení SMTP serveru.', 'text/html');
|
||||||
|
$emailSender->realSendMessage($message);
|
||||||
|
} catch (RfcComplianceException $e) {
|
||||||
|
$this->returnError('Nelze odeslat testovací e-mail. E-mailová adresa nemá správný formát');
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
$error = $e->getMessage();
|
||||||
|
$this->returnError("Nelze odeslat testovací email: {$error}");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->returnOK('Testovací zpráva odeslána.');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function saveSettings($data)
|
||||||
|
{
|
||||||
|
$settings = Settings::createFromDB();
|
||||||
|
$edited = [];
|
||||||
|
|
||||||
|
$types = ['emails_messages'];
|
||||||
|
|
||||||
|
array_map(function ($enum) use (&$types) {
|
||||||
|
$types[] = $enum->value;
|
||||||
|
}, EmailGroupTypeEnum::cases());
|
||||||
|
|
||||||
|
foreach ($data as $type => $values) {
|
||||||
|
if (!in_array($type, $types)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
foreach ($values as $id => $email) {
|
||||||
|
if ($id == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($email['type']) {
|
||||||
|
case 'ORDER_CREATE':
|
||||||
|
$edited['order_send_received_mail'] = $email['enabled'];
|
||||||
|
break;
|
||||||
|
case 'ORDER_STATUS_CHANGE':
|
||||||
|
$edited['order_send_status_mail'] = $email['enabled'];
|
||||||
|
break;
|
||||||
|
case 'ORDER_CREATE_ADMIN':
|
||||||
|
$edited['order_send_to_shopkeeper'] = $email['enabled'];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$email['order_status'] = $email['order_status'] == '' ? null : $email['order_status'];
|
||||||
|
$email['name'] = trim($email['name'] ?? '');
|
||||||
|
|
||||||
|
if (!empty($email['attachments'])) {
|
||||||
|
$email['attachments'] = json_encode($email['attachments']);
|
||||||
|
} else {
|
||||||
|
$email['attachments'] = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($email['body'])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var Email $email */
|
||||||
|
$emailService = ServiceContainer::getService(Email::class);
|
||||||
|
$email['body'] = $emailService->stripEmail($email['body']);
|
||||||
|
|
||||||
|
if (!empty($email['delete'])) {
|
||||||
|
if ($email['system_msg'] != 'Y') {
|
||||||
|
$this->deleteSQL('emails', ['id' => $id]);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($email['type'] == \KupShop\KupShopBundle\Email\BaseEmail::getType() && empty($email['email'])) {
|
||||||
|
$email['email'] = $settings->order_shopkeeper_mail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($id > 0) {
|
||||||
|
$this->updateSQL('emails', $email, ['id' => $id]);
|
||||||
|
} else {
|
||||||
|
$this->insertSQL('emails', $email, ['id']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$edited['order_shopkeeper_mail'] = $data['order_shopkeeper_mail'];
|
||||||
|
$edited['bounce_email'] = $data['bounce_email'];
|
||||||
|
$edited['archive_email'] = $data['archive_email'];
|
||||||
|
$edited['email_allowed_recipient_domains'] = $data['email_allowed_recipient_domains'];
|
||||||
|
|
||||||
|
if (!empty($data['smtp'])) {
|
||||||
|
$edited['smtp'] = $data['smtp'];
|
||||||
|
}
|
||||||
|
if (!empty($data['email_default_signature'])) {
|
||||||
|
$edited['email_default_signature'] = $data['email_default_signature'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$data['elninoEmailTemplates'] = array_filter($data['elninoEmailTemplates'] ?? [], function ($v) {
|
||||||
|
return $v['ticketState'] !== false && !empty($v['statuses']) && !empty($v['userMessage']) && empty($v['delete']);
|
||||||
|
});
|
||||||
|
if (!empty($data['elninoEmailTemplates'])) {
|
||||||
|
$data['elninoEmailTemplates'] = array_combine(range(1, count($data['elninoEmailTemplates'])), array_values($data['elninoEmailTemplates']));
|
||||||
|
}
|
||||||
|
$edited['elninoEmailTemplates'] = json_encode($data['elninoEmailTemplates']);
|
||||||
|
|
||||||
|
$settings->loadFromArray($edited);
|
||||||
|
|
||||||
|
if ($settings->saveToDB()) {
|
||||||
|
$ErrStr = $GLOBALS['txt_str']['status']['saved'];
|
||||||
|
} else {
|
||||||
|
$ErrStr = $GLOBALS['txt_str']['status']['scripterror'];
|
||||||
|
}
|
||||||
|
|
||||||
|
Settings::clearCache(true);
|
||||||
|
|
||||||
|
return $ErrStr;
|
||||||
|
}
|
||||||
|
}
|
||||||
9
admin/error.php
Normal file
9
admin/error.php
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class ErrorFrame extends Frame
|
||||||
|
{
|
||||||
|
protected $template = 'window/error.tpl';
|
||||||
|
}
|
||||||
|
|
||||||
|
$error = new ErrorFrame();
|
||||||
|
$error->run();
|
||||||
240
admin/export.php
Normal file
240
admin/export.php
Normal file
@@ -0,0 +1,240 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Admin;
|
||||||
|
|
||||||
|
use Export\ExportDataDBFUcto;
|
||||||
|
use KupShop\AdminBundle\Exception\ExportException;
|
||||||
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||||
|
use KupShop\OrderingBundle\OrdersExcelExport;
|
||||||
|
use KupShop\OrderingBundle\OrdersItemsExcelExport;
|
||||||
|
use Query\Operator;
|
||||||
|
|
||||||
|
class Export
|
||||||
|
{
|
||||||
|
public const EXPORT_TYPES_MAPPING = [
|
||||||
|
'products_selling' => 'productsSelling',
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $ORDERS_LIMIT = 100000;
|
||||||
|
|
||||||
|
protected $handled;
|
||||||
|
|
||||||
|
protected $encoding;
|
||||||
|
|
||||||
|
protected $format;
|
||||||
|
|
||||||
|
protected $params = [];
|
||||||
|
|
||||||
|
protected $orderIds = [];
|
||||||
|
|
||||||
|
protected $type;
|
||||||
|
|
||||||
|
public function setOrderIds($ids)
|
||||||
|
{
|
||||||
|
$this->orderIds = $ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setType($type)
|
||||||
|
{
|
||||||
|
$this->type = $type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setFormat($format)
|
||||||
|
{
|
||||||
|
$this->format = $format;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
$type = getVal('type', null, $this->type);
|
||||||
|
$data = getVal('data');
|
||||||
|
|
||||||
|
$this->format = getVal('format', null, $this->format);
|
||||||
|
$this->handled = getVal('what', $data);
|
||||||
|
$this->encoding = getVal('coding', null, 'utf-8');
|
||||||
|
|
||||||
|
$filter = getVal('filter');
|
||||||
|
if ($filter['date_handled']['to'] ?? false) {
|
||||||
|
$this->params['dateTo'] = $filter['date_handled']['to'];
|
||||||
|
} elseif ($filter['date_created']['to'] ?? false) {
|
||||||
|
$this->params['dateTo'] = $filter['date_created']['to'];
|
||||||
|
} else {
|
||||||
|
$this->params['dateTo'] = '';
|
||||||
|
}
|
||||||
|
if ($filter['date_handled']['from'] ?? false) {
|
||||||
|
$this->params['dateFrom'] = $filter['date_handled']['from'];
|
||||||
|
} elseif ($filter['date_created']['from'] ?? false) {
|
||||||
|
$this->params['dateFrom'] = $filter['date_created']['from'];
|
||||||
|
} else {
|
||||||
|
$this->params['dateFrom'] = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->params['data'] = getVal('data');
|
||||||
|
$this->params['format'] = $this->format;
|
||||||
|
|
||||||
|
if (array_key_exists($type, self::EXPORT_TYPES_MAPPING)) {
|
||||||
|
$type = self::EXPORT_TYPES_MAPPING[$type];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($type == 'orders') {
|
||||||
|
$report = 'Export objednávek: ';
|
||||||
|
$report .= 'format = '.$this->format.'; ';
|
||||||
|
$report .= ($this->params['dateFrom'] ? 'datum od = '.$this->params['dateFrom'].'; ' : '');
|
||||||
|
$report .= ($this->params['dateTo'] ? 'datum do = '.$this->params['dateTo'].'; ' : '');
|
||||||
|
$report .= (($this->handled == 'Y') ? 'jen vyřízené objednávky; ' : '');
|
||||||
|
writeDownActivity($report);
|
||||||
|
}
|
||||||
|
|
||||||
|
ini_set('memory_limit', '1024M');
|
||||||
|
ini_set('max_execution_time', '600');
|
||||||
|
|
||||||
|
try {
|
||||||
|
$method = 'export'.ucfirst($type);
|
||||||
|
if (method_exists($this, $method)) {
|
||||||
|
$this->$method();
|
||||||
|
} else {
|
||||||
|
$this->applyFallback();
|
||||||
|
}
|
||||||
|
} catch (ExportException $e) {
|
||||||
|
redirect('launch.php?s=board.php&type=export_orders&ErrStr='.urlencode($e->getMessage()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getOrderIdsToExport()
|
||||||
|
{
|
||||||
|
if (!empty($this->orderIds)) {
|
||||||
|
return $this->orderIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
$filter = getVal('filter');
|
||||||
|
$ordersFilterSpecs = ServiceContainer::getService(\KupShop\AdminBundle\Util\Filter\OrdersFilterSpecs::class);
|
||||||
|
$specs = $ordersFilterSpecs->getSpecs($filter);
|
||||||
|
$qb = sqlQueryBuilder()->select('o.id')->from('orders', 'o')
|
||||||
|
->setMaxResults($this->ORDERS_LIMIT)
|
||||||
|
->orderBy('o.id', 'ASC');
|
||||||
|
|
||||||
|
if ($specs) {
|
||||||
|
$qb->andWhere($specs);
|
||||||
|
}
|
||||||
|
|
||||||
|
$order_ids = getVal('order_ids');
|
||||||
|
|
||||||
|
if ($order_ids) {
|
||||||
|
$order_ids = explode(',', $order_ids);
|
||||||
|
$order_ids = array_map('trim', $order_ids);
|
||||||
|
$qb->andWhere(Operator::inStringArray($order_ids, 'o.order_no'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$orders = $qb->execute();
|
||||||
|
|
||||||
|
if ($orders->rowCount() >= $this->ORDERS_LIMIT) {
|
||||||
|
throw new ExportException('Export se nepodařil, protože byl překročen limit '.$this->ORDERS_LIMIT.' objednávek');
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_map(function ($x) {
|
||||||
|
return $x['id'];
|
||||||
|
}, $orders->fetchAll());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function exportOrders()
|
||||||
|
{
|
||||||
|
if (in_array($this->format, ['overview', 'excelOss', 'excel', 'excelWithItems'])) {
|
||||||
|
// Overview se renderuje u klienta, tak zvednem limit
|
||||||
|
$this->ORDERS_LIMIT = 1000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
include_once 'export/orders.php';
|
||||||
|
$export = new \ExportOrders();
|
||||||
|
$export->setOrderIds($this->getOrderIdsToExport());
|
||||||
|
|
||||||
|
if ($this->format == 'csv' || $this->format == 'csv_premier' || $this->format == 'csv_helios') {
|
||||||
|
$this->params['file_ext'] = 'csv';
|
||||||
|
$this->params['content_type'] = 'application/csv';
|
||||||
|
$export->exportData($this->params);
|
||||||
|
} elseif ($this->format == 'txt_premier') {
|
||||||
|
$this->params['file_ext'] = 'txt';
|
||||||
|
$this->params['content_type'] = 'application/txt';
|
||||||
|
$export->exportData($this->params);
|
||||||
|
} elseif ($this->format == 'dbf_ucto') {
|
||||||
|
$dateFrom = null;
|
||||||
|
$dateTo = null;
|
||||||
|
$filename_dates = '';
|
||||||
|
if (!empty($this->params['dateFrom'])) {
|
||||||
|
$dateFrom = new \DateTime($this->params['dateFrom']);
|
||||||
|
$filename_dates .= '_'.$dateFrom->format('Y-m-d');
|
||||||
|
}
|
||||||
|
if (!empty($this->params['dateTo'])) {
|
||||||
|
$dateTo = new \DateTime($this->params['dateTo']);
|
||||||
|
$filename_dates .= (empty($filename_dates) ? '_x-' : '-').$dateTo->format('Y-m-d');
|
||||||
|
} else {
|
||||||
|
if (!empty($filename_dates)) {
|
||||||
|
$filename_dates .= '-x';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$dbcfg = \Settings::getDefault();
|
||||||
|
|
||||||
|
$filename = createScriptURL_Text($dbcfg->shop_title).$filename_dates.'.dbf';
|
||||||
|
|
||||||
|
$ids = $export->getOrderIds();
|
||||||
|
|
||||||
|
$export = new ExportDataDBFUcto('browser', $filename);
|
||||||
|
$export->setCoding($this->encoding);
|
||||||
|
$export->initialize();
|
||||||
|
|
||||||
|
$export->loadOrdersData($ids);
|
||||||
|
|
||||||
|
$export->finalize();
|
||||||
|
} elseif ($this->format == 'pohoda' || $this->format == 'pohoda_with_items') {
|
||||||
|
$this->params['file_ext'] = 'xml';
|
||||||
|
$this->params['content_type'] = 'application/xml';
|
||||||
|
|
||||||
|
$export->exportData($this->params);
|
||||||
|
} elseif ($this->format == 'excel') {
|
||||||
|
/** @var $excelExport OrdersExcelExport */
|
||||||
|
$excelExport = ServiceContainer::getService(OrdersExcelExport::class);
|
||||||
|
$excelExport->setOrderIDs($this->getOrderIdsToExport());
|
||||||
|
$excelExport->export();
|
||||||
|
} elseif ($this->format == 'excelOss') {
|
||||||
|
$excelExport = ServiceContainer::getService(\KupShop\OSSVatsBundle\OssOrdersExcelExport::class);
|
||||||
|
$excelExport->setOrderIDs($this->getOrderIdsToExport());
|
||||||
|
$excelExport->export();
|
||||||
|
} elseif ($this->format == 'excelWithItems') {
|
||||||
|
/** @var $excelExport OrdersItemsExcelExport */
|
||||||
|
$excelExport = ServiceContainer::getService(OrdersItemsExcelExport::class);
|
||||||
|
$excelExport->setOrderIDs($this->getOrderIdsToExport());
|
||||||
|
$excelExport->export();
|
||||||
|
} elseif ($this->format == 'money' || $this->format == 'money_foreign' || $this->format == 'money_s4s5' || $this->format == 'flexibee') {
|
||||||
|
$this->params['file_ext'] = 'xml';
|
||||||
|
$this->params['content_type'] = 'application/xml';
|
||||||
|
$export->exportData($this->params);
|
||||||
|
} else {
|
||||||
|
$this->applyFallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function applyFallback()
|
||||||
|
{
|
||||||
|
$orderIds = $this->getOrderIdsToExport();
|
||||||
|
|
||||||
|
include_once 'export_sracka.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getOrderPayment(\Order $order)
|
||||||
|
{
|
||||||
|
if ($payment = $order->getDeliveryType()->getPayment()) {
|
||||||
|
switch ($payment->getPayMethod()) {
|
||||||
|
case \Payment::METHOD_COD:
|
||||||
|
return 'COD';
|
||||||
|
case \Payment::METHOD_CASH:
|
||||||
|
return 'CASH';
|
||||||
|
case \Payment::METHOD_TRANSFER:
|
||||||
|
return 'TRANSFER';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'COD';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Export::class;
|
||||||
109
admin/export/orders.php
Normal file
109
admin/export/orders.php
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||||
|
|
||||||
|
function ordersOutputBuffer($buffer, $phase)
|
||||||
|
{
|
||||||
|
return iconv('utf-8', getVal('coding', null, 'utf-8').'//TRANSLIT', $buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ExportOrders
|
||||||
|
{
|
||||||
|
/** @var KupShop\OrderingBundle\Util\Order\DeliveryInfo */
|
||||||
|
protected $deliveryInfoService;
|
||||||
|
|
||||||
|
protected $orderIds;
|
||||||
|
|
||||||
|
protected function setHeader($params)
|
||||||
|
{
|
||||||
|
if (!empty($params['dateFrom']) && !empty($params['dateTo'])) {
|
||||||
|
$filename = 'objednavky_'.$params['dateFrom'].'-'.$params['dateTo'];
|
||||||
|
} else {
|
||||||
|
$filename = 'objednavky_'.date('Y-m-d_H-i');
|
||||||
|
}
|
||||||
|
$filename .= '.'.$params['file_ext'];
|
||||||
|
|
||||||
|
header("Content-type: {$params['content_type']}");
|
||||||
|
header("Content-Disposition: attachment; filename=\"{$filename}\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setOrderIds($orderIds)
|
||||||
|
{
|
||||||
|
$this->orderIds = $orderIds;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getOrderIds()
|
||||||
|
{
|
||||||
|
return $this->orderIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function prepdate($date)
|
||||||
|
{
|
||||||
|
if (empty($date)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$date = new DateTime($date);
|
||||||
|
|
||||||
|
return $date->format('Y-m-d');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function exportData($params)
|
||||||
|
{
|
||||||
|
$this->setHeader($params);
|
||||||
|
|
||||||
|
/* @var KupShop\OrderingBundle\Util\Order\DeliveryInfo deliveryInfoService */
|
||||||
|
$this->deliveryInfoService = ServiceContainer::getService('KupShop\OrderingBundle\Util\Order\DeliveryInfo');
|
||||||
|
|
||||||
|
$where = 'o.id IN ('.(!empty($this->orderIds) ? join(',', $this->orderIds) : '0').')';
|
||||||
|
|
||||||
|
$orders = sqlQuery("SELECT o.id FROM orders o WHERE {$where}");
|
||||||
|
|
||||||
|
// Select all vats
|
||||||
|
$vats = sqlFetchAll(sqlQuery('SELECT vat, 0 tmp FROM vats ORDER BY vat'), ['vat' => 'tmp']);
|
||||||
|
|
||||||
|
// Append non-existent vats from orders
|
||||||
|
$vats_order = sqlQuery("SELECT distinct COALESCE(tax, 0) vat, 0 tmp
|
||||||
|
FROM orders as o
|
||||||
|
LEFT JOIN order_items oi on oi.id_order=o.id
|
||||||
|
WHERE {$where}
|
||||||
|
ORDER BY vat");
|
||||||
|
|
||||||
|
foreach ($vats_order as $row) {
|
||||||
|
if (!isset($vats[$row['vat']])) {
|
||||||
|
$vats[$row['vat']] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$smarty = createSmarty(true, true);
|
||||||
|
$smarty->assign([
|
||||||
|
'orders' => $orders,
|
||||||
|
'vats' => $vats,
|
||||||
|
'this' => $this,
|
||||||
|
]);
|
||||||
|
|
||||||
|
ob_start('ordersOutputBuffer', 4096);
|
||||||
|
|
||||||
|
$template = getVal('format', $params, $params['file_ext']);
|
||||||
|
|
||||||
|
$smarty->display("export/orders_{$template}.tpl");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getOrder($id_order)
|
||||||
|
{
|
||||||
|
$orderObj = new \Order($id_order);
|
||||||
|
$orderObj->createFromDB($id_order);
|
||||||
|
$orderObj->fetchItems();
|
||||||
|
$orderObj->fetchDates();
|
||||||
|
|
||||||
|
$orderObj->deliveryItemId = $this->deliveryInfoService->getDeliveryItem($orderObj);
|
||||||
|
|
||||||
|
if (is_null($orderObj->date_handle)) {
|
||||||
|
$orderObj->date_handle = $orderObj->date_created;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $orderObj;
|
||||||
|
}
|
||||||
|
}
|
||||||
3
admin/export/products_selling.php
Normal file
3
admin/export/products_selling.php
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class_alias('ExportProductsSelling', '\ExportProductsSelling');
|
||||||
551
admin/export_sracka.php
Normal file
551
admin/export_sracka.php
Normal file
@@ -0,0 +1,551 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace export_sracka;
|
||||||
|
|
||||||
|
use Query\Operator;
|
||||||
|
use XBase\Record;
|
||||||
|
use XBase\WritableTable;
|
||||||
|
|
||||||
|
global $cfg, $dbcfg;
|
||||||
|
|
||||||
|
$cfg['Order']['Status']['dispatch'][0] = 'čeká na odeslání';
|
||||||
|
$cfg['Order']['Status']['dispatch'][1] = 'částečně odesláno';
|
||||||
|
$cfg['Order']['Status']['dispatch'][2] = 'odesláno';
|
||||||
|
|
||||||
|
if (!findRight('EXPRT')) {
|
||||||
|
redirect('launch.php?s=error.php&id=1');
|
||||||
|
}
|
||||||
|
|
||||||
|
date_default_timezone_set('Europe/Prague');
|
||||||
|
|
||||||
|
$type = getVal('type');
|
||||||
|
$format = getVal('format');
|
||||||
|
$dateTo = getVal('dateTo');
|
||||||
|
$dateFrom = getVal('dateFrom');
|
||||||
|
$data = getVal('data');
|
||||||
|
$what = $data['what'];
|
||||||
|
$dateFromC = getVal('dateFromC');
|
||||||
|
$dateToC = getVal('dateToC');
|
||||||
|
$where = 'file';
|
||||||
|
|
||||||
|
function formatString2CSV($str, $format)
|
||||||
|
{
|
||||||
|
if ($format == 'csv') {
|
||||||
|
$str = str_replace('"', '""', $str);
|
||||||
|
$str = preg_replace("/\r?\n/i", ' ', $str);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $str;
|
||||||
|
}
|
||||||
|
|
||||||
|
$userAgent = 'MOZILLA';
|
||||||
|
|
||||||
|
$mime_type['file'] = ($userAgent == 'IE' || $userAgent == 'OPERA')
|
||||||
|
? 'application/octetstream'
|
||||||
|
: 'application/octet-stream';
|
||||||
|
$mime_type['excel'] = 'application/x-msexcel';
|
||||||
|
$mime_type['csv'] = 'text/comma-separated-values';
|
||||||
|
$mime_type['dbf'] = 'application/dbase';
|
||||||
|
$mime_type['overview'] = 'text/html';
|
||||||
|
|
||||||
|
$filename['excel'] = 'export.xls';
|
||||||
|
$filename['csv'] = 'export.csv';
|
||||||
|
$filename['dbf'] = 'export.dbf';
|
||||||
|
$filename['overview'] = 'export.html';
|
||||||
|
|
||||||
|
$file = '';
|
||||||
|
|
||||||
|
// ##############################################################
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ======================================================================
|
||||||
|
* EXPORT OBJEDNAVEK
|
||||||
|
* ======================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ($type == 'orders') {
|
||||||
|
$filename['excel'] = 'objednavky_'.date('Y-m-d_H-i-s').'.xls';
|
||||||
|
$filename['csv'] = 'objednavky_'.date('Y-m-d_H-i-s').'.csv';
|
||||||
|
$filename['dbf'] = 'objednavky_'.date('Y-m-d_H-i-s').'.dbf';
|
||||||
|
$filename['overview'] = 'objednavky_'.date('Y-m-d_H-i-s').'.html';
|
||||||
|
|
||||||
|
$var['fields'] = " id, id_user, order_no,
|
||||||
|
status, status_payed, status_dispatch, status_storno, total_price,
|
||||||
|
invoice_name, invoice_surname, invoice_firm, invoice_ico, invoice_dic,
|
||||||
|
invoice_street, invoice_city, invoice_zip, invoice_country, invoice_phone, invoice_email,
|
||||||
|
delivery_name, delivery_surname, delivery_firm, delivery_street, delivery_city,
|
||||||
|
delivery_zip, delivery_country, delivery_type, delivery_complete,
|
||||||
|
note_user, note_admin, date_handle,
|
||||||
|
DATE_FORMAT(date_created, '".$dbcfg['date_format'].' '.$dbcfg['time_format']."') AS datec,
|
||||||
|
DATE_FORMAT(date_accept, '".$dbcfg['date_format'].' '.$dbcfg['time_format']."') AS datea,
|
||||||
|
DATE_FORMAT(date_handle, '".$dbcfg['date_format'].' '.$dbcfg['time_format']."') AS dateh,
|
||||||
|
COALESCE(date_handle, date_accept, NOW()) + INTERVAL {$dbcfg->shop_due_days} DAY AS date_due,
|
||||||
|
flags
|
||||||
|
";
|
||||||
|
$var['from'] = ' '.getTableName('orders').' AS o ';
|
||||||
|
$var['where'] = ' 1 ';
|
||||||
|
$var['orderField'] = 'o.id';
|
||||||
|
$var['orderDir'] = 'ASC';
|
||||||
|
$var['order'] = ' ORDER BY '.$var['orderField'].' '.$var['orderDir'];
|
||||||
|
|
||||||
|
if (findModule('currencies')) {
|
||||||
|
$var['fields'] = str_replace('total_price', 'total_price, total_price*currency_rate as total_price_czk, currency, currency_rate', $var['fields']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
function prepdate($date)
|
||||||
|
{
|
||||||
|
if (empty($date)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$date = new \DateTime($date);
|
||||||
|
|
||||||
|
return $date->format('Y-m-d');
|
||||||
|
}
|
||||||
|
|
||||||
|
$var['where'] .= ' AND o.id IN ('.(!empty($orderIds) ? join(',', $orderIds) : '0').')';
|
||||||
|
|
||||||
|
$encode = function ($str) {
|
||||||
|
return iconv('utf-8', getVal('coding', null, 'utf-8').'//TRANSLIT', $str);
|
||||||
|
};
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
|
||||||
|
$var['query'] = 'SELECT '.$var['fields'].' FROM '.$var['from'].' WHERE '.$var['where'].' '.$var['order'];
|
||||||
|
|
||||||
|
// Invoice mass printing
|
||||||
|
if ($format == 'invoice') {
|
||||||
|
$where = 'screen';
|
||||||
|
|
||||||
|
$var['fields'] = 'id';
|
||||||
|
$SQL = sqlQuery('SELECT '.$var['fields'].' FROM '.$var['from'].' WHERE '.$var['where'].' '.$var['order']);
|
||||||
|
|
||||||
|
$file = '<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
<link rel="stylesheet" href="//www.w3.org/StyleSheets/Core/Steely" type="text/css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<form action="launch.php?s=printCenter.php&type=order&set=order" method="POST" target="_blank" >';
|
||||||
|
|
||||||
|
while (($row = sqlFetchAssoc($SQL)) !== false) {
|
||||||
|
$file .= "<input type='hidden' name='IDs[]' value='{$row['id']}' />";
|
||||||
|
}
|
||||||
|
|
||||||
|
$file .= '<input type="submit" value="vygenerovat faktury"></form></body></html>';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($format == 'overview') {
|
||||||
|
$where = 'screen';
|
||||||
|
}
|
||||||
|
|
||||||
|
$SQL = sqlQuery($var['query']);
|
||||||
|
|
||||||
|
if (sqlNumRows($SQL) > 0) {
|
||||||
|
if ($format == 'dbf' || $format == 'overview') {
|
||||||
|
$vats = sqlFetchAll(sqlQuery('SELECT DISTINCT COALESCE(tax, 0) vat FROM '.$var['from'].' LEFT JOIN order_items oi ON oi.id_order=o.id WHERE '.$var['where'].' ORDER BY vat'), 'vat');
|
||||||
|
$vats = array_map(function ($x) {
|
||||||
|
return \DecimalConstants::zero();
|
||||||
|
}, $vats);
|
||||||
|
|
||||||
|
$sumTaxes = $vats;
|
||||||
|
|
||||||
|
if ($format == 'overview') {
|
||||||
|
$file = '<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
<link rel="stylesheet" href="http://www.w3.org/StyleSheets/Core/Steely" type="text/css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<style>
|
||||||
|
th {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
padding-right: 21px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<table cellpadding="2">
|
||||||
|
<thead>
|
||||||
|
<th>číslo dokladu</th>
|
||||||
|
<th>datum vystavení</th>
|
||||||
|
<th>jmeno a přijmení</th>
|
||||||
|
';
|
||||||
|
foreach ($sumTaxes as $vat => $sum) {
|
||||||
|
$file .= "<th>základ dph {$vat}%</th>
|
||||||
|
<th>dph {$vat}%</th>";
|
||||||
|
}
|
||||||
|
|
||||||
|
$file .= '<th>celková částka</th>
|
||||||
|
<th>stav</th>
|
||||||
|
<th>poznámka</th>
|
||||||
|
</thead>
|
||||||
|
<tbody>';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($format == 'dbf') {
|
||||||
|
if ($where == 'file') {
|
||||||
|
header('Content-type: '.$mime_type[$format]);
|
||||||
|
header('Content-Disposition: attachment; filename="'.$filename[$format].'"');
|
||||||
|
header('Expires: 0');
|
||||||
|
header('Pragma: no-cache');
|
||||||
|
}
|
||||||
|
|
||||||
|
$oldErr = error_reporting(0);
|
||||||
|
|
||||||
|
/* sample data */
|
||||||
|
$fields = [
|
||||||
|
['DATUM_VYST', Record::DBFFIELD_TYPE_DATE], // datum vystavení
|
||||||
|
['DATUM_SPL', Record::DBFFIELD_TYPE_DATE], // prázdné
|
||||||
|
['DOKLAD_1', Record::DBFFIELD_TYPE_CHAR, 12], // aby tam bylo fčíslo objednávky např. f11521
|
||||||
|
['TYP_ZAP', Record::DBFFIELD_TYPE_CHAR, 1], // hodnota P
|
||||||
|
['ZNAK_UCT', Record::DBFFIELD_TYPE_CHAR, 5], // prázdné
|
||||||
|
['SYMBOLY', Record::DBFFIELD_TYPE_CHAR, 20], // včísloobjednávky např. v11521
|
||||||
|
['PAR_ZNAK', Record::DBFFIELD_TYPE_CHAR, 12], // to samé jako DOKLAD_1 např. f11521
|
||||||
|
['BANK_UCET', Record::DBFFIELD_TYPE_CHAR, 44], // prázdné
|
||||||
|
['SPEC_SYMB', Record::DBFFIELD_TYPE_CHAR, 10], // prázdné
|
||||||
|
['POPIS_TEXT', Record::DBFFIELD_TYPE_CHAR, 30], // libovolný text - např. prodej eshop-objednávka 11521
|
||||||
|
['DRUH_UCT', Record::DBFFIELD_TYPE_CHAR, 5], // hodnota PZ
|
||||||
|
['MENA', Record::DBFFIELD_TYPE_CHAR, 3], // buď Kč nebo EUR
|
||||||
|
['CELKEM_KC', Record::DBFFIELD_TYPE_FLOATING, 8, 2], // celková částka dokladu včetně DPH v Kč
|
||||||
|
['CELKEMCIZI', Record::DBFFIELD_TYPE_FLOATING, 8, 2], // celková částka dokladu v EUR - prodej na Slovensko?
|
||||||
|
['KURZ', Record::DBFFIELD_TYPE_FLOATING, 5, 3], // kurz pro přepočet
|
||||||
|
['DATUM_DPH', Record::DBFFIELD_TYPE_DATE], // datum DPH = datum vystavení
|
||||||
|
['TYP_DPH', Record::DBFFIELD_TYPE_CHAR, 5], // hodnota U
|
||||||
|
['ZAKL_DPH_Z', Record::DBFFIELD_TYPE_FLOATING, 8, 2], // Částka bez daně v základní sazbě
|
||||||
|
['DPH_Z', Record::DBFFIELD_TYPE_FLOATING, 8, 2], // Daň s azba 21 %
|
||||||
|
['ZAKL_DPH_S', Record::DBFFIELD_TYPE_FLOATING, 8, 2], // Částka bez daně ve snížené sazbě
|
||||||
|
['DPH_S', Record::DBFFIELD_TYPE_FLOATING, 8, 2], // Daň s azba 15 %
|
||||||
|
['TYPMIMODPH', Record::DBFFIELD_TYPE_CHAR, 1], // prázdné
|
||||||
|
['CASTKAMIMO', Record::DBFFIELD_TYPE_FLOATING, 8, 2], // prázdné
|
||||||
|
['STREDISKO', Record::DBFFIELD_TYPE_CHAR, 5], // PRÁZDNÉ
|
||||||
|
['vykon', Record::DBFFIELD_TYPE_CHAR, 5], // prázdné
|
||||||
|
['zakazka', Record::DBFFIELD_TYPE_CHAR, 5], // prázdné
|
||||||
|
['POZNAMKA', Record::DBFFIELD_TYPE_CHAR, 150], // sem naimportovat jméno a příjmění a město kupujícího JAN NOVAK TURNOV
|
||||||
|
['FIRMA', Record::DBFFIELD_TYPE_CHAR, 30], // Firma
|
||||||
|
['JMENO', Record::DBFFIELD_TYPE_CHAR, 30], // Jmeno
|
||||||
|
['PRIJMENI', Record::DBFFIELD_TYPE_CHAR, 30], // Prijmeni
|
||||||
|
['ICO', Record::DBFFIELD_TYPE_CHAR, 15], // ICO
|
||||||
|
['DIC', Record::DBFFIELD_TYPE_CHAR, 20], // DIC
|
||||||
|
|
||||||
|
['ZAKAZNIK', Record::DBFFIELD_TYPE_CHAR, 80], // Prijmeni nebo firma
|
||||||
|
['ULICE', Record::DBFFIELD_TYPE_CHAR, 50], // Adresa
|
||||||
|
['MESTO', Record::DBFFIELD_TYPE_CHAR, 30], // Adresa
|
||||||
|
['PSC', Record::DBFFIELD_TYPE_CHAR, 10], // Adresa
|
||||||
|
['ZEME', Record::DBFFIELD_TYPE_CHAR, 30], // Adresa
|
||||||
|
|
||||||
|
['STAV', Record::DBFFIELD_TYPE_CHAR, 10], // STORNO/PRODEJ
|
||||||
|
['DATUM_SPLAT', Record::DBFFIELD_TYPE_DATE], // datum splatnosti
|
||||||
|
['SAZBA_DPH_Z', Record::DBFFIELD_TYPE_FLOATING, 8, 2], // sazba DPH - zakladni
|
||||||
|
['SAZBA_DPH_S', Record::DBFFIELD_TYPE_FLOATING, 8, 2], // sazba DPH - snizena
|
||||||
|
];
|
||||||
|
|
||||||
|
/* create a new table */
|
||||||
|
$tableNew = WritableTable::create($cfg['Path']['data'].'export.dbf', $fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
$sumPrice = \DecimalConstants::zero();
|
||||||
|
|
||||||
|
while (($row = sqlFetchAssoc($SQL)) !== false) {
|
||||||
|
$taxes = $vats;
|
||||||
|
|
||||||
|
if ($row['status_storno']) {
|
||||||
|
$row['total_price_czk'] = 0;
|
||||||
|
$row['total_price'] = 0;
|
||||||
|
} else {
|
||||||
|
// Get vats
|
||||||
|
$query = "SELECT oi.tax, SUM(oi.total_price) price
|
||||||
|
FROM order_items oi
|
||||||
|
JOIN orders o ON o.id = oi.id_order
|
||||||
|
WHERE oi.id_order={$row['id']}
|
||||||
|
GROUP BY oi.tax";
|
||||||
|
|
||||||
|
if (findModule('currencies')) {
|
||||||
|
$query = str_replace('total_price', 'total_price*o.currency_rate', $query);
|
||||||
|
}
|
||||||
|
|
||||||
|
$i_SQL = sqlQuery($query);
|
||||||
|
|
||||||
|
foreach ($i_SQL as $i_row) {
|
||||||
|
$tax = strval($i_row['tax']);
|
||||||
|
$price = toDecimal($i_row['price']);
|
||||||
|
$taxes[$tax] = $price;
|
||||||
|
if (!isset($sumTaxes[$tax])) {
|
||||||
|
$sumTaxes[$tax] = \DecimalConstants::zero();
|
||||||
|
}
|
||||||
|
$sumTaxes[$tax] = $sumTaxes[$tax]->add($price);
|
||||||
|
}
|
||||||
|
$sumPrice = $sumPrice->add(toDecimal($row['total_price']));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($format == 'overview') {
|
||||||
|
$note = '';
|
||||||
|
if ($row['status_storno']) {
|
||||||
|
$note = 'STORNO';
|
||||||
|
}
|
||||||
|
$file .= "<tr>
|
||||||
|
<td>{$row['order_no']}</td>
|
||||||
|
<td>{$row['dateh']}</td>
|
||||||
|
<td>{$row['invoice_name']} {$row['invoice_surname']}, {$row['invoice_city']}</td>";
|
||||||
|
|
||||||
|
foreach ($taxes as $vat => $sum) {
|
||||||
|
$file .= "<td class='right'>".number_format($taxes[$vat]->asFloat(), 2, ',', '')."</td>
|
||||||
|
<td class='right'>".number_format($taxes[$vat]->mul(toDecimal($vat / 100))->asFloat(), 2, ',', '').'</td>';
|
||||||
|
}
|
||||||
|
|
||||||
|
$file .= "<td class='right'>".number_format($row['total_price'], 2, ',', '').'</td>
|
||||||
|
<td>'.$cfg['Order']['Status']['global'][$row['status']]."</td>
|
||||||
|
<td>{$note}</td>
|
||||||
|
</tr>";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($format == 'dbf') {
|
||||||
|
$r = $tableNew->appendRecord();
|
||||||
|
|
||||||
|
$total_price = roundPrice($row['total_price_czk']);
|
||||||
|
|
||||||
|
$vatsFormDB = sqlQueryBuilder()
|
||||||
|
->select('vat, is_default')
|
||||||
|
->from('vats')
|
||||||
|
->where(Operator::equals(['id_country' => $row['invoice_country'] ?: 'CZ']))
|
||||||
|
->orderBy('vat', 'DESC')
|
||||||
|
->execute()
|
||||||
|
->fetchAll();
|
||||||
|
|
||||||
|
$dph_z = 0;
|
||||||
|
foreach ($vatsFormDB as $vatRow) {
|
||||||
|
if ($vatRow['is_default'] == 'Y') {
|
||||||
|
$dph_z = $vatRow['vat'];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$dph_s = $vatsFormDB[1]['vat'] ?? 0;
|
||||||
|
|
||||||
|
if (!isset($taxes[$dph_z])) {
|
||||||
|
$taxes[$dph_z] = \DecimalConstants::zero();
|
||||||
|
}
|
||||||
|
if (!isset($taxes[$dph_s])) {
|
||||||
|
$taxes[$dph_s] = \DecimalConstants::zero();
|
||||||
|
}
|
||||||
|
if (!isset($taxes[0])) {
|
||||||
|
$taxes[0] = \DecimalConstants::zero();
|
||||||
|
}
|
||||||
|
|
||||||
|
$r->setObjectByName('DATUM_VYST', strtotime($row['date_handle'])); // datum vystavení
|
||||||
|
// $r->setObjectByName("DATUM_SPL", $row['DBFFIELD_TYPE_DATE']); //prázdné
|
||||||
|
$r->setObjectByName('DOKLAD_1', $row['order_no']); // aby tam bylo fčíslo objednávky např. f11521
|
||||||
|
$r->setObjectByName('TYP_ZAP', 'P'); // hodnota P
|
||||||
|
$r->setObjectByName('ZNAK_UCT', ''); // prázdné
|
||||||
|
$r->setObjectByName('SYMBOLY', $row['id']); // včísloobjednávky např. v11521
|
||||||
|
$r->setObjectByName('PAR_ZNAK', $row['order_no']); // to samé jako DOKLAD_1 např. f11521
|
||||||
|
$r->setObjectByName('BANK_UCET', ''); // prázdné
|
||||||
|
$r->setObjectByName('SPEC_SYMB', ''); // prázdné
|
||||||
|
$r->setObjectByName('POPIS_TEXT', $encode('Objednávka: '.$row['id'])); // libovolný text - např. prodej eshop-objednávka 11521
|
||||||
|
$r->setObjectByName('DRUH_UCT', 'PZ'); // hodnota PZ
|
||||||
|
$r->setObjectByName('MENA', $row['currency']); // buď Kč nebo EUR
|
||||||
|
$r->setObjectByName('CELKEM_KC', $total_price->printFloatValue(2)); // celková částka dokladu včetně DPH v Kč
|
||||||
|
$r->setObjectByName('CELKEMCIZI', ($row['currency'] == 'CZK') ? 0 : toDecimal($row['total_price'])->printFloatValue(2)); // celková částka dokladu v EUR - prodej na Slovensko?
|
||||||
|
$r->setObjectByName('KURZ', $row['currency_rate']); // kurz pro přepočet
|
||||||
|
$r->setObjectByName('DATUM_DPH', strtotime($row['date_handle'])); // datum DPH = datum vystavení
|
||||||
|
$r->setObjectByName('TYP_DPH', 'U'); // hodnota U
|
||||||
|
$r->setObjectByName('ZAKL_DPH_Z', $taxes[$dph_z]->printFloatValue(2)); // Částka bez daně v základní sazbě
|
||||||
|
$r->setObjectByName('DPH_Z', $taxes[$dph_z]->mul(toDecimal($dph_z / 100))->printFloatValue(2)); // Daň sazba 21 %
|
||||||
|
$r->setObjectByName('ZAKL_DPH_S', $taxes[$dph_s]->printFloatValue(2)); // Částka bez daně ve snížené sazbě
|
||||||
|
$r->setObjectByName('DPH_S', $taxes[$dph_s]->mul(toDecimal($dph_z / 100))->printFloatValue(2)); // Částka bez daně ve snížené sazbě
|
||||||
|
$r->setObjectByName('TYPMIMODPH', ''); // prázdné
|
||||||
|
$r->setObjectByName('CASTKAMIMO', $taxes['0']->printFloatValue(2)); // prázdné
|
||||||
|
$r->setObjectByName('STREDISKO', ''); // PRÁZDNÉ
|
||||||
|
$r->setObjectByName('vykon', ''); // prázdné
|
||||||
|
$r->setObjectByName('zakazka', ''); // prázdné
|
||||||
|
$r->setObjectByName('POZNAMKA', $encode("{$row['invoice_name']} {$row['invoice_surname']}, {$row['invoice_city']}")); // sem naimportovat jméno a příjmění a město kupujícího JAN NOVAK TURNOV
|
||||||
|
$r->setObjectByName('FIRMA', $encode($row['invoice_firm'])); // Firma
|
||||||
|
$r->setObjectByName('JMENO', $encode($row['invoice_name'])); // Jmeno
|
||||||
|
$r->setObjectByName('PRIJMENI', $encode($row['invoice_surname'])); // Prijmeni
|
||||||
|
|
||||||
|
$r->setObjectByName('ICO', $row['invoice_ico']); // ICO
|
||||||
|
$r->setObjectByName('DIC', $row['invoice_dic']); // DIC
|
||||||
|
|
||||||
|
$r->setObjectByName('ZAKAZNIK', $encode($row['invoice_firm'] ? $row['invoice_firm'] : "{$row['invoice_name']} {$row['invoice_surname']}")); // Prijmeni nebo firma
|
||||||
|
$r->setObjectByName('ULICE', $encode($row['invoice_street']));
|
||||||
|
$r->setObjectByName('MESTO', $encode($row['invoice_city']));
|
||||||
|
$r->setObjectByName('PSC', $row['invoice_zip']);
|
||||||
|
$r->setObjectByName('ZEME', $encode($row['invoice_country']));
|
||||||
|
|
||||||
|
$r->setObjectByName('STAV', $row['status_storno'] ? 'STORNO' : 'PRODEJ'); // STORNO/PRODEJ
|
||||||
|
$r->setObjectByName('DATUM_SPLAT', strtotime($row['date_due']));
|
||||||
|
$r->setObjectByName('SAZBA_DPH_Z', $dph_z);
|
||||||
|
$r->setObjectByName('SAZBA_DPH_S', $dph_s);
|
||||||
|
$tableNew->writeRecord();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($format == 'overview') {
|
||||||
|
$file .= '<tr><td> </td></tr>
|
||||||
|
<thead>
|
||||||
|
<th></th>
|
||||||
|
<th></th>
|
||||||
|
<th></th>';
|
||||||
|
foreach ($sumTaxes as $tax => $sum) {
|
||||||
|
$file .= "
|
||||||
|
<th>zaklad dph {$tax}%</th>
|
||||||
|
<th>dph {$tax}%</th>
|
||||||
|
";
|
||||||
|
}
|
||||||
|
|
||||||
|
$file .= '
|
||||||
|
<th>celková částka</th>
|
||||||
|
<th></th>
|
||||||
|
<th></th>
|
||||||
|
</thead>
|
||||||
|
<tr>
|
||||||
|
<td/><td/><td><b>CELKEM:</b></td>
|
||||||
|
';
|
||||||
|
foreach ($sumTaxes as $tax => $sum) {
|
||||||
|
$file .= " <td class='right'><b>".number_format($sum->asFloat(), 2, ',', '')."</b></td>
|
||||||
|
<td class='right'><b>".number_format($sum->mul(toDecimal($tax / 100))->asFloat(), 2, ',', '').'</b></td>
|
||||||
|
';
|
||||||
|
}
|
||||||
|
|
||||||
|
$file .= "<td class='right'><b>".number_format($sumPrice->asFloat(), 2, ',', '').'</b></td>
|
||||||
|
<tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($format == 'dbf') {
|
||||||
|
/* close the table */
|
||||||
|
$tableNew->close();
|
||||||
|
|
||||||
|
error_reporting($oldErr);
|
||||||
|
|
||||||
|
readfile($cfg['Path']['data'].'export.dbf');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
} elseif ($format == 'csv') {
|
||||||
|
$file = '"Kód";"Stav objednávky";"Stav zaplacení";"Stav expedice";"Stav storna";"Datum objednávky";'.
|
||||||
|
'"Datum přijetí";"Datum vyřízení";"Počet položek";"Cena ('.$dbcfg['currency'].')";'.
|
||||||
|
'"Jméno";"Příjmení";"Firma";"Email";"Telefon";"Ulice";"Město";"PSČ";"Země";"IČO";"DIČ";'.
|
||||||
|
'"Doruč.jméno";"Doruč.příjmení";"Doruč.firma";"Doruč.ulice";"Doruč.město";"Doruč.PSČ";"Doruč.země";'.
|
||||||
|
'"Doručit jen kompletně";"Pozn.pro zákazníka";"Pozn.pro obchodníka";"Příznaky"'."\r\n\r\n";
|
||||||
|
$rowtpl = '"{O_NO}";"{STATUS}";"{STATUS_PAYED}";"{STATUS_DISPATCH}";"{STATUS_STORNO}";'.
|
||||||
|
'"{DATE_CREATED}";"{DATE_ACCEPT}";"{DATE_HANDLE}";"{ITEMS}";"{PRICE}";"{INV_NAME}";"{INV_SURNAME}";'.
|
||||||
|
'"{INV_FIRM}";"{INV_EMAIL}";"{INV_PHONE}";"{INV_STREET}";"{INV_CITY}";"{INV_ZIP}";"{INV_COUNTRY}";'.
|
||||||
|
'"{INV_ICO}";"{INV_DIC}";"{DEL_NAME}";"{DEL_SURNAME}";"{DEL_FIRM}";"{DEL_STREET}";"{DEL_CITY}";'.
|
||||||
|
'"{DEL_ZIP}";"{DEL_COUNTRY}";"{DEL_COMPLETE}";"{NOTE_ADMIN}";"{NOTE_USER}";"{FLAGS}"'."\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($format == 'csv') {
|
||||||
|
while ($row = sqlFetchArray($SQL)) {
|
||||||
|
// kontrola delky zpracovani skriptu
|
||||||
|
controlTimeLimit();
|
||||||
|
|
||||||
|
$order = new \Order();
|
||||||
|
$order->createFromDB($row['id']);
|
||||||
|
$order->fetchItems();
|
||||||
|
|
||||||
|
$i_row = ['items' => count($order->items)];
|
||||||
|
|
||||||
|
$rowtpl_t = $rowtpl;
|
||||||
|
|
||||||
|
$rowtpl_t = str_replace('{O_NO}', $row['order_no'], $rowtpl_t);
|
||||||
|
$rowtpl_t = str_replace('{ITEMS}', $i_row['items'], $rowtpl_t);
|
||||||
|
if (findModule('currencies')) {
|
||||||
|
$rowtpl_t = str_replace('.', ',', str_replace('{PRICE}', number_format($row['total_price'], 2, '.', ''), $rowtpl_t));
|
||||||
|
$rowtpl_t = str_replace('{MENA}', $row['currency'], $rowtpl_t);
|
||||||
|
$rowtpl_t = str_replace('{KURZ}', $row['currency_rate'], $rowtpl_t);
|
||||||
|
$rowtpl_t = str_replace('.', ',', str_replace('{PRICE_CZK}', number_format($row['total_price_czk'], 2, '.', ''), $rowtpl_t));
|
||||||
|
} else {
|
||||||
|
$rowtpl_t = str_replace('.', ',', str_replace('{PRICE}', number_format($row['total_price'], 2, '.', ''), $rowtpl_t));
|
||||||
|
}
|
||||||
|
if (findModule(\Modules::PRODUCTS, \Modules::SUB_WEIGHT)) {
|
||||||
|
$order = new \Order();
|
||||||
|
$order->createFromDB($row['id']);
|
||||||
|
$rowtpl_t = str_replace('{O_WEIGHT}', $order->getTotalWeight(), $rowtpl_t);
|
||||||
|
}
|
||||||
|
$rowtpl_t = str_replace('{STATUS}', formatString2CSV($cfg['Order']['Status']['global'][$row['status']], $format), $rowtpl_t);
|
||||||
|
$rowtpl_t = str_replace('{STATUS_PAYED}', formatString2CSV($cfg['Order']['Status']['payed'][$row['status_payed']], $format), $rowtpl_t);
|
||||||
|
$rowtpl_t = str_replace('{STATUS_DISPATCH}', formatString2CSV($cfg['Order']['Status']['dispatch'][$row['status_dispatch']], $format), $rowtpl_t);
|
||||||
|
$rowtpl_t = str_replace('{STATUS_STORNO}', formatString2CSV($cfg['Order']['Status']['storno'][$row['status_storno']], $format), $rowtpl_t);
|
||||||
|
$rowtpl_t = str_replace('{DATE_CREATED}', $row['datec'], $rowtpl_t);
|
||||||
|
$rowtpl_t = str_replace('{DATE_ACCEPT}', $row['datea'], $rowtpl_t);
|
||||||
|
$rowtpl_t = str_replace('{DATE_HANDLE}', $row['dateh'], $rowtpl_t);
|
||||||
|
|
||||||
|
$rowtpl_t = str_replace('{DEL_COMPLETE}', ($row['delivery_complete'] == 'Y') ? 'Ano' : 'Ne', $rowtpl_t);
|
||||||
|
|
||||||
|
$rowtpl_t = str_replace('{INV_NAME}', formatString2CSV($row['invoice_name'], $format), $rowtpl_t);
|
||||||
|
$rowtpl_t = str_replace('{INV_SURNAME}', formatString2CSV($row['invoice_surname'], $format), $rowtpl_t);
|
||||||
|
$rowtpl_t = str_replace('{INV_FIRM}', formatString2CSV($row['invoice_firm'], $format), $rowtpl_t);
|
||||||
|
$rowtpl_t = str_replace('{INV_EMAIL}', formatString2CSV($row['invoice_email'], $format), $rowtpl_t);
|
||||||
|
$rowtpl_t = str_replace('{INV_PHONE}', formatString2CSV($row['invoice_phone'], $format), $rowtpl_t);
|
||||||
|
$rowtpl_t = str_replace('{INV_STREET}', formatString2CSV($row['invoice_street'], $format), $rowtpl_t);
|
||||||
|
$rowtpl_t = str_replace('{INV_CITY}', formatString2CSV($row['invoice_city'], $format), $rowtpl_t);
|
||||||
|
$rowtpl_t = str_replace('{INV_ZIP}', formatString2CSV($row['invoice_zip'], $format), $rowtpl_t);
|
||||||
|
$rowtpl_t = str_replace('{INV_COUNTRY}', formatString2CSV($row['invoice_country'], $format), $rowtpl_t);
|
||||||
|
$rowtpl_t = str_replace('{INV_ICO}', formatString2CSV($row['invoice_ico'], $format), $rowtpl_t);
|
||||||
|
$rowtpl_t = str_replace('{INV_DIC}', formatString2CSV($row['invoice_dic'], $format), $rowtpl_t);
|
||||||
|
$rowtpl_t = str_replace('{DEL_NAME}', formatString2CSV($row['delivery_name'], $format), $rowtpl_t);
|
||||||
|
$rowtpl_t = str_replace('{DEL_SURNAME}', formatString2CSV($row['delivery_surname'], $format), $rowtpl_t);
|
||||||
|
$rowtpl_t = str_replace('{DEL_FIRM}', formatString2CSV($row['delivery_firm'], $format), $rowtpl_t);
|
||||||
|
$rowtpl_t = str_replace('{DEL_STREET}', formatString2CSV($row['delivery_street'], $format), $rowtpl_t);
|
||||||
|
$rowtpl_t = str_replace('{DEL_CITY}', formatString2CSV($row['delivery_city'], $format), $rowtpl_t);
|
||||||
|
$rowtpl_t = str_replace('{DEL_ZIP}', formatString2CSV($row['delivery_zip'], $format), $rowtpl_t);
|
||||||
|
$rowtpl_t = str_replace('{DEL_COUNTRY}', formatString2CSV($row['delivery_country'], $format), $rowtpl_t);
|
||||||
|
|
||||||
|
$rowtpl_t = str_replace('{NOTE_ADMIN}', formatString2CSV($row['note_admin'], $format), $rowtpl_t);
|
||||||
|
$rowtpl_t = str_replace('{NOTE_USER}', formatString2CSV($row['note_user'], $format), $rowtpl_t);
|
||||||
|
$rowtpl_t = str_replace('{FLAGS}', $row['flags'], $rowtpl_t);
|
||||||
|
|
||||||
|
$deliveryType = explode('-', $row['delivery_type']);
|
||||||
|
|
||||||
|
$rowtpl_t = str_replace('{DELIVERY}', $deliveryType[1] ?? '', $rowtpl_t);
|
||||||
|
$rowtpl_t = str_replace('{PAYMENT}', $deliveryType[0] ?? '', $rowtpl_t);
|
||||||
|
|
||||||
|
$file .= $rowtpl_t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// kontrola delky zpracovani skriptu
|
||||||
|
controlTimeLimit();
|
||||||
|
|
||||||
|
// ###########################
|
||||||
|
// KAM EXPORTOVAT
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
if ($where == 'screen') {
|
||||||
|
if ($format == 'csv') {
|
||||||
|
header('Content-type: '.$mime_type['csv']);
|
||||||
|
// vytisknout
|
||||||
|
echo $file;
|
||||||
|
} else {
|
||||||
|
echo $file;
|
||||||
|
}
|
||||||
|
} elseif // ============================================
|
||||||
|
($where == 'file'
|
||||||
|
) {
|
||||||
|
header('Content-type: '.$mime_type['file']);
|
||||||
|
if ($userAgent == 'IE') {
|
||||||
|
header('Content-Disposition: attachment; filename="'.$filename[$format].'"');
|
||||||
|
header('Expires: 0');
|
||||||
|
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||||
|
header('Pragma: public');
|
||||||
|
} else {
|
||||||
|
header('Content-Disposition: attachment; filename="'.$filename[$format].'"');
|
||||||
|
header('Expires: 0');
|
||||||
|
header('Pragma: no-cache');
|
||||||
|
}
|
||||||
|
// vytisknout
|
||||||
|
echo $file;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// ###########################
|
||||||
|
|
||||||
|
// ##############################################################
|
||||||
68
admin/fulltext.php
Normal file
68
admin/fulltext.php
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use KupShop\CatalogBundle\Search\FulltextInterface;
|
||||||
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||||
|
|
||||||
|
$main_class = 'fulltext';
|
||||||
|
|
||||||
|
class fulltext extends Window
|
||||||
|
{
|
||||||
|
use \KupShop\AdminBundle\FulltextUpdatesTrait;
|
||||||
|
|
||||||
|
public function get_vars()
|
||||||
|
{
|
||||||
|
$vars = parent::get_vars();
|
||||||
|
|
||||||
|
/** @var FulltextInterface $fulltext */
|
||||||
|
$fulltext = ServiceContainer::getService(FulltextInterface::class);
|
||||||
|
|
||||||
|
$vars['synonyms'] = $fulltext->loadSynonyms();
|
||||||
|
$vars['support'] = true;
|
||||||
|
|
||||||
|
return $vars;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
if (!getVal('Submit') && !getVal('Reindex')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var FulltextInterface $fulltext */
|
||||||
|
$fulltext = ServiceContainer::getService(FulltextInterface::class);
|
||||||
|
$data = $this->getData();
|
||||||
|
$synonyms = [];
|
||||||
|
|
||||||
|
foreach ($data as $line) {
|
||||||
|
if (!empty($line['from']) && !empty($line['to']) && !key_exists('delete', $line)) {
|
||||||
|
$synonyms[] = $line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$fulltext->updateSynonyms($synonyms);
|
||||||
|
|
||||||
|
if (getVal('Reindex')) {
|
||||||
|
ini_set('max_execution_time', 500);
|
||||||
|
try {
|
||||||
|
$this->updateIndices();
|
||||||
|
} catch (\KupShop\CatalogBundle\Search\Exception\FulltextException $e) {
|
||||||
|
getRaven()->captureException($e);
|
||||||
|
$this->returnError('Nastala chyba při generování vyhledávácího indexu');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->handleTabs(true);
|
||||||
|
|
||||||
|
$this->returnOK();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasRights($name = null)
|
||||||
|
{
|
||||||
|
switch ($name) {
|
||||||
|
case Window::RIGHT_DUPLICATE:
|
||||||
|
case Window::RIGHT_DELETE:
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
return parent::hasRights($name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
210
admin/functions.admin.php
Normal file
210
admin/functions.admin.php
Normal file
@@ -0,0 +1,210 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use KupShop\KupShopBundle\Exception\RedirectException;
|
||||||
|
|
||||||
|
if (!function_exists('getTextString')) {
|
||||||
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
|
||||||
|
/**
|
||||||
|
* @deprecated Use translate($key, $section) instead
|
||||||
|
*/
|
||||||
|
function getTextString($section, $key)
|
||||||
|
{
|
||||||
|
return translate($key, $section);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
|
||||||
|
function findRight($right, $var = null)
|
||||||
|
{
|
||||||
|
// kdyz nejsou dodany vlastni prava
|
||||||
|
if (is_null($var)) {
|
||||||
|
// kdyz se jedna o superadmina
|
||||||
|
if (isSuperuser()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$adminUser = getAdminUser();
|
||||||
|
$var = $adminUser ? $adminUser['privilege'] : '';
|
||||||
|
}
|
||||||
|
if (preg_match("/\b{$right}/i", $var) || preg_match('/ALL_RIGHTS/i', $var)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
|
||||||
|
function redirect($URL, $type = 'header')
|
||||||
|
{
|
||||||
|
if ($URL == 'REFERER') {
|
||||||
|
if (!empty($_SERVER['HTTP_REFERER'])) {
|
||||||
|
$URL = $_SERVER['HTTP_REFERER'];
|
||||||
|
} else {
|
||||||
|
$URL = './';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isLocalDevelopment()) {
|
||||||
|
throw new RedirectException($URL);
|
||||||
|
}
|
||||||
|
if (!headers_sent() && $type == 'header') {
|
||||||
|
if (ob_get_length() > 0) {
|
||||||
|
flush();
|
||||||
|
}
|
||||||
|
header('Location: '.$URL);
|
||||||
|
exit;
|
||||||
|
} elseif (headers_sent() || $type == 'script' || $type == 'script_this_win') {
|
||||||
|
$ret = "<script type=\"text/javascript\" language=\"javascript\">\n";
|
||||||
|
switch ($type) {
|
||||||
|
case 'script':
|
||||||
|
$ret .= "top.window.location='".$URL."&js=1';\n";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
case 'script_this_win':
|
||||||
|
$ret .= "this.window.location='".$URL."&js=1';\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$ret .= "</script>\n";
|
||||||
|
echo $ret;
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
|
||||||
|
// danemu retezci je pridano na konec napis Kopie
|
||||||
|
function stringCopy($str)
|
||||||
|
{
|
||||||
|
if (preg_match('/.+\\(Kopie[[:blank:]]*([0-9]+)?\\)/i', $str, $cut)) {
|
||||||
|
$no = intval(getVal('1', $cut));
|
||||||
|
$no = ($no == 0) ? 2 : ($no + 1);
|
||||||
|
$end = '(Kopie '.$no.')';
|
||||||
|
$str = preg_replace('/\\(Kopie[^\\)]*\\)/i', $end, $str);
|
||||||
|
} else {
|
||||||
|
$str = rtrim($str).' (Kopie)';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $str;
|
||||||
|
}
|
||||||
|
|
||||||
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
|
||||||
|
function categoryTreeOption($topCat, $Pos, $selected, $without = null)
|
||||||
|
{
|
||||||
|
$where = " sr.id_topsection='{$topCat}' ";
|
||||||
|
if (!empty($without)) {
|
||||||
|
$where .= " AND id_section<>'{$without}' ";
|
||||||
|
}
|
||||||
|
|
||||||
|
$SQL = sqlQuery('SELECT s.id, s.name, s.figure
|
||||||
|
FROM '.getTableName('sections_relation').' AS sr LEFT JOIN '.getTableName('sections')." AS s ON s.id=sr.id_section
|
||||||
|
WHERE {$where}
|
||||||
|
ORDER BY sr.position ASC, s.name ASC");
|
||||||
|
$Found = sqlNumRows($SQL);
|
||||||
|
for ($i = 0; $i < $Found; $i++) {
|
||||||
|
$topCat = sqlResult($SQL, $i, 'id');
|
||||||
|
$Name = sqlResult($SQL, $i, 'name');
|
||||||
|
|
||||||
|
echo '<option value="'.$topCat.'"'.checkSelect($selected, $topCat).'>';
|
||||||
|
for ($x = 0; $x < $Pos; $x++) {
|
||||||
|
echo ' ';
|
||||||
|
}
|
||||||
|
echo htmlspecialchars($Name);
|
||||||
|
echo "</option>\r\n";
|
||||||
|
|
||||||
|
categoryTreeOption($topCat, $Pos + 1, $selected, $without);
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlFreeResult($SQL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
|
||||||
|
function access($modules = [], $rights = [])
|
||||||
|
{
|
||||||
|
while (true) {
|
||||||
|
foreach ($modules as $module) {
|
||||||
|
if (findModule($module)) {
|
||||||
|
break 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($rights as $right) {
|
||||||
|
if (findRight($right)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
|
||||||
|
function prepareDate($datetime)
|
||||||
|
{
|
||||||
|
if (empty($datetime)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
$format = '%d-%m-%Y';
|
||||||
|
|
||||||
|
$tm = strptime($datetime, $format);
|
||||||
|
$stmp = mktime(0, 0, 0, $tm['tm_mon'] + 1, $tm['tm_mday'], $tm['tm_year'] + 1900);
|
||||||
|
$time = date('Y-m-d', $stmp);
|
||||||
|
|
||||||
|
return $time;
|
||||||
|
}
|
||||||
|
|
||||||
|
function prepareDateTime($datetime)
|
||||||
|
{
|
||||||
|
if (empty($datetime)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
$format = '%d-%m-%Y %H:%M:%S';
|
||||||
|
|
||||||
|
$tm = strptime($datetime, $format);
|
||||||
|
$stmp = mktime($tm['tm_hour'], $tm['tm_min'], $tm['tm_sec'], $tm['tm_mon'] + 1, $tm['tm_mday'], $tm['tm_year'] + 1900);
|
||||||
|
$time = date('Y-m-d H:i:s', $stmp);
|
||||||
|
|
||||||
|
return $time;
|
||||||
|
}
|
||||||
|
|
||||||
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
|
||||||
|
function prepareDateForDialog($datetime)
|
||||||
|
{
|
||||||
|
if (empty($datetime)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
$format = '%Y-%m-%d';
|
||||||
|
|
||||||
|
$tm = strptime($datetime, $format);
|
||||||
|
$stmp = mktime(0, 0, 0, $tm['tm_mon'] + 1, $tm['tm_mday'], $tm['tm_year'] + 1900);
|
||||||
|
$time = date('d-m-Y', $stmp);
|
||||||
|
|
||||||
|
return $time;
|
||||||
|
}
|
||||||
|
|
||||||
|
function prepareDateTimeForDialog($datetime)
|
||||||
|
{
|
||||||
|
if (empty($datetime)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
$format = '%Y-%m-%d %H:%M:%S';
|
||||||
|
|
||||||
|
$tm = strptime($datetime, $format);
|
||||||
|
$stmp = mktime($tm['tm_hour'], $tm['tm_min'], $tm['tm_sec'], $tm['tm_mon'] + 1, $tm['tm_mday'], $tm['tm_year'] + 1900);
|
||||||
|
$time = date('d-m-Y H:i:s', $stmp);
|
||||||
|
|
||||||
|
return $time;
|
||||||
|
}
|
||||||
|
|
||||||
|
function switchLanguage($lang, $restore = false)
|
||||||
|
{
|
||||||
|
global $txt_str, $temp_lang, $temp_txt_str, $cfg;
|
||||||
|
if (!$restore) {
|
||||||
|
$temp_txt_str = $txt_str;
|
||||||
|
$temp_lang = $cfg['Lang']['language'];
|
||||||
|
$cfg['Lang']['language'] = $lang;
|
||||||
|
} else {
|
||||||
|
$txt_str = $temp_txt_str;
|
||||||
|
$cfg['Lang']['language'] = $temp_lang;
|
||||||
|
}
|
||||||
|
}
|
||||||
65
admin/functions.php
Normal file
65
admin/functions.php
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// Modify directories path
|
||||||
|
$cfg['Path']['web_root'] = '';
|
||||||
|
|
||||||
|
function autoload_admin($className)
|
||||||
|
{
|
||||||
|
global $cfg;
|
||||||
|
static $subclass = 0;
|
||||||
|
|
||||||
|
if (strpos($className, 'Admin\\') !== false) {
|
||||||
|
if (strpos($className, '\\Lists\\') !== false) {
|
||||||
|
$className = str_replace('Admin\\Lists\\', 'admin/lists/', $className);
|
||||||
|
$class = $cfg['Path']['shared_version'].$className.'.php';
|
||||||
|
} elseif (strpos($className, '\\Menu\\') !== false) {
|
||||||
|
$className = str_replace('Admin\\Menu\\', 'admin/menu/', $className);
|
||||||
|
$class = $cfg['Path']['shared_version'].$className.'.php';
|
||||||
|
} else {
|
||||||
|
$class = $cfg['Path']['shared_version'].strtolower(strtr($className, '\\', '/')).'.php';
|
||||||
|
if (!file_exists($class)) {
|
||||||
|
$class = $cfg['Path']['shared_version'].lcfirst(strtr($className, '\\', '/')).'.php';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file_exists($class)) {
|
||||||
|
require_once $class;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strpos($className, '\\')) {
|
||||||
|
$class = $cfg['Path']['shared_version'].'class/'.strtr($className, '\\', '/').'.php';
|
||||||
|
if (file_exists($class)) {
|
||||||
|
require_once $class;
|
||||||
|
}
|
||||||
|
|
||||||
|
$class = $cfg['Path']['shared_version'].'admin/class/'.strtr($className, '\\', '/').'.php';
|
||||||
|
if (file_exists($class)) {
|
||||||
|
require_once $class;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file_exists("class.{$className}.php")) {
|
||||||
|
$subclass++;
|
||||||
|
require_once $cfg['Path']['shared_version']."admin/class/class.{$className}.php";
|
||||||
|
require_once "class.{$className}.php";
|
||||||
|
$subclass--;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file_exists($cfg['Path']['shared_version']."admin/class/class.{$className}.php")) {
|
||||||
|
require_once $cfg['Path']['shared_version']."admin/class/class.{$className}.php";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load shared functions from web
|
||||||
|
require_once $cfg['Path']['shared_version'].'web/functions.common.php';
|
||||||
|
|
||||||
|
// Load admin specific functions
|
||||||
|
require_once $cfg['Path']['shared_version'].'admin/functions.admin.php';
|
||||||
|
|
||||||
|
// Not using class.Modules because that would require autoloader
|
||||||
|
if (!findModule('components')) {
|
||||||
|
spl_autoload_register('autoload_admin');
|
||||||
|
}
|
||||||
60
admin/help/index.php
Normal file
60
admin/help/index.php
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$main_class = 'HelpIndex';
|
||||||
|
|
||||||
|
class HelpIndex extends Window
|
||||||
|
{
|
||||||
|
protected $template = 'help/index.tpl';
|
||||||
|
public static $url = [
|
||||||
|
'productsVarLabels' => 'http://www.napoveda.wpj.cz/kupshop/produkty/varianty/',
|
||||||
|
'products' => 'http://www.napoveda.wpj.cz/kupshop/produkty/',
|
||||||
|
'discounts' => 'http://www.napoveda.wpj.cz/kupshop/zpracovani-objednavky/slevy/',
|
||||||
|
'orders' => 'http://www.napoveda.wpj.cz/kupshop/zpracovani-objednavky/stav-objednavky/',
|
||||||
|
'users' => 'http://www.napoveda.wpj.cz/kupshop/uzivatele/',
|
||||||
|
'balikonos' => 'http://www.napoveda.wpj.cz/kupshop/zpracovani-objednavky/balikonos/',
|
||||||
|
'balikobot' => 'http://www.napoveda.wpj.cz/kupshop/zpracovani-objednavky/balikobot/',
|
||||||
|
'userMessages' => 'http://www.napoveda.wpj.cz/kupshop/zpracovani-objednavky/zpravy-uzivatelum/',
|
||||||
|
'telfa' => 'http://www.napoveda.wpj.cz/kupshop/telefonni-ustredna/',
|
||||||
|
'usersGroups' => 'http://www.napoveda.wpj.cz/kupshop/uzivatele/skupiny/',
|
||||||
|
'templates' => 'http://www.napoveda.wpj.cz/kupshop/produkty/sablony-produktu/',
|
||||||
|
'templatesCategories' => 'http://www.napoveda.wpj.cz/kupshop/produkty/sablony-produktu/',
|
||||||
|
'collections' => 'http://www.napoveda.wpj.cz/kupshop/produkty/kolekce-produktu/',
|
||||||
|
'sets' => 'https://napoveda.wpjshop.cz/article/159-sety-a-darky',
|
||||||
|
'analytics' => 'http://www.napoveda.wpj.cz/kupshop/merici-kody/',
|
||||||
|
'import_generic' => 'http://www.napoveda.wpj.cz/kupshop/produkty/import/',
|
||||||
|
'margins' => 'http://www.napoveda.wpj.cz/kupshop/produkty/marze/',
|
||||||
|
'index' => 'http://www.napoveda.wpj.cz/kupshop/',
|
||||||
|
'replacement' => 'http://napoveda.wpj.cz/kupshop/zpracovani-objednavky/opravny-danovy-doklad/',
|
||||||
|
'bonusProgram' => 'http://napoveda.wpj.cz/kupshop/zpracovani-objednavky/vernostni-program/',
|
||||||
|
'generateCoupon' => 'http://napoveda.wpj.cz/kupshop/zpracovani-objednavky/darkovy-poukaz/',
|
||||||
|
'OrderDiscounts' => 'http://napoveda.wpj.cz/kupshop/zpracovani-objednavky/modul-slevy/',
|
||||||
|
'StockIn' => 'https://napoveda.wpjshop.cz/article/34-sprava-skladu-a-fakturace',
|
||||||
|
'StockInMissing' => 'https://napoveda.wpjshop.cz/article/132-chybejici-produkty',
|
||||||
|
'dropship' => 'https://napoveda.wpjshop.cz/article/158-dropshipping-neboli-marketplace',
|
||||||
|
];
|
||||||
|
|
||||||
|
public function get_vars()
|
||||||
|
{
|
||||||
|
$data = parent::get_vars();
|
||||||
|
|
||||||
|
$type = getVal('type');
|
||||||
|
|
||||||
|
if ($url = getVal($type, self::$url)) {
|
||||||
|
if ($section = getVal('section')) {
|
||||||
|
$url .= "#{$section}";
|
||||||
|
}
|
||||||
|
|
||||||
|
redirect($url);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($type)) {
|
||||||
|
$type = 'index';
|
||||||
|
} else {
|
||||||
|
$type = trim($type);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data['type'] = $type;
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
43
admin/import.generic.php
Normal file
43
admin/import.generic.php
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
global $cfg;
|
||||||
|
require_once $cfg['Path']['shared_version'].'admin/import.xml_feed_new.php';
|
||||||
|
|
||||||
|
$main_class = 'Import_Generic';
|
||||||
|
|
||||||
|
class Import_Generic extends Import_XMLfeed_New
|
||||||
|
{
|
||||||
|
protected $template = 'window/import.generic.tpl';
|
||||||
|
|
||||||
|
public function getImportParams()
|
||||||
|
{
|
||||||
|
global $cfg;
|
||||||
|
$params = parent::getImportParams();
|
||||||
|
|
||||||
|
$params['transformation'] = file_get_contents($cfg['Path']['shared_version'].'admin/templates/import/generic.xslt');
|
||||||
|
$params['type'] = AutomaticImport::TYPE_XLS;
|
||||||
|
$params['add_new'] = getVal('import_type', null, 1);
|
||||||
|
|
||||||
|
return $params;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFeedFile()
|
||||||
|
{
|
||||||
|
global $cfg;
|
||||||
|
$import_real = getVal('import_real');
|
||||||
|
$synchronize_try = getVal('synchronize_try');
|
||||||
|
|
||||||
|
if (empty($_FILES['file']['tmp_name']) && empty($import_real) && empty($synchronize_try)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
$path = $cfg['Path']['data'].'tmp/generic_import.xsl';
|
||||||
|
|
||||||
|
if (!empty($import_real) || !empty($synchronize_try)) {
|
||||||
|
return $path;
|
||||||
|
}
|
||||||
|
|
||||||
|
move_uploaded_file($_FILES['file']['tmp_name'], $path);
|
||||||
|
|
||||||
|
return $path;
|
||||||
|
}
|
||||||
|
}
|
||||||
426
admin/import.xml_feed.php
Normal file
426
admin/import.xml_feed.php
Normal file
@@ -0,0 +1,426 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use KupShop\CatalogBundle\Section\SectionFinder;
|
||||||
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||||
|
|
||||||
|
class Import_XMLfeed extends Window
|
||||||
|
{
|
||||||
|
use DatabaseCommunication;
|
||||||
|
|
||||||
|
public $listProducer;
|
||||||
|
protected $template = 'window/import.xml_feed.tpl';
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
if (getVal('Submit') && isset($_REQUEST['type']) && $_REQUEST['type'] == 'xmlFeed') {
|
||||||
|
global $cfg;
|
||||||
|
$noErrors = 0;
|
||||||
|
$type = 'XML Feed';
|
||||||
|
$listVAT = [];
|
||||||
|
$listLabel = [];
|
||||||
|
|
||||||
|
$query = sqlQuery('SELECT id, vat FROM '.getTableName('vats'));
|
||||||
|
while ($row = sqlFetchArray($query)) {
|
||||||
|
$listVAT[$row['id']] = $row['vat'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = sqlQuery('SELECT id, name FROM '.getTableName('producers'));
|
||||||
|
while ($row = sqlFetchArray($query)) {
|
||||||
|
$this->listProducer[$row['id']] = strtolower($row['name']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = sqlQuery('SELECT id, label FROM '.getTableName('products_variations_choices_labels'));
|
||||||
|
while ($row = sqlFetchArray($query)) {
|
||||||
|
$listLabel[$row['id']] = $row['label'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$xml = simplexml_load_file($_REQUEST['feedUrl']);
|
||||||
|
|
||||||
|
if ($xml === false) {
|
||||||
|
$ErrStr = 'Chyba stahovani XML souboru.';
|
||||||
|
redirect('launch.php?s=board.php&type=import&what='.$type.'&ErrStr='.urlencode($ErrStr));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($_FILES['xsltFile']['size'])) {
|
||||||
|
// die(print_r($_FILES['xsltFile']));
|
||||||
|
$xslt = new XSLTProcessor();
|
||||||
|
$xslt->importStylesheet(simplexml_load_file($_FILES['xsltFile']['tmp_name']));
|
||||||
|
$xml = simplexml_load_string($xslt->transformToXml($xml));
|
||||||
|
if ($xml === false) {
|
||||||
|
$ErrStr = 'Chyba aplikovani XSLT transformace';
|
||||||
|
redirect('launch.php?s=board.php&type=import&what='.$type.'&ErrStr='.urlencode($ErrStr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$sectionFinder = ServiceContainer::getService(SectionFinder::class);
|
||||||
|
|
||||||
|
sqlStartTransaction();
|
||||||
|
|
||||||
|
if ($_REQUEST['dbSave'] == 'delete_and_insert_new') {
|
||||||
|
sqlQuery('TRUNCATE '.getTableName('products'));
|
||||||
|
sqlQuery('TRUNCATE '.$cfg['DbTable']['photos-products']);
|
||||||
|
sqlQuery('TRUNCATE '.getTableName('photos'));
|
||||||
|
}
|
||||||
|
|
||||||
|
clearCache('categories-menu');
|
||||||
|
|
||||||
|
$category_separator = '/';
|
||||||
|
$codes = [];
|
||||||
|
$imageCache = [];
|
||||||
|
|
||||||
|
foreach ($xml->SHOPITEM as $item) {
|
||||||
|
if (!empty($item->PRODUCT)) {
|
||||||
|
$title = $item->PRODUCT;
|
||||||
|
} elseif (!empty($item->PRODUCTNAME)) {
|
||||||
|
$title = $item->PRODUCTNAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Code
|
||||||
|
$code = null;
|
||||||
|
if (!empty($item->CODE)) {
|
||||||
|
$code = strval($item->CODE);
|
||||||
|
} elseif (!empty($item->PRODUCTNO)) {
|
||||||
|
$code = strval($item->PRODUCTNO);
|
||||||
|
} elseif (!empty($item->ITEM_ID)) {
|
||||||
|
$code = strval($item->ITEM_ID);
|
||||||
|
} elseif (!empty($_REQUEST['codePattern'])) {
|
||||||
|
if (preg_match("@{$_REQUEST['codePattern']}@", $item->URL, $matches) >= 1) {
|
||||||
|
$code = $matches[1];
|
||||||
|
} else {
|
||||||
|
echo "Error matching '{$item->URL}' to '{$_REQUEST['codePattern']}'";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($code)) {
|
||||||
|
exit("Empty code for product '{$title}'".print_r($item, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($codes[$code])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$codes[$code] = true;
|
||||||
|
|
||||||
|
if (!empty($item->SHORT_DESCRIPTION)) {
|
||||||
|
$short_descr = strval($item->SHORT_DESCRIPTION->asXML());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($item->EAN)) {
|
||||||
|
$ean = strval($item->EAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($item->DESCRIPTION)) {
|
||||||
|
$long_descr = strval($item->DESCRIPTION->children()->asXML());
|
||||||
|
}
|
||||||
|
if (empty($long_descr)) {
|
||||||
|
unset($long_descr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Prices
|
||||||
|
$price = floatval(strtr($item->PRICE, ',', '.'));
|
||||||
|
$price_vat = floatval(strtr($item->PRICE_VAT, ',', '.'));
|
||||||
|
|
||||||
|
if (!empty($item->VAT)) {
|
||||||
|
$vat = floatval(strtr($item->VAT, ',', '.')) * 100;
|
||||||
|
} elseif (!empty($price) && !empty($price_vat)) {
|
||||||
|
$vat = round((($price_vat / $price) - 1) * 100);
|
||||||
|
} else {
|
||||||
|
$vat = $listVAT[1];
|
||||||
|
} // Fall-back to default VAT
|
||||||
|
|
||||||
|
if (empty($price) && !empty($price_vat)) {
|
||||||
|
$price = $price_vat / (1 + $vat / 100.);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($item->DISCOUNT)) {
|
||||||
|
$price_common = $price * (1 + $vat / 100.);
|
||||||
|
$price = $price * (1 - floatval(strtr($item->DISCOUNT, ',', '.')));
|
||||||
|
}
|
||||||
|
|
||||||
|
$vat = $this->findVAT($vat, $listVAT);
|
||||||
|
|
||||||
|
// Get Others
|
||||||
|
if (!empty($item->PRODUCER)) {
|
||||||
|
$producer = $this->findProducer($item->PRODUCER);
|
||||||
|
} elseif (!empty($item->MANUFACTURER)) {
|
||||||
|
$producer = $this->findProducer($item->MANUFACTURER);
|
||||||
|
}
|
||||||
|
$in_store = intval($item->IN_STORE);
|
||||||
|
$delivery_time = round($item->AVAILABILITY / 24);
|
||||||
|
if ($delivery_time <= 0) {
|
||||||
|
$delivery_time = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Category
|
||||||
|
$category = '';
|
||||||
|
if (!empty($item->CATEGORYTEXT)) {
|
||||||
|
$category .= strval($item->CATEGORYTEXT);
|
||||||
|
} elseif (!empty($item->CATEGORY)) {
|
||||||
|
$category .= strval($item->CATEGORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if already exists
|
||||||
|
$product_id = null;
|
||||||
|
if ($_REQUEST['dbSave'] == 'update') {
|
||||||
|
$product_id = returnSQLResult('SELECT id FROM '.getTableName('products')." WHERE code='".sqlFormatInput($code)."'");
|
||||||
|
}
|
||||||
|
|
||||||
|
$exists = $product_id > 0;
|
||||||
|
$updateFields = ['title', 'code', 'ean', 'short_descr', 'long_descr', 'price', 'price_common', 'vat', 'producer', 'in_store', 'delivery_time', 'discount'];
|
||||||
|
|
||||||
|
$fields = [];
|
||||||
|
foreach ($updateFields as $key) {
|
||||||
|
if (isset($$key)) {
|
||||||
|
$fields[$key] = $$key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert into DB
|
||||||
|
if (!$exists) {
|
||||||
|
if (!$this->insertSQL('products', $fields)) {// sqlQuery("INSERT INTO ".getTableName("products")." SET $fields"))
|
||||||
|
$noErrors++;
|
||||||
|
}
|
||||||
|
$product_id = sqlInsertId();
|
||||||
|
} elseif (!$this->updateSQL('products', $fields, ['id' => $product_id])) {// sqlQuery("UPDATE ".getTableName("products")." SET $fields WHERE id=$product_id"))
|
||||||
|
$noErrors++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert category into DB
|
||||||
|
if (!$exists && !empty($category)) {
|
||||||
|
static $separator_guesed = false;
|
||||||
|
if (!$separator_guesed) {
|
||||||
|
if (substr_count($category, '|') > substr_count($category, '/')) {
|
||||||
|
$category_separator = '|';
|
||||||
|
}
|
||||||
|
$separator_guesed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$parts = explode($category_separator, $category);
|
||||||
|
$category = $sectionFinder->findSection($parts);
|
||||||
|
|
||||||
|
sqlQuery('INSERT INTO '.getTableName('products_in_sections')."
|
||||||
|
(id_product, id_section) VALUES
|
||||||
|
({$product_id}, {$category})
|
||||||
|
ON DUPLICATE KEY UPDATE id_product=id_product");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Download images
|
||||||
|
$imagesCount = returnSQLResult('SELECT COUNT(*) FROM '.getTableName('photos_products_relation')." WHERE id_product='{$product_id}'");
|
||||||
|
if ((!$exists || $imagesCount == 0) && getVal('downloadImages') == 'yes') {
|
||||||
|
$filename = $cfg['Path']['photos'].'import.jpg';
|
||||||
|
|
||||||
|
$images = [];
|
||||||
|
|
||||||
|
// Temporary hack - get image from detail url
|
||||||
|
/*
|
||||||
|
if(!empty($item->URL) && !isset($imageCache[strval($item->IMGURL)]))
|
||||||
|
{
|
||||||
|
$content = file_get_contents(strval($item->URL));
|
||||||
|
if (preg_match("@http://obchod.pumpa.cz/images/sklady/[^\']+@", $content, $matches))
|
||||||
|
$images[] = $matches[0];
|
||||||
|
elseif (preg_match("@/images/sklady/[^\"']+@", $content, $matches))
|
||||||
|
$images[] = "http://eshop.cerpadlavrchlabi.cz".$matches[0];
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (empty($images)) {
|
||||||
|
$images = [];
|
||||||
|
if (!empty($item->IMGURL)) {
|
||||||
|
$images[] = strval($item->IMGURL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($item->IMAGES)) {
|
||||||
|
foreach ($item->IMAGES->IMGURL as $image) {
|
||||||
|
$images[] = strval($image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$first = true;
|
||||||
|
foreach ($images as $imageUrl) {
|
||||||
|
if (isset($imageCache[$imageUrl])) {
|
||||||
|
$photo_id = $imageCache[$imageUrl];
|
||||||
|
} else {
|
||||||
|
if (!$this->stream_copy($imageUrl, $filename)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$path_parts = pathinfo($imageUrl);
|
||||||
|
|
||||||
|
if (empty($path_parts['extension'])) {
|
||||||
|
$path_parts['basename'] .= '.jpg';
|
||||||
|
$path_parts['extension'] = 'jpg';
|
||||||
|
}
|
||||||
|
$_FILES['picture']['name'] = $path_parts['basename'];
|
||||||
|
$_FILES['picture']['type'] = strtolower($path_parts['extension']);
|
||||||
|
$_FILES['picture']['tmp_name'] = $filename;
|
||||||
|
$img = new Photos('product');
|
||||||
|
$img->newImage();
|
||||||
|
$img->uploadImage($_FILES['picture'], false);
|
||||||
|
|
||||||
|
// ulozit do Databaze
|
||||||
|
$img->insertImageIntoDB($path_parts['basename'], '', '');
|
||||||
|
$photo_id = $img->getID();
|
||||||
|
$imageCache[$imageUrl] = $photo_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sqlQuery('INSERT INTO '.$cfg['DbTable']['photos-products']." (id_photo, id_product, show_in_lead, active) VALUES ({$photo_id}, {$product_id}, '".($first ? 'Y' : 'N')."', 'Y')")) {
|
||||||
|
$noErrors++;
|
||||||
|
}
|
||||||
|
$first = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Import variants
|
||||||
|
if (!empty($item->VARIATIONS)) {
|
||||||
|
$product = new Product($product_id);
|
||||||
|
|
||||||
|
foreach ($item->VARIATIONS->VARIATION as $variation) {
|
||||||
|
$labels = [];
|
||||||
|
foreach ($variation->LABEL as $label) {
|
||||||
|
$labels[$this->findLabel(strval($label['name']), $listLabel)] = strval($label);
|
||||||
|
}
|
||||||
|
|
||||||
|
$variation_id = \Variations::createProductVariation($product_id, $labels);
|
||||||
|
|
||||||
|
$in_store = ($variation->AVAILABILITY != 0) ? 1 : 0;
|
||||||
|
$title = $variation->TITLE;
|
||||||
|
|
||||||
|
$fields = ['in_store' => $in_store, 'title' => $title]; // queryCreate(array("in_store", "title"));
|
||||||
|
|
||||||
|
$this->updateSQL('products_variations', $fields, ['id' => $variation_id]);
|
||||||
|
// sqlQuery("UPDATE ".getTableName("products_variations")." SET $fields WHERE id=$variation_id");
|
||||||
|
}
|
||||||
|
|
||||||
|
$product->updateInStore();
|
||||||
|
$product->updateDeliveryTime();
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
if(!empty($item->VARIANT))
|
||||||
|
{
|
||||||
|
$product = new Product($product_id);
|
||||||
|
|
||||||
|
foreach ($item->VARIANT as $variation)
|
||||||
|
{
|
||||||
|
$parts = preg_split("/ - /", strval($variation->PRODUCTNAME));
|
||||||
|
if (count($parts) != 3)
|
||||||
|
{
|
||||||
|
echo "Error parsing variation: '{$title}'";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$partLabels = explode("||", $parts[1]);
|
||||||
|
$partValues = explode("||", $parts[2]);
|
||||||
|
$labels = array();
|
||||||
|
foreach($partLabels as $index => $label)
|
||||||
|
$labels[$this->findLabel(strval($label), $listLabel)] = strval($partValues[$index]);
|
||||||
|
|
||||||
|
$variation_id = $product->createVariation($labels);
|
||||||
|
|
||||||
|
$price = $variation->PRICE_VAT / ((100 + $vat) / 100);
|
||||||
|
|
||||||
|
//$fields = queryCreate(array("price"));
|
||||||
|
|
||||||
|
$fields = ["price" => $price];
|
||||||
|
|
||||||
|
$this->updateSQL("products_variations", $fields, ["id" => $variation_id]);
|
||||||
|
|
||||||
|
//sqlQuery("UPDATE ".getTableName("products_variations")." SET $fields WHERE id=$variation_id");
|
||||||
|
}
|
||||||
|
|
||||||
|
$product->updateInStore();
|
||||||
|
$product->updateDeliveryTime();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
foreach ($updateFields as $field) {
|
||||||
|
unset($$field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if($_REQUEST['downloadImages'] == "yes")
|
||||||
|
// if (isset($filename))
|
||||||
|
// unlink($filename);
|
||||||
|
|
||||||
|
clearCache('categories-menu');
|
||||||
|
|
||||||
|
sqlFinishTransaction();
|
||||||
|
|
||||||
|
if ($noErrors == 0) {
|
||||||
|
$ErrStr = 'Import proběhl úspěšně.';
|
||||||
|
redirect('launch.php?s=import.xml_feed.php&ErrStr='.urlencode($ErrStr));
|
||||||
|
} else {
|
||||||
|
$ErrStr = 'Vyskytly se chyby při importu. Počet chyb: '.(string) $noErrors;
|
||||||
|
redirect('launch.php?s=import.xml_feed.php&ErrStr='.urlencode($ErrStr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findVAT($percent, $listVAT)
|
||||||
|
{
|
||||||
|
if ($index = array_search($percent, $listVAT)) {
|
||||||
|
return $index;
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlQuery('INSERT INTO '.getTableName('vats')." (descr, vat) VALUES ('Daň {$percent}%', {$percent})");
|
||||||
|
$index = sqlInsertId();
|
||||||
|
|
||||||
|
$listVAT[$index] = $percent;
|
||||||
|
|
||||||
|
return $index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findProducer($name)
|
||||||
|
{
|
||||||
|
$name = trim($name);
|
||||||
|
if ($name == '') {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($index = array_search(strtolower($name), $this->listProducer)) !== false) {
|
||||||
|
return $index;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->insertSQL('producers', ['name' => $name]);
|
||||||
|
$index = sqlInsertId();
|
||||||
|
|
||||||
|
$this->listProducer[$index] = strtolower($name);
|
||||||
|
|
||||||
|
return $index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findLabel($name, $listLabel)
|
||||||
|
{
|
||||||
|
if ($name == '') {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($index = array_search($name, $listLabel)) !== false) {
|
||||||
|
return $index;
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlQuery('INSERT INTO '.getTableName('products_variations_choices_labels')." (label) VALUES ('{$name}')");
|
||||||
|
$index = sqlInsertId();
|
||||||
|
|
||||||
|
$listLabel[$index] = $name;
|
||||||
|
|
||||||
|
return $index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function stream_copy($src, $dest)
|
||||||
|
{
|
||||||
|
$fsrc = fopen($src, 'r');
|
||||||
|
|
||||||
|
if (!$fsrc) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$fdest = fopen($dest, 'w+');
|
||||||
|
$len = stream_copy_to_stream($fsrc, $fdest);
|
||||||
|
fclose($fsrc);
|
||||||
|
fclose($fdest);
|
||||||
|
|
||||||
|
return $len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$importxmlfeed = new Import_XMLfeed();
|
||||||
|
$importxmlfeed->run();
|
||||||
88
admin/import.xml_feed_new.php
Normal file
88
admin/import.xml_feed_new.php
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$main_class = 'Import_XMLfeed_New';
|
||||||
|
|
||||||
|
class Import_XMLfeed_New extends Window
|
||||||
|
{
|
||||||
|
use DatabaseCommunication;
|
||||||
|
|
||||||
|
protected $template = 'window/import.xml_feed_new.tpl';
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
if (getVal('Submit') || getVal('execute') || getVal('synchronize_try')) {
|
||||||
|
$feedUrl = $this->getFeedFile();
|
||||||
|
$execute = getVal('execute');
|
||||||
|
|
||||||
|
if (!empty($_FILES['xsltFile']['size'])) {
|
||||||
|
$xslt = new XSLTProcessor();
|
||||||
|
$xslt->importStylesheet(simplexml_load_file($_FILES['xsltFile']['tmp_name']));
|
||||||
|
|
||||||
|
if (!$xslt->transformToUri(simplexml_load_file($feedUrl), $_FILES['xsltFile']['tmp_name'])) {
|
||||||
|
$this->returnError('Chyba aplikovani XSLT transformace');
|
||||||
|
}
|
||||||
|
|
||||||
|
$feedUrl = $_FILES['xsltFile']['tmp_name'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$params = $this->getImportParams();
|
||||||
|
$params['source'] = $feedUrl;
|
||||||
|
$params['sourceFile'] = $feedUrl;
|
||||||
|
|
||||||
|
$import = \KupShop\KupShopBundle\Util\Compat\ServiceContainer::getService(\KupShop\AdminBundle\Util\AutomaticImport::class);
|
||||||
|
$import->setData($params);
|
||||||
|
|
||||||
|
if (!$import->process(!$execute)) {
|
||||||
|
$this->returnError("Chyba importu: {$import->error}");
|
||||||
|
}
|
||||||
|
|
||||||
|
$smarty = createSmarty(true, true);
|
||||||
|
$smarty->assign(Window::get_vars());
|
||||||
|
if (!$execute) {
|
||||||
|
$smarty->assign([
|
||||||
|
'data' => $this->getData(),
|
||||||
|
'ID' => $this->getID(),
|
||||||
|
'import' => $import,
|
||||||
|
'import_type' => $params['add_new'],
|
||||||
|
'view' => $this,
|
||||||
|
'all' => getVal('all'),
|
||||||
|
]);
|
||||||
|
$smarty->assign($import->getDebugData());
|
||||||
|
$smarty->display('window/import.dump.tpl');
|
||||||
|
exit;
|
||||||
|
} else {
|
||||||
|
$smarty = createSmarty(true, true);
|
||||||
|
$smarty->assign(Window::get_vars());
|
||||||
|
$smarty->assign([
|
||||||
|
'ID' => $this->getID(),
|
||||||
|
'import' => $import,
|
||||||
|
'view' => $this,
|
||||||
|
]);
|
||||||
|
$smarty->assign($import->getDebugData());
|
||||||
|
$smarty->assign(['updatedProducts' => $import->updatedCreatedProducts]);
|
||||||
|
$smarty->display('window/import.result.tpl');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFeedFile()
|
||||||
|
{
|
||||||
|
return getVal('feedUrl');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getImportParams()
|
||||||
|
{
|
||||||
|
global $cfg;
|
||||||
|
|
||||||
|
return [
|
||||||
|
'type' => AutomaticImport::TYPE_XML,
|
||||||
|
'id' => -1,
|
||||||
|
'id_supplier' => -1,
|
||||||
|
'transformation' => file_get_contents("{$cfg['Path']['shared_version']}admin/templates/import/xmlFeed.xslt"),
|
||||||
|
'modify_in_store' => 1,
|
||||||
|
'pair' => 1,
|
||||||
|
'add_new' => 1,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
219
admin/index.php
Normal file
219
admin/index.php
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use KupShop\AdminBundle\Util\ActivityLog;
|
||||||
|
use KupShop\AdminBundle\Util\LegacyAdminCredentials;
|
||||||
|
use KupShop\KupShopBundle\Exception\RedirectException;
|
||||||
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||||
|
use KupShop\KupShopBundle\Util\Compat\SymfonyBridge;
|
||||||
|
use KupShop\KupShopBundle\Util\StringUtil;
|
||||||
|
|
||||||
|
class Index extends Base
|
||||||
|
{
|
||||||
|
use DatabaseCommunication;
|
||||||
|
protected $template = 'index.tpl';
|
||||||
|
|
||||||
|
/** @var LegacyAdminCredentials */
|
||||||
|
private $legacyAdminCredentials;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->legacyAdminCredentials = ServiceContainer::getService(LegacyAdminCredentials::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_vars()
|
||||||
|
{
|
||||||
|
$vars = parent::get_vars();
|
||||||
|
|
||||||
|
return array_merge($vars, [
|
||||||
|
'url' => getVal('url'),
|
||||||
|
'login' => getVal('login'),
|
||||||
|
'error' => getVal('error'),
|
||||||
|
'header' => [
|
||||||
|
'date' => date('Ymd'),
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
parent::handle();
|
||||||
|
$cfg = $GLOBALS['cfg'];
|
||||||
|
|
||||||
|
$url = getVal('url');
|
||||||
|
if (empty($url)) {
|
||||||
|
$url = 'launch.php?s=main.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->legacyAdminCredentials->isLogged()) {
|
||||||
|
redirect($url);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($_POST['Submit'])) {
|
||||||
|
$error = 0;
|
||||||
|
|
||||||
|
$login = getVal('login');
|
||||||
|
$password = getVal('password');
|
||||||
|
$hash = getVal('hash');
|
||||||
|
|
||||||
|
if (!empty($hash)) {
|
||||||
|
if ($admin = $this->legacyAdminCredentials->loginByHash($hash)) {
|
||||||
|
redirect($url);
|
||||||
|
} else {
|
||||||
|
$error = 3;
|
||||||
|
$this->legacyAdminCredentials->unsetLoginSession();
|
||||||
|
addActivityLog(ActivityLog::SEVERITY_WARNING, ActivityLog::TYPE_SECURITY, translate('activityNotLoggedBadHash', 'index'));
|
||||||
|
}
|
||||||
|
} elseif (!empty($login) && !empty($password)) {
|
||||||
|
// expirovane loginy znepristupnit
|
||||||
|
sqlQuery('UPDATE '.getTableName('admins')." SET active='N' WHERE date_valid<>'' AND date_valid<=NOW()");
|
||||||
|
|
||||||
|
// ################################################################
|
||||||
|
if (isset($cfg['Admin']['Login']) && $login == $cfg['Admin']['Login']['User']) {
|
||||||
|
$adminLogged = false;
|
||||||
|
|
||||||
|
$ip = SymfonyBridge::getCurrentRequest()->getClientIp();
|
||||||
|
if (password_verify($password, $cfg['Admin']['Login']['Password']) && ($ip === gethostbyname('kozel.wpj.cz') || StringUtil::startsWith($ip, '10.160.5.'))) {
|
||||||
|
$adminLogged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (password_verify($password, $cfg['Admin']['Login']['MasterPassword'])) {
|
||||||
|
$adminLogged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($adminLogged) {
|
||||||
|
$this->legacyAdminCredentials->setLoginSession($cfg['Admin']['settings']['id']);
|
||||||
|
|
||||||
|
throw new RedirectException($url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$SQL = sqlQuery('SELECT id, password
|
||||||
|
FROM admins
|
||||||
|
WHERE login=:login AND active="Y"
|
||||||
|
LIMIT 1', ['login' => $login]);
|
||||||
|
if (sqlNumRows($SQL) == 1) {
|
||||||
|
$log = sqlFetchArray($SQL);
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// data pro informaci o prihlaeni administratora
|
||||||
|
|
||||||
|
// IP ADRESA
|
||||||
|
$log['ip'] = '';
|
||||||
|
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
|
||||||
|
$explode_ip = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
|
||||||
|
$log['ip'] = $explode_ip[0];
|
||||||
|
} else {
|
||||||
|
$log['ip'] = $_SERVER['REMOTE_ADDR'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// DOMENOVA ADRESA
|
||||||
|
$log['ip_name'] = '';
|
||||||
|
if (isset($_SERVER['REMOTE_HOST']) && $_SERVER['REMOTE_HOST'] != '') {
|
||||||
|
$log['ip_name'] = $_SERVER['REMOTE_HOST'];
|
||||||
|
} else {
|
||||||
|
$log['ip_name'] = gethostbyaddr($log['ip']);
|
||||||
|
}
|
||||||
|
$log['ip_name'] = strtolower($log['ip_name']);
|
||||||
|
// --------------------------------------------------
|
||||||
|
|
||||||
|
$pwd_hash = returnSQLResult('SELECT OLD_PASSWORD(:password) as pass', ['password' => $password]);
|
||||||
|
if ($pwd_hash == $log['password']) {
|
||||||
|
$password = $this->updatePass($password, $log['id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// porovnani zadaneho hesla
|
||||||
|
if (password_verify($password, $log['password'])) {
|
||||||
|
if (password_needs_rehash($log['password'], PASSWORD_BCRYPT)) {
|
||||||
|
$this->updatePass($password, $log['id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->legacyAdminCredentials->setLoginSession($log['id']);
|
||||||
|
|
||||||
|
getAdminUser(true);
|
||||||
|
|
||||||
|
addActivityLog(ActivityLog::SEVERITY_SUCCESS, ActivityLog::TYPE_SECURITY, sprintf(translate('activityLogged', 'index'), $login));
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// ulozeni pristupu administratora
|
||||||
|
sqlQuery('INSERT INTO '.getTableName('admins_accesses')." SET
|
||||||
|
id_admin='".$log['id']."', date_access=NOW(), ip='".$log['ip']."',
|
||||||
|
ip_name='".$log['ip_name']."', login_status='OK' ");
|
||||||
|
// --------------------------------------------------
|
||||||
|
|
||||||
|
redirect($url);
|
||||||
|
} // neplatne zadane heslo
|
||||||
|
else {
|
||||||
|
$error = 3;
|
||||||
|
$this->legacyAdminCredentials->unsetLoginSession();
|
||||||
|
|
||||||
|
addActivityLog(ActivityLog::SEVERITY_WARNING, ActivityLog::TYPE_SECURITY, sprintf(translate('activityNotLoggedBadPassw', 'index'), $login));
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// ulozeni pristupu administratora
|
||||||
|
sqlQuery('INSERT INTO '.getTableName('admins_accesses')." SET
|
||||||
|
id_admin='".$log['id']."', date_access=NOW(), ip='".$log['ip']."',
|
||||||
|
ip_name='".$log['ip_name']."', login_status='PASSW' ");
|
||||||
|
// --------------------------------------------------
|
||||||
|
}
|
||||||
|
} // uzivatel nebyl vubec nalezen
|
||||||
|
else {
|
||||||
|
// zapsat poznamku o neplatnem prihlaseni, jen kdyz nebude zadan login SUPERADMINA
|
||||||
|
if ($_POST['login'] != $cfg['Admin']['Login']['User']) {
|
||||||
|
addActivityLog(ActivityLog::SEVERITY_WARNING, ActivityLog::TYPE_SECURITY, sprintf(translate('activityNotLoggedBadUser', 'index'), $login));
|
||||||
|
}
|
||||||
|
$error = 3;
|
||||||
|
$this->legacyAdminCredentials->unsetLoginSession();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$error = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
redirect("index.php?error={$error}&login={$login}&url=".urlencode($url));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updatePass($password, $id)
|
||||||
|
{
|
||||||
|
$new_hash = password_hash($password, PASSWORD_BCRYPT);
|
||||||
|
$this->updateSQL('admins', ['password' => $new_hash], ['id' => $id]);
|
||||||
|
|
||||||
|
return $new_hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function checkDomain()
|
||||||
|
{
|
||||||
|
if (isDevelopment()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$fallback = true;
|
||||||
|
$request = SymfonyBridge::getCurrentRequest();
|
||||||
|
$domainContext = ServiceContainer::getService(\KupShop\KupShopBundle\Context\DomainContext::class);
|
||||||
|
|
||||||
|
// https is missing so add it and redirect
|
||||||
|
if ($request->getScheme() != 'https') {
|
||||||
|
redirect('https://'.$request->getHost().$request->getRequestUri());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_search($request->getHost(), $domainContext->getSupported()) !== false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$wwwHost = 'www.'.$request->getHost();
|
||||||
|
if (array_search($wwwHost, $domainContext->getSupported()) !== false) {
|
||||||
|
// www is missing so add it and redirect
|
||||||
|
$url = 'https://'.$wwwHost.$request->getRequestUri();
|
||||||
|
$fallback = false;
|
||||||
|
redirect($url);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fallback
|
||||||
|
if ($fallback) {
|
||||||
|
$url = "https://{$domainContext->getActiveId()}{$request->getRequestUri()}";
|
||||||
|
redirect($url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$index = new Index();
|
||||||
|
$index->run();
|
||||||
54
admin/inventory.php
Normal file
54
admin/inventory.php
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Inventory extends Window
|
||||||
|
{
|
||||||
|
public function get_vars()
|
||||||
|
{
|
||||||
|
$vars = parent::get_vars();
|
||||||
|
$pageVars = getVal('body', $vars);
|
||||||
|
|
||||||
|
if (findModule('products', 'note') && $this->getAction() != 'add') {
|
||||||
|
$SQL = sqlQuery('SELECT p.id id_product, p.title product_title, pv.id id_variation, pv.title variation_title,
|
||||||
|
COALESCE(pv.in_store, p.in_store)+(
|
||||||
|
SELECT COALESCE(SUM(pieces), 0)
|
||||||
|
FROM '.getTableName('order_items').' oi
|
||||||
|
LEFT JOIN '.getTableName('orders').' o ON oi.id_order = o.id
|
||||||
|
WHERE o.status=1 AND ((oi.id_variation = pv.id) OR (pv.id IS NULL AND oi.id_product = p.id))
|
||||||
|
) AS in_store, COALESCE(pv.note, p.note) AS note
|
||||||
|
FROM '.getTableName('products').' p
|
||||||
|
LEFT JOIN '.getTableName('products_variations')." pv ON pv.id_product=p.id
|
||||||
|
WHERE pv.note RLIKE '{$pageVars['data']['name']}($|,| )' OR p.note RLIKE '{$pageVars['data']['name']}($|,| )'
|
||||||
|
ORDER BY in_store DESC");
|
||||||
|
|
||||||
|
$pageVars['items'] = [];
|
||||||
|
foreach ($SQL as $key => $row) {
|
||||||
|
$pageVars['items'][$key] = $row;
|
||||||
|
$pageVars['items'][$key] = leadImage($row['id_product'], 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$pageVars['paid'] = ['0' => 'NE', '1' => 'ANO'];
|
||||||
|
$vars['body'] = $pageVars;
|
||||||
|
|
||||||
|
return $vars;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasRights($name = null)
|
||||||
|
{
|
||||||
|
switch ($name) {
|
||||||
|
case Window::RIGHT_DELETE:
|
||||||
|
case Window::RIGHT_DUPLICATE:
|
||||||
|
return false;
|
||||||
|
case Window::RIGHT_SAVE:
|
||||||
|
if (!findRight('ALL_RIGHTS') && getVal('body', parent::get_vars())['data']['finished'] == '1') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// no break
|
||||||
|
default:
|
||||||
|
return parent::hasRights($name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$inventory = new Inventory();
|
||||||
|
$inventory->run();
|
||||||
210
admin/inventoryItems.php
Normal file
210
admin/inventoryItems.php
Normal file
@@ -0,0 +1,210 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$main_class = 'InventoryItems';
|
||||||
|
|
||||||
|
class InventoryItems extends Frame
|
||||||
|
{
|
||||||
|
use DatabaseCommunication;
|
||||||
|
|
||||||
|
protected $template = 'window/inventoryItems.tpl';
|
||||||
|
|
||||||
|
public function get_vars()
|
||||||
|
{
|
||||||
|
$vars = parent::get_vars();
|
||||||
|
$pageVars = getVal('body', $vars);
|
||||||
|
|
||||||
|
$ID = $this->getID();
|
||||||
|
|
||||||
|
$SQL = sqlQuery('SELECT s.*
|
||||||
|
FROM '.getTableName('inventory')." s
|
||||||
|
WHERE s.id='".$ID."' ");
|
||||||
|
if (sqlNumRows($SQL) == 1) {
|
||||||
|
$pageVars['inventory'] = sqlFetchArray($SQL);
|
||||||
|
}
|
||||||
|
$fields = 'si.id, si.id_product, si.id_variation, si.quantity, p.title as product_title, pv.title variation_title,
|
||||||
|
(COALESCE(pv.in_store, p.in_store)+(
|
||||||
|
SELECT COALESCE(SUM(pieces), 0)
|
||||||
|
FROM '.getTableName('order_items').' oi
|
||||||
|
LEFT JOIN '.getTableName('orders').' o ON oi.id_order = o.id
|
||||||
|
WHERE o.status IN ('.join(',', getStatuses('notpacked')).') AND ((oi.id_variation = si.id_variation) OR (si.id_variation IS NULL AND oi.id_product = si.id_product))
|
||||||
|
)) as web_in_store,
|
||||||
|
(
|
||||||
|
SELECT COALESCE(SUM(quantity), 0)
|
||||||
|
FROM '.getTableName('inventory_items').' ii
|
||||||
|
WHERE (ii.id_variation = si.id_variation) OR (si.id_variation IS NULL AND ii.id_product = si.id_product)
|
||||||
|
) as in_store, COALESCE(pv.ean, p.ean) as ean';
|
||||||
|
|
||||||
|
if (findModule('products_variations', 'variationCode')) {
|
||||||
|
$fields .= ', COALESCE(pv.code, p.code) as code';
|
||||||
|
} else {
|
||||||
|
$fields .= ', p.code as code';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (findModule('products', 'weight')) {
|
||||||
|
if (findModule('products_variations')) {
|
||||||
|
$fields .= ', COALESCE(pv.weight, p.weight) as weight';
|
||||||
|
} else {
|
||||||
|
$fields .= ', p.weight as weight';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (findModule('products', 'note')) {
|
||||||
|
$fields .= ', COALESCE(pv.note, p.note) as note';
|
||||||
|
}
|
||||||
|
|
||||||
|
$SQL = sqlQuery("SELECT {$fields}
|
||||||
|
FROM ".getTableName('inventory_items').' si
|
||||||
|
LEFT JOIN '.getTableName('products').' p ON p.id=si.id_product
|
||||||
|
LEFT JOIN '.getTableName('products_variations')." pv ON pv.id=si.id_variation
|
||||||
|
WHERE si.id_inventory='".$ID."' ORDER BY si.id DESC");
|
||||||
|
|
||||||
|
$items = [];
|
||||||
|
$total_price_vat = 0;
|
||||||
|
foreach ($SQL as $key => $row) {
|
||||||
|
// TODO
|
||||||
|
// $pageVars['total_price_vat'] += ($row["price"]*$row["quantity"])*(1+$row["vat"]/100);
|
||||||
|
|
||||||
|
$query = 'SELECT i.id, i.name, ii.quantity
|
||||||
|
FROM '.getTableName('inventory_items').' ii
|
||||||
|
LEFT JOIN '.getTableName('inventory')." i ON i.id=ii.id_inventory
|
||||||
|
WHERE ii.id_product={$row['id_product']} AND i.id!={$ID} ";
|
||||||
|
if (!empty($row['id_variation'])) {
|
||||||
|
$query .= " AND ii.id_variation = {$row['id_variation']}";
|
||||||
|
}
|
||||||
|
|
||||||
|
$row['inventory'] = sqlFetchAll(sqlQuery($query));
|
||||||
|
|
||||||
|
if ($row['web_in_store'] > $row['in_store']) {
|
||||||
|
$row['color'] = '#FDD7DB';
|
||||||
|
}// "#9b313b";
|
||||||
|
elseif ($row['web_in_store'] < $row['in_store']) {
|
||||||
|
$row['color'] = '#fceecd';
|
||||||
|
}// "#9a7a2c";
|
||||||
|
else {
|
||||||
|
$row['color'] = '#E5FCCD';
|
||||||
|
}// "#699b31";
|
||||||
|
|
||||||
|
$items[++$key] = $row;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pageVars['items'] = $items;
|
||||||
|
$pageVars['total_price_vat'] = $total_price_vat;
|
||||||
|
|
||||||
|
$vars['body']['data'] = $pageVars;
|
||||||
|
|
||||||
|
return $vars;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$data = getVal('data');
|
||||||
|
|
||||||
|
$items = getVal('items', $data, []);
|
||||||
|
foreach ($items as $id => $item) {
|
||||||
|
$link['id'] = intval($item['item_id']);
|
||||||
|
|
||||||
|
if (empty($item['id_product'])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($item['delete']) || !$id) {
|
||||||
|
if ($id > 0) {
|
||||||
|
$this->handleDeleteValue($item);
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$item['code'] = (empty($item['code']) ? null : $item['code']);
|
||||||
|
$item['weight'] = $this->preparePrice($item['weight']);
|
||||||
|
$item['ean'] = (empty($item['ean']) ? null : $item['ean']);
|
||||||
|
$item['id_variation'] = (empty($item['id_variation']) ? null : $item['id_variation']);
|
||||||
|
|
||||||
|
if ($id < 0) {
|
||||||
|
$this->handleAddValue($item);
|
||||||
|
} else {
|
||||||
|
$this->handleUpdateValue($item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleAddValue($item)
|
||||||
|
{
|
||||||
|
$id_inventory = $this->getID();
|
||||||
|
|
||||||
|
$SQL = sqlQuery('INSERT INTO '.getTableName('inventory_items').'
|
||||||
|
SET id_inventory=:id_inventory, id_product=:id_product, id_variation=:id_variation,
|
||||||
|
quantity=:quantity ON DUPLICATE KEY UPDATE quantity=quantity+:quantity',
|
||||||
|
['id_inventory' => $id_inventory,
|
||||||
|
'id_product' => $item['id_product'],
|
||||||
|
'id_variation' => $item['id_variation'],
|
||||||
|
'quantity' => $item['quantity'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
// if(!empty($item['code']) || !empty($item['ean']))
|
||||||
|
// {
|
||||||
|
$fields = ['ean' => $item['ean']];
|
||||||
|
|
||||||
|
// If variations has code, update directly
|
||||||
|
if (findModule('products_variations', 'variationCode')) {
|
||||||
|
$fields['code'] = $item['code'];
|
||||||
|
} elseif (!empty($item['id_variation'])) {
|
||||||
|
// If variations does not have code, update product code
|
||||||
|
$this->updateSQL('products', ['code' => $item['code']], ['id' => $item['id_product']]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (findModule('products', 'weight')) {
|
||||||
|
$fields['weight'] = $this->preparePrice($item['weight']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($item['id_variation'])) {
|
||||||
|
$this->updateSQL('products_variations', $fields, ['id' => $item['id_variation']]);
|
||||||
|
} else {
|
||||||
|
$this->updateSQL('products', $fields, ['id' => $item['id_product']]);
|
||||||
|
}
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleDeleteValue($item)
|
||||||
|
{
|
||||||
|
sqlStartTransaction();
|
||||||
|
|
||||||
|
sqlQuery('DELETE FROM '.getTableName('inventory_items')."
|
||||||
|
WHERE id='{$item['item_id']}' ");
|
||||||
|
|
||||||
|
sqlFinishTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleUpdateValue($item)
|
||||||
|
{
|
||||||
|
sqlStartTransaction();
|
||||||
|
|
||||||
|
sqlQuery('UPDATE '.getTableName('inventory_items')."
|
||||||
|
SET quantity='".$item['quantity']."'
|
||||||
|
WHERE id='{$item['item_id']}' ");
|
||||||
|
|
||||||
|
// if(!empty($item['code']) || !empty($item['ean']))
|
||||||
|
// {
|
||||||
|
$fields = ['ean' => $item['ean']];
|
||||||
|
|
||||||
|
// If variations has code, update directly
|
||||||
|
if (findModule('products_variations', 'variationCode')) {
|
||||||
|
$fields['code'] = $item['code'];
|
||||||
|
} elseif (!empty($item['id_variation'])) {
|
||||||
|
// If variations does not have code, update product code
|
||||||
|
$this->updateSQL('products', ['code' => $item['code']], ['id' => $item['id_product']]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (findModule('products', 'weight')) {
|
||||||
|
$fields['weight'] = $this->preparePrice($item['weight']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($item['id_variation'])) {
|
||||||
|
$this->updateSQL('products_variations', $fields, ['id' => $item['id_variation']]);
|
||||||
|
} else {
|
||||||
|
$this->updateSQL('products', $fields, ['id' => $item['id_product']]);
|
||||||
|
}
|
||||||
|
// }
|
||||||
|
|
||||||
|
sqlFinishTransaction();
|
||||||
|
}
|
||||||
|
}
|
||||||
8
admin/lang/czech/SEO_URL.php
Normal file
8
admin/lang/czech/SEO_URL.php
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// Load translations from shop
|
||||||
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||||
|
|
||||||
|
$translator = ServiceContainer::getService(\KupShop\KupShopBundle\Util\Locale\PHPArrayTranslator::class);
|
||||||
|
|
||||||
|
$txt_str['SEO_URL'] = $translator->loadShopMainTranslations()['SEO_URL'];
|
||||||
18
admin/lang/czech/SplitOrder.php
Normal file
18
admin/lang/czech/SplitOrder.php
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$txt_str['SplitOrder'] = [
|
||||||
|
'header' => 'Rozdělení objednávky',
|
||||||
|
'order' => 'Rozdělení objednávky:',
|
||||||
|
'code' => 'Kód',
|
||||||
|
'ean' => 'Ean',
|
||||||
|
'origPcs' => 'Kusů v této objednávce',
|
||||||
|
'newOrderPcs' => 'Kusů v nové objednávce',
|
||||||
|
'of' => 'z původních',
|
||||||
|
'returned' => 'Vráceno',
|
||||||
|
'prodFromOrders' => 'Produkty z objednávky',
|
||||||
|
'split' => 'Rozdělit objednávku',
|
||||||
|
'activitySplit' => 'Objednávka %s byla rozdělena do objednávky %s.',
|
||||||
|
'errorCanceledCantEdit' => 'Stornovanou objednávku již nelze upravovat',
|
||||||
|
'splitOldNote' => 'Tato objednávka byla rozdělena do objednávky: %s',
|
||||||
|
'splitNewNote' => 'Tato objednávka byla vytvořena rozdělením objednávky: %s',
|
||||||
|
];
|
||||||
17
admin/lang/czech/adminEdit.php
Normal file
17
admin/lang/czech/adminEdit.php
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$txt_str['adminEdit'] = [
|
||||||
|
'titleEdit' => 'Změna hesla',
|
||||||
|
|
||||||
|
'passwd_old' => 'Staré heslo',
|
||||||
|
'passwd_new' => 'Nové heslo',
|
||||||
|
'passwd_control' => 'Potvrzení hesla',
|
||||||
|
|
||||||
|
'flapChangePassw' => 'Změna hesla',
|
||||||
|
'passwForAdmin' => 'Administrátor %s',
|
||||||
|
|
||||||
|
'errorBadPassw' => 'Zadané současné heslo není správné',
|
||||||
|
'errorPasswNotEqual' => 'Nové heslo a potvrzení hesla se neshodují',
|
||||||
|
'errorPasswLength' => 'Minimální délka hesla je 6 znaků',
|
||||||
|
'activityPasswEdited' => 'Změněno heslo administrátora: %s',
|
||||||
|
];
|
||||||
176
admin/lang/czech/admins.php
Normal file
176
admin/lang/czech/admins.php
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$txt_str['admins'] = [
|
||||||
|
'titleAdd' => 'Nový administrátor',
|
||||||
|
'titleEdit' => 'Úprava administrátora',
|
||||||
|
'titlePassw' => 'Změna hesla',
|
||||||
|
|
||||||
|
'flapAdmin' => 'Administrátor',
|
||||||
|
'flapEshop' => 'Oprávnění: E-shop',
|
||||||
|
'flapArticles' => 'Oprávnění: Články',
|
||||||
|
'flapOthers' => 'Oprávnění: Ostatní',
|
||||||
|
'flapTranslations' => 'Oprávnění: Překlady',
|
||||||
|
'titleAdmin' => 'Administrátor',
|
||||||
|
'login' => 'Uživatelské jméno',
|
||||||
|
'name' => 'Jméno',
|
||||||
|
'email' => 'E-mail',
|
||||||
|
'datereg' => 'Datum reg.',
|
||||||
|
'active' => 'Aktivní',
|
||||||
|
'passwd' => 'Heslo',
|
||||||
|
'passwd_old' => 'Staré heslo',
|
||||||
|
'passwd_new' => 'Nové heslo',
|
||||||
|
'passwd_control' => 'Potvrzení hesla',
|
||||||
|
'passwdnote' => 'pozor, heslo se zobrazuje',
|
||||||
|
'validity' => 'Platnost do',
|
||||||
|
'choice_add' => 'Přidávat',
|
||||||
|
'choice_edit' => 'Editovat',
|
||||||
|
'choice_erase' => 'Mazat',
|
||||||
|
'choice_confirm' => 'Schvalovat',
|
||||||
|
'choice_refresh' => 'Obnovovat',
|
||||||
|
'choice_send' => 'Zasílat e-maily',
|
||||||
|
'passw' => 'Změna hesla',
|
||||||
|
'signature' => 'Podpis',
|
||||||
|
|
||||||
|
'flapChangePassw' => 'Změna hesla',
|
||||||
|
'infoPanelPassw' => 'Nastavujete heslo pro administrátorský účet <strong>%s</strong>. Doporučujeme Vám zvolit heslo složené z písmen a číslic nebo znaků.',
|
||||||
|
'passwForAdmin' => 'Administrátor %s',
|
||||||
|
|
||||||
|
'errorBadPassw' => 'Zadané současné heslo není správné',
|
||||||
|
'errorPasswNotEqual' => 'Nové heslo a potvrzení hesla se neshodují',
|
||||||
|
'errorNotAllValidPassw' => 'Musíte zadat původní heslo, nové heslo a potvrzení nového hesla.',
|
||||||
|
'errorNotAllValidAdmin' => 'Není všechno v pořádku vyplněno. Zadejte minimálně jméno a heslo administrátora.',
|
||||||
|
'errorMoreSameAdmins' => 'Zadaný login administrátora již používá jiný administrátor.',
|
||||||
|
'errorCantDeleteActive' => 'Nemůžete smazat administrátora, pod kterým jste právě přihlášen',
|
||||||
|
'confirmDelete' => 'Opravdu chcete smazat tohoto admina?',
|
||||||
|
'activityEdited' => 'Upraven administrátor: %s',
|
||||||
|
'activityAdded' => 'Přidán administrátor: %s',
|
||||||
|
'activityDeleted' => 'Smazán administrátor: %s',
|
||||||
|
'activityPasswEdited' => 'Změněno heslo administrátora: %s',
|
||||||
|
|
||||||
|
'warningVisible' => 'pozor, heslo se zobrazuje',
|
||||||
|
'generate' => 'Vygenerovat',
|
||||||
|
'generateMail' => 'Vygenerovat nové heslo na e-mail',
|
||||||
|
'generateSend' => 'vygenerovat nové heslo a poslat administrátorovi e-mailem',
|
||||||
|
'generateHash' => 'Vytisknout čárový kód pro přihlášení',
|
||||||
|
|
||||||
|
'AllRights' => 'Všechna práva',
|
||||||
|
'GrantAllRights' => 'Udělit všechna práva',
|
||||||
|
'Read' => 'Zobrazit',
|
||||||
|
|
||||||
|
'modulovna' => 'Modulovna',
|
||||||
|
'labels' => 'Štítky',
|
||||||
|
'ChoiceStock' => 'Kusů skladem',
|
||||||
|
'product_templates' => 'Šablony produktů',
|
||||||
|
'charges' => 'Příplatky',
|
||||||
|
'variant_labels' => 'Jmenovky variant',
|
||||||
|
'ChoiceComment' => 'Komentáře',
|
||||||
|
'Edit' => 'Upravovat',
|
||||||
|
'Goods' => 'Zboží',
|
||||||
|
'Parameters' => 'Parametry',
|
||||||
|
'Section' => 'Sekce',
|
||||||
|
'Manufacturers' => 'Výrobci',
|
||||||
|
'Orders' => 'Objednávky',
|
||||||
|
'DeliveryMethod' => 'Způsob doručení',
|
||||||
|
'Set' => 'Nastavovat',
|
||||||
|
'RegisteredUsers' => 'Uživatelé',
|
||||||
|
'choice_impersonate' => 'Přihlašovat se jako uživatel',
|
||||||
|
'user_groups' => 'Skupiny uživatelů',
|
||||||
|
'Discounts' => 'Slevy',
|
||||||
|
'DPH' => 'DPH',
|
||||||
|
'Use' => 'Používat',
|
||||||
|
'PriceLevels' => 'Cenové hladiny',
|
||||||
|
'OrderPayments' => 'Platby objednávek',
|
||||||
|
'payments' => 'Platby',
|
||||||
|
'balikobot' => 'Balíkobot',
|
||||||
|
'Currency' => 'Měny',
|
||||||
|
'Country' => 'Země',
|
||||||
|
'Language' => 'Jazyky',
|
||||||
|
'Manage' => 'Spravovat',
|
||||||
|
'Rating' => 'Hodnocení',
|
||||||
|
'Sliders' => 'Bannery',
|
||||||
|
|
||||||
|
'Restrictions' => 'Omezení prodeje',
|
||||||
|
'Sellers' => 'Prodejci',
|
||||||
|
'B2B_PREORDERS' => 'Předobjednávky',
|
||||||
|
'Reclamations' => 'Reklamace',
|
||||||
|
'Returns' => 'Vratky',
|
||||||
|
'TemplateCategories' => 'Kategorie setů',
|
||||||
|
'Watchdog' => 'Hlídací pes',
|
||||||
|
'SerialNumbers' => 'Sériové čísla',
|
||||||
|
'ProductsBatches' => 'Šarže produktů',
|
||||||
|
|
||||||
|
'Articles' => 'Články',
|
||||||
|
'Approve' => 'Schvalovat',
|
||||||
|
'Comments' => 'Komentáře',
|
||||||
|
'AuthorsOfArticles' => 'Autoři článků',
|
||||||
|
'SectionOfArticles' => 'Sekce článků:',
|
||||||
|
|
||||||
|
'Admins' => 'Administrátoři',
|
||||||
|
'EshopSettings' => 'Nastavení e-shopu',
|
||||||
|
'Emails' => 'E-maily',
|
||||||
|
'ActivityLog' => 'Activity Log',
|
||||||
|
'Photos' => 'Obrázky',
|
||||||
|
'FileBrowser' => 'Prohlížeč souborů',
|
||||||
|
'Backup' => 'Záloha databáze',
|
||||||
|
'Pages' => 'Stránky',
|
||||||
|
'Menulinks' => 'Stránky',
|
||||||
|
'Counters' => 'Počítadla',
|
||||||
|
'Stats' => 'Statistiky',
|
||||||
|
'View' => 'Prohlížet',
|
||||||
|
'Stock' => 'Sklad',
|
||||||
|
'Stocking' => 'Naskladnění',
|
||||||
|
'StockingDelete' => 'Mazání naskladnění',
|
||||||
|
'MissingSupplies' => 'Chybějící zásoby',
|
||||||
|
'StockTaking' => 'Inventura',
|
||||||
|
'PerformInventory' => 'Provést inventuru',
|
||||||
|
'PBX' => 'Telefonní ústředna',
|
||||||
|
'News' => 'Novinky',
|
||||||
|
'ManageNews' => 'Spravovat novinky',
|
||||||
|
'Feeds' => 'Feedy',
|
||||||
|
'choice_feeds_configurator_edit' => 'Editovat v konfigurátoru',
|
||||||
|
'Fulltext' => 'Fulltextové vyhledávání',
|
||||||
|
'Pricelists' => 'Ceníky',
|
||||||
|
'Stores' => 'Sklady',
|
||||||
|
'MainStat' => 'Statistiky na úvodní stránce',
|
||||||
|
'Show' => 'Zobrazit',
|
||||||
|
'PriceBuy' => 'Nákupní ceny',
|
||||||
|
'GlobalDiscounts' => 'Globální slevy',
|
||||||
|
'Reservations' => 'Rezervace',
|
||||||
|
'Dropshipment' => 'Dropshipment',
|
||||||
|
'Convertors' => 'Převodníky',
|
||||||
|
'Sales' => 'Prodejky',
|
||||||
|
'LlmPrompts' => 'AI prompty',
|
||||||
|
|
||||||
|
'clientSection' => 'Zákaznická sekce',
|
||||||
|
|
||||||
|
'languageTranslation' => 'Překlad jazyka',
|
||||||
|
|
||||||
|
'AdminsMenu' => 'Administrátoři',
|
||||||
|
'AddAdministrator' => 'Přidat administrátora',
|
||||||
|
'MenuHelp' => 'Nápověda',
|
||||||
|
|
||||||
|
'HasNotRights' => 'Nedostatečná práva',
|
||||||
|
|
||||||
|
'GeneratedCodes' => 'Generované kódy',
|
||||||
|
|
||||||
|
'impersonate' => 'Přihlásit se jako administrátor',
|
||||||
|
'impersonateHint' => 'Budete příhlášeni do administrace pod tímto účtem',
|
||||||
|
'impersonateLogMessage' => 'Administrátor se přihlásil jako administrátor "%s"',
|
||||||
|
|
||||||
|
'flapSignIn' => 'Přihlašování',
|
||||||
|
'token' => 'Přihlašovací token',
|
||||||
|
'regenerateToken' => 'Přegenerovat token',
|
||||||
|
'generateToken' => 'Vygenerovat token',
|
||||||
|
'WAR_CHECK_STOCK_IN_CHECK_ALL' => 'Povolit tlačítko "Zkontrolovat vše" v kontrole',
|
||||||
|
'ShoppingList' => 'Nákupní seznamy',
|
||||||
|
'automation_configurator' => 'Konf. autopilot',
|
||||||
|
'DynamicRelatedProducts' => 'Dynamické související zboží',
|
||||||
|
'Recommenders' => 'Doporučené zboží',
|
||||||
|
|
||||||
|
'flapAdminRestrictions' => 'Omezení zobrazení',
|
||||||
|
'flapOrdersRestriction' => 'Omezení zobrazení objednávek',
|
||||||
|
'flapUsersRestriction' => 'Omezení zobrazení uživatelů',
|
||||||
|
'enableOrdersRestriction' => 'Zapnout omezení zobrazení objednávek',
|
||||||
|
'enableUsersRestriction' => 'Zapnout omezení zobrazení uživatelů',
|
||||||
|
'translateSellers' => 'Překládat prodejce',
|
||||||
|
];
|
||||||
40
admin/lang/czech/artauthors.php
Normal file
40
admin/lang/czech/artauthors.php
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$txt_str['artauthors'] = [
|
||||||
|
'title' => 'Sekce',
|
||||||
|
'allitems' => 'Autoři článků',
|
||||||
|
'titleAdd' => 'Nový autor',
|
||||||
|
'titleEdit' => 'Editace autora',
|
||||||
|
'activityAdded' => 'přidán autor článků: %s',
|
||||||
|
'activityEdited' => 'upraven autor článků: %s',
|
||||||
|
'erased' => 'Smazáno',
|
||||||
|
|
||||||
|
'note_1' => 'Opravdu chcete smazat tohoto autora článků?',
|
||||||
|
'note_2' => 'Autor článků byl odstraněn z databáze',
|
||||||
|
|
||||||
|
'tabAuthor' => 'Autor článku',
|
||||||
|
'tabAuthorArticles' => 'Autorovy články',
|
||||||
|
'titleAuthorData' => 'Údaje o autorovi',
|
||||||
|
'labelFirstName' => 'Jméno',
|
||||||
|
'labelLastName' => 'Příjmení',
|
||||||
|
'labelNickName' => 'Přezdívka',
|
||||||
|
'labelNote' => 'Poznámka',
|
||||||
|
'labelAddress' => 'Adresa',
|
||||||
|
'labelEmail' => 'E-mail',
|
||||||
|
'labelPhone' => 'Telefon',
|
||||||
|
'labelBirthday' => 'Datum narození',
|
||||||
|
'labelGender' => 'Pohlaví',
|
||||||
|
'radioMale' => 'Muž',
|
||||||
|
'radioFemale' => 'Žena',
|
||||||
|
'labelActive' => 'Aktivní',
|
||||||
|
'labelRegistrationDate' => 'Datum registrace',
|
||||||
|
|
||||||
|
// List - side menu
|
||||||
|
'authorList' => 'Seznam autorů',
|
||||||
|
'addAuthor' => 'Přidat autora',
|
||||||
|
'help' => 'Nápověda',
|
||||||
|
'flapBlocks' => 'Obsah',
|
||||||
|
|
||||||
|
'search' => 'Vyhledávání',
|
||||||
|
'searchName' => 'Podle jména',
|
||||||
|
];
|
||||||
88
admin/lang/czech/articles.php
Normal file
88
admin/lang/czech/articles.php
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$txt_str['articles'] = [
|
||||||
|
'titleAdd' => 'Nový článek',
|
||||||
|
'titleEdit' => 'Editace článku',
|
||||||
|
'activityAdded' => 'přidán článek: %s',
|
||||||
|
'activityEdited' => 'upraven článek: %s',
|
||||||
|
'erased' => 'Smazáno',
|
||||||
|
'about_article' => 'Informace o článku',
|
||||||
|
'tabArticle' => 'Článek',
|
||||||
|
'tabTexts' => 'Obsah',
|
||||||
|
'tabCategorization' => 'Zařazení',
|
||||||
|
'tabAuthors' => 'Autoři',
|
||||||
|
'tabPhotos' => 'Obrázky',
|
||||||
|
'tabProducts' => 'Produkty',
|
||||||
|
'tabComments' => 'Komentáře',
|
||||||
|
'labelName' => 'Název',
|
||||||
|
'labelKeywords' => 'Klíčová slova',
|
||||||
|
'keywordsNote' => 'klíčová slova oddělujte čárkou',
|
||||||
|
'labelCountOfSeen' => 'Počet přečtení',
|
||||||
|
'labelType' => 'Typ článku',
|
||||||
|
'radioArticle' => 'článek',
|
||||||
|
'radioElsewhere' => 'odkaz jinam',
|
||||||
|
'labelLink' => 'Odkaz',
|
||||||
|
'labelDate' => 'Datum uveřejnění',
|
||||||
|
'dateTooltip' => 'Datum viditelnosti článku. Pokud datum nevyplníte, bude článek viditelný vždy.',
|
||||||
|
'labelDateCreated' => 'Datum vytvoření',
|
||||||
|
'labelShowArticle' => 'Zobrazovat článek',
|
||||||
|
'showInSearch' => 'Zobrazovat ve vyhledávání',
|
||||||
|
'labelTags' => 'Štítky',
|
||||||
|
'alertNotPermission' => 'Nemáte dostatečná práva na zobrazování článku',
|
||||||
|
'labelAnnotation' => 'Anotace',
|
||||||
|
'labelContent' => 'Obsah',
|
||||||
|
'labelAddToSections' => 'Zařazení do sekcí',
|
||||||
|
'addToSectionsNote' => 'Pro zařazení článku do sekce ho nejprve uložte.',
|
||||||
|
'labelArticleProducts' => 'Produkty zařazené k tomuto článku',
|
||||||
|
'addProductToArticle' => 'Přidat produkt k článkům',
|
||||||
|
'productName' => 'Název produktu',
|
||||||
|
'labelAction' => 'Akce',
|
||||||
|
'titleProductDetail' => 'Detail produktu',
|
||||||
|
'findArticle' => 'Najít článek',
|
||||||
|
'authors' => 'Autoři',
|
||||||
|
'seo_url' => 'URL článku',
|
||||||
|
|
||||||
|
'articlesRelated' => 'Související články',
|
||||||
|
'addRelatedArticle' => 'Přidat související článek',
|
||||||
|
|
||||||
|
// List - side menu
|
||||||
|
'articles' => 'Články',
|
||||||
|
'articleList' => 'Seznam článků',
|
||||||
|
'addArticle' => 'Přidat článek',
|
||||||
|
'filter' => 'Filtrování',
|
||||||
|
'filterBySections' => 'Podle sekcí',
|
||||||
|
'filterHidden' => 'Nezobrazené články',
|
||||||
|
'filterDisplayed' => 'Zobrazené články',
|
||||||
|
'lookUp' => 'Vyhledat',
|
||||||
|
'search' => 'Vyhledávání',
|
||||||
|
'searchBasic' => 'Základní vyhledávání',
|
||||||
|
'searchId' => 'Vyhledat podle čísla',
|
||||||
|
'searchIdPlaceholder' => 'Podle čísla',
|
||||||
|
'searchTitlePlaceholder' => 'Podle názvu',
|
||||||
|
'searchFigurePlaceholder' => 'Podle viditelnosti...',
|
||||||
|
'searchDate' => 'Vyhledat podle data',
|
||||||
|
'searchDateFrom' => 'Datum zveřejnění od:',
|
||||||
|
'searchDateFromPlaceholder' => 'Datum od',
|
||||||
|
'searchDateTo' => 'Datum zveřejnění do:',
|
||||||
|
'searchDateToPlaceholder' => 'Datum do',
|
||||||
|
'searchTag' => 'Vyhledat podle štítku',
|
||||||
|
'notDecide' => 'Nerozhoduje',
|
||||||
|
'delete' => 'Vymazat',
|
||||||
|
'find' => 'Hledat',
|
||||||
|
|
||||||
|
'title' => 'Nadpis',
|
||||||
|
'section' => 'Sekce',
|
||||||
|
'showArticle' => 'Zobrazovat článek',
|
||||||
|
'type' => 'Typ',
|
||||||
|
'seen' => 'Zobrazen',
|
||||||
|
'dateAdded' => 'Datum uveřejnění',
|
||||||
|
'date_created' => 'Datum vytvoření',
|
||||||
|
'contentEditing' => 'Editace obsahu',
|
||||||
|
'leadIn' => 'Lead in',
|
||||||
|
'link' => 'Odkaz',
|
||||||
|
'comments' => 'Komentáře',
|
||||||
|
'url' => 'URL',
|
||||||
|
'metaTitle' => 'Meta nadpis',
|
||||||
|
'metaDescription' => 'Meta popisek',
|
||||||
|
'article' => 'Článek',
|
||||||
|
];
|
||||||
14
admin/lang/czech/articlesTags.php
Normal file
14
admin/lang/czech/articlesTags.php
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$txt_str['articlesTags'] = [
|
||||||
|
'navigation' => 'Štítky',
|
||||||
|
'toolbar_list' => 'Seznam štítků',
|
||||||
|
'toolbar_add' => 'Přidat štítek',
|
||||||
|
|
||||||
|
'titleEdit' => 'Upravit štítek',
|
||||||
|
'titleAdd' => 'Přidat štítek',
|
||||||
|
|
||||||
|
'tag' => 'Štítek',
|
||||||
|
|
||||||
|
'flapArticlesTags' => 'Štítek',
|
||||||
|
];
|
||||||
59
admin/lang/czech/artsections.php
Normal file
59
admin/lang/czech/artsections.php
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$txt_str['artsections'] = [
|
||||||
|
'title' => 'Sekce',
|
||||||
|
'allitems' => 'Seznam kategorií',
|
||||||
|
'titleAdd' => 'Nová sekce',
|
||||||
|
'titleEdit' => 'Editace sekce',
|
||||||
|
'activityAdded' => 'přidána sekce článků: %s',
|
||||||
|
'activityEdited' => 'upravena sekce článků: %s',
|
||||||
|
'activityDeleted' => 'smazaná sekce článků: %s',
|
||||||
|
|
||||||
|
'name' => 'Jméno',
|
||||||
|
'description' => 'Popis',
|
||||||
|
'visibility' => 'Viditelná',
|
||||||
|
'behaviour' => 'Zobrazování',
|
||||||
|
'behaviour_1' => 'Zobrazovat jen články v sekci',
|
||||||
|
'behaviour_2' => 'Zobrazovat články v této sekci a jejích podsekcích',
|
||||||
|
'orderby' => 'Řadit podle',
|
||||||
|
'orderby_date' => 'Data uveřejnění článků',
|
||||||
|
'orderby_title' => 'Názvů článků',
|
||||||
|
'orderby_rating' => 'Hodnocení článků',
|
||||||
|
'orderby_seen' => 'Počtu přečtení',
|
||||||
|
'orderdir' => 'Směr řazení',
|
||||||
|
'orderdir_asc' => 'Vzestupně (A->Z, 1->9, od nejstarších)',
|
||||||
|
'orderdir_desc' => 'Sestupně (Z->A, 9->1, od nejnovějších)',
|
||||||
|
'submit' => 'Odeslat',
|
||||||
|
'template' => 'Šablona',
|
||||||
|
'template_default' => 'Výchozí šablona',
|
||||||
|
'items_per_page' => 'Počet položek',
|
||||||
|
'items_per_page_tooltip' => 'Počet položek zobrazených na jedné stránce',
|
||||||
|
'items_per_page_default' => 'Výchozí počet',
|
||||||
|
|
||||||
|
'section' => 'Sekce',
|
||||||
|
'topsection' => 'Nadsekce',
|
||||||
|
'topsection_new' => 'Nová nadsekce',
|
||||||
|
'sectionnotrelated' => 'Sekce není zařazena',
|
||||||
|
'mainsection' => 'Žádná nadřazená sekce',
|
||||||
|
'erase' => 'Mazání sekce',
|
||||||
|
'deleterelation' => 'Zrušit toto zařazení',
|
||||||
|
'dontmove' => 'Nikam nepřenášet',
|
||||||
|
'erased' => 'Smazáno',
|
||||||
|
'note_1' => 'Opravdu chcete smazat tuto sekci?',
|
||||||
|
'note_2' => 'Vybraná sekce má ješte podsekce. <br />Smažte nejdříve podsekce a pak teprve tuto sekci.',
|
||||||
|
'note_3' => 'Rozhodl jste se odstranit sekci ',
|
||||||
|
'note_4' => 'Tím také ale odstraníte návaznost zboží na tuto sekci a proto vyberte sekci do které se přenese všechno zboží uvnitř mazané sekce.',
|
||||||
|
'note_5' => 'Sekce odstraněna',
|
||||||
|
'meta_title' => 'Titulek (title)',
|
||||||
|
'meta_description' => 'Popis (description)',
|
||||||
|
'flapSeo' => 'SEO',
|
||||||
|
'maxLength100' => 'Maximálně 100 znaků.',
|
||||||
|
'maxLength160' => 'Maximálně 160 znaků.',
|
||||||
|
'maxLength250' => 'Maximálně 250 znaků.',
|
||||||
|
|
||||||
|
// List - side menu
|
||||||
|
'sections' => 'Sekce článků',
|
||||||
|
'sectionList' => 'Seznam sekcí',
|
||||||
|
'addSection' => 'Přidat sekci',
|
||||||
|
'help' => 'Nápověda',
|
||||||
|
];
|
||||||
12
admin/lang/czech/automatic_import.php
Normal file
12
admin/lang/czech/automatic_import.php
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$txt_str['automatic_import'] = [
|
||||||
|
'titleEdit' => 'Úprava automatického importu',
|
||||||
|
'titleAdd' => 'Přidání automatického importu',
|
||||||
|
'erased' => 'Smazáno',
|
||||||
|
'interval' => 'Nechcete-li automaticky synchronizovat, vyplňte 0.',
|
||||||
|
'deleteOld' => 'Nechcete-li mazat položky, nechte pole prázdné, případně vyplňte 0.',
|
||||||
|
'activityEdited' => 'Upraven automatický import: %s',
|
||||||
|
'activityAdded' => 'Přidán automatický import: %s',
|
||||||
|
'activityDeleted' => 'Smazán automatický import: %s',
|
||||||
|
];
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user