810 lines
26 KiB
PHP
810 lines
26 KiB
PHP
<?php
|
|
|
|
namespace KupShop\AdminBundle\AdminListMassEdit;
|
|
|
|
use KupShop\AdminBundle\Admin\Actions\AbstractAction;
|
|
use KupShop\AdminBundle\Admin\Actions\ActionsLocator;
|
|
use KupShop\AdminBundle\Admin\Actions\IAction;
|
|
use KupShop\AdminBundle\AdminList\BaseList;
|
|
use KupShop\AdminBundle\Util\ActivityLog;
|
|
use KupShop\KupShopBundle\Context\CurrencyContext;
|
|
use KupShop\KupShopBundle\Util\HtmlBuilder\HTML;
|
|
use Query\Operator;
|
|
use Symfony\Contracts\Service\Attribute\Required;
|
|
|
|
class BaseListMassEdit implements IListMassEdit
|
|
{
|
|
/**
|
|
* @var BaseList
|
|
*/
|
|
protected $listClass;
|
|
|
|
protected $template = 'listEdit.tpl';
|
|
|
|
protected $figureDivide = [40, 100, 200, 500, 1000, 2000, 5000, 10000];
|
|
|
|
protected $fetchedItems;
|
|
|
|
protected $prefetchValues = [];
|
|
|
|
protected $actions;
|
|
protected $actionsFailed = [];
|
|
protected $actionCount = 0;
|
|
|
|
/** @required */
|
|
public ActionsLocator $actionsLocator;
|
|
|
|
protected array $currencies = [];
|
|
|
|
#[Required]
|
|
public CurrencyContext $currencyContext;
|
|
|
|
public function setListClass(BaseList $listClass): void
|
|
{
|
|
$this->listClass = $listClass;
|
|
if (!empty($this->getActions())) {
|
|
$tableDef = &$this->listClass->getTableDef();
|
|
$tableDef['fields']['Akce'] = ['visible' => 'Y', 'fieldType' => BaseList::TYPE_LIST_ACTIONS];
|
|
}
|
|
}
|
|
|
|
protected function getActions()
|
|
{
|
|
if (empty($this->actions)) {
|
|
$actions = $this->actionsLocator->getActions(getVal('type'));
|
|
/** @var AbstractAction $action */
|
|
foreach ($actions as $action) {
|
|
if ($action->showInMassEdit()) {
|
|
$this->actions[$action->getActionType()] = $action;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $this->actions;
|
|
}
|
|
|
|
public function get_vars()
|
|
{
|
|
$divide = getVal('divide', null, $this->figureDivide[0]);
|
|
$this->listClass->setPageDivide($divide);
|
|
|
|
$vars = $this->listClass->get_vars();
|
|
|
|
$vars['object'] = $vars['view'] = $this;
|
|
$vars['parent'] = $this->listClass->getTemplate();
|
|
$vars['divide']['items'] = array_combine($this->figureDivide, $this->figureDivide);
|
|
$vars['divide']['item'] = $divide;
|
|
$vars['listQueryString'] = $this->getListQueryString();
|
|
$this->listClass->setTemplate($this->template);
|
|
|
|
return $vars;
|
|
}
|
|
|
|
protected function stringCamelize($input, $separator = '_')
|
|
{
|
|
return str_replace($separator, '', ucwords($input, $separator));
|
|
}
|
|
|
|
public function getItemClass($class, $values, $fieldType)
|
|
{
|
|
if (is_callable($class)) {
|
|
$class = $class($values);
|
|
} elseif ($class && method_exists($this, $class)) {
|
|
$class = $this->$class($values);
|
|
}
|
|
|
|
if ($fieldType) {
|
|
$class .= ' edit_list_item';
|
|
}
|
|
|
|
return $class;
|
|
}
|
|
|
|
public function renderEditField($column, $values, $firstRow = false)
|
|
{
|
|
$editMethod = $this->getRenderMethodName($column);
|
|
$renders = $this->$editMethod($column, $values, $firstRow);
|
|
$renders = is_array($renders) ? $renders : [$renders];
|
|
|
|
$fieldType = $column['fieldType'];
|
|
|
|
if (!$firstRow && $fieldType !== BaseList::TYPE_POSITION) {
|
|
foreach ($renders as $renderItem) {
|
|
$renderItem->attr('disabled', true);
|
|
}
|
|
}
|
|
if ($fieldType == 'actions') {
|
|
$field_name = $fieldType;
|
|
} else {
|
|
$field_name = $this->listClass->getFieldArrayName($column['field']);
|
|
}
|
|
|
|
$columnEnabler = HTML::create('div')
|
|
->class('checkbox')
|
|
->tag('input')
|
|
->attr('type', 'checkbox')
|
|
->attr('style', 'margin: 0 10px 0 0; float:left;')
|
|
->class('columnEnabler'.($firstRow ? ' editFirstRow' : ''))
|
|
->attr('name', "checked[{$field_name}][{$values['id']}]")
|
|
->attr('id', "checked[{$field_name}][{$values['id']}]")
|
|
->end()
|
|
->tag('label')
|
|
->attr('for', "checked[{$field_name}][{$values['id']}]")
|
|
->end();
|
|
|
|
if ($fieldType === BaseList::TYPE_POSITION) {
|
|
// checked="checked" will be added from jQuery in listSortable.tpl
|
|
// after DnD stop
|
|
$columnEnabler = HTML::create('input')
|
|
->attr('type', 'checkbox')
|
|
->attr('style', 'display: none')
|
|
->class('columnEnabler'.($firstRow ? ' editFirstRow' : ''))
|
|
->attr('name', "checked[{$field_name}][{$values['id']}]")
|
|
->attr('id', "checked[{$field_name}][{$values['id']}]")
|
|
->end();
|
|
}
|
|
|
|
return [
|
|
$columnEnabler,
|
|
...$renders,
|
|
];
|
|
}
|
|
|
|
public function getBoolChecked($values): string
|
|
{
|
|
return $values == 'Y' ? 'checked' : '';
|
|
}
|
|
|
|
protected function massRenderString($column, $values)
|
|
{
|
|
$field_name = $this->listClass->getFieldArrayName($column['field']);
|
|
$value = $this->listClass->getListRowValue($values, $column['field']);
|
|
|
|
return HTML::create('input')
|
|
->attr('type', 'text')
|
|
->attr('name', "data[{$field_name}][{$values['id']}]")
|
|
->class('input')
|
|
->attr('style', 'width: 100%;')
|
|
->attr('value', $value);
|
|
}
|
|
|
|
protected function massRenderInt($column, $values, $firstRow)
|
|
{
|
|
$field_name = $this->listClass->getFieldArrayName($column['field']);
|
|
|
|
return HTML::create('input')
|
|
->attr('type', $firstRow ? 'text' : 'number')
|
|
->attr('name', "data[{$field_name}][{$values['id']}]")
|
|
->class('input')
|
|
->attr('style', 'width: 100%;')
|
|
->attr('value', $values[$field_name]);
|
|
}
|
|
|
|
protected function massRenderFloat($column, $values, $firstRow)
|
|
{
|
|
$field_name = $this->listClass->getFieldArrayName($column['field']);
|
|
|
|
return HTML::create('input')
|
|
->attr('type', $firstRow ? 'text' : 'number')
|
|
->attr('name', "data[{$field_name}][{$values['id']}]")
|
|
->class('input')
|
|
->attr('step', '0.0001')
|
|
->attr('value', $values[$field_name]);
|
|
}
|
|
|
|
protected function massRenderPrice($column, $values, $firstRow)
|
|
{
|
|
$field_name = $this->listClass->getFieldArrayName($column['field']);
|
|
$vat = (new \KupShop\AdminBundle\AdminList\BaseList())->getListRowValue($values, 'vat', getAdminVat()['id']);
|
|
|
|
$defaultWithVat = \Settings::getDefault()->prod_prefer_price_vat;
|
|
|
|
$vat = getVat($vat);
|
|
|
|
$select = HTML::create('select')
|
|
->class('input mass_price_vat listEdit-select')->attr('style', 'width: 35%;')
|
|
->attr('name', "data[{$field_name}_iswithvat][{$values['id']}]");
|
|
$option0 = $select->tag('option')
|
|
->text('Bez DPH')
|
|
->attr('value', 0);
|
|
$option1 = $select->tag('option')
|
|
->text('S DPH')
|
|
->attr('title', $vat.'%')
|
|
->attr('value', 1);
|
|
|
|
$price = $values[$field_name];
|
|
|
|
if ($defaultWithVat) {
|
|
$price = toDecimal($price)->addVat($vat);
|
|
$option1->attr('selected', 1);
|
|
} else {
|
|
$option0->attr('selected', 1);
|
|
}
|
|
|
|
return [
|
|
HTML::create('input')
|
|
->attr('type', $firstRow ? 'text' : 'number')
|
|
->attr('name', "data[{$field_name}][{$values['id']}]")
|
|
->class('input vat_target')
|
|
->attr('style', 'width: 65%;')
|
|
->attr('step', '0.0001')
|
|
->attr('value', $price),
|
|
HTML::create('input')
|
|
->class('input vat_value')
|
|
->attr('name', "data[{$field_name}_vat][{$values['id']}]")
|
|
->attr('type', 'hidden')
|
|
->attr('value', $vat),
|
|
$select,
|
|
];
|
|
}
|
|
|
|
protected function massRenderPriceWithCurrency($column, $values, $firstRow)
|
|
{
|
|
return $this->addCurrencySymbol($values['currency'] ?? null, $this->massRenderPrice($column, $values, $firstRow));
|
|
}
|
|
|
|
protected function massRenderFloatWithCurrency($column, $values, $firstRow)
|
|
{
|
|
return $this->addCurrencySymbol($values['currency'] ?? null, [$this->massRenderFloat($column, $values, $firstRow)]);
|
|
}
|
|
|
|
protected function massRenderBool($column, $values)
|
|
{
|
|
$field_name = $this->listClass->getFieldArrayName($column['field']);
|
|
|
|
$checked = $this->getBoolChecked($values[$field_name]);
|
|
|
|
return HTML::create('input')
|
|
->attr('type', 'checkbox')
|
|
->class('input')
|
|
->attr('style', 'margin: 0 10px 0 0; float:left;')
|
|
->attr('name', "data[{$field_name}][{$values['id']}]")
|
|
->attr('value', '1')
|
|
->attr($checked, $checked);
|
|
}
|
|
|
|
protected function massRenderList($column, $values)
|
|
{
|
|
$field_name = $this->listClass->getFieldArrayName($column['field']);
|
|
|
|
$select = HTML::create('select')
|
|
->class('input selecter listEdit-select')
|
|
->attr('style', 'width: 100%;')
|
|
->attr('name', "data[{$field_name}][{$values['id']}]");
|
|
|
|
$options = $column['fieldOptions'];
|
|
if ($values['id'] == 0 || empty($values[$field_name])) {
|
|
$options = ['' => '-'] + $options;
|
|
}
|
|
|
|
foreach ($options as $id => $value) {
|
|
$option = $select->tag('option')
|
|
->text($value)
|
|
->attr('value', $id);
|
|
if ($id == $values[$field_name]) {
|
|
$option->attr('selected', true);
|
|
}
|
|
}
|
|
|
|
return $select;
|
|
}
|
|
|
|
public function massRenderListMultiselect($column, $values)
|
|
{
|
|
$field_name = $this->listClass->getFieldArrayName($column['field']);
|
|
|
|
$select = HTML::create('select')
|
|
->class('input')
|
|
->attr('name', "data[{$field_name}][{$values['id']}][]")
|
|
->class('input selecter listEdit-multiselect')
|
|
->attr('data-filter-type', 'multiselect')
|
|
->attr('multiple');
|
|
|
|
$options = $column['fieldOptions'];
|
|
$selected = explode(',', $values[$field_name] ?? '');
|
|
|
|
foreach ($options as $id => $value) {
|
|
$option = $select->tag('option')
|
|
->text($value)
|
|
->attr('value', $id);
|
|
if (in_array($id, $selected)) {
|
|
$option->attr('selected', true);
|
|
}
|
|
}
|
|
|
|
return $select;
|
|
}
|
|
|
|
public function massRenderAutocomplete($column, $values)
|
|
{
|
|
$field_name = $this->listClass->getFieldArrayName($column['field']);
|
|
|
|
$value = $this->listClass->getListRowValue($values, $column['field']);
|
|
|
|
$select = HTML::create('select')
|
|
->class('input listEdit-autocomplete ajax-selecter')
|
|
->attr('style', 'width: 100%;')
|
|
->attr('data-type', $column['fieldOptions']['autocomplete'] ?? '')
|
|
->attr('name', "data[{$field_name}][{$values['id']}]");
|
|
|
|
if ($value !== null) {
|
|
if ($column['fieldOptions']['prefetchField'] ?? false) {
|
|
$name = $values[$column['fieldOptions']['prefetchField']] ?? $value;
|
|
} else {
|
|
$name = $this->getPrefetchFields($column['fieldOptions'], $field_name)[$value]['name'] ?? $value;
|
|
}
|
|
$select->tag('option')
|
|
->text($name)
|
|
->attr('value', $value)
|
|
->attr('selected', true);
|
|
}
|
|
|
|
return $select;
|
|
}
|
|
|
|
public function massRenderMultiselectAutocomplete($column, $values)
|
|
{
|
|
$field_name = $this->listClass->getFieldArrayName($column['field']);
|
|
|
|
$value = $this->listClass->getListRowValue($values, $column['field']);
|
|
|
|
if (($column['fieldOptions']['fieldType'] ?? '') == 'json') {
|
|
try {
|
|
$value = json_decode($value ?? '', true);
|
|
} catch (\Throwable $e) {
|
|
$value = [];
|
|
}
|
|
}
|
|
|
|
$select = HTML::create('select')
|
|
->class('input selecter listEdit-multiselectAutocomplete ajax-selecter')
|
|
->attr('style', 'width: 100%;')
|
|
->attr('data-type', $column['fieldOptions']['autocomplete'] ?? '')
|
|
->attr('name', "data[{$field_name}][{$values['id']}][]")
|
|
->attr('data-filter-type', 'multiselect')
|
|
->attr('multiple');
|
|
|
|
if ($value) {
|
|
if ($column['fieldOptions']['prefetchField'] ?? false) {
|
|
$prefetchValues = array_map(function ($val) use ($column) {
|
|
return ['id' => $val['id'], 'name' => $val[$column['fieldOptions']['prefetchField']] ?? $val['name']];
|
|
}, $value);
|
|
} else {
|
|
$prefetchValues = $this->getPrefetchFields($column['fieldOptions'], $field_name, array_keys($value));
|
|
}
|
|
|
|
foreach ($prefetchValues as $id => $value) {
|
|
$select->tag('option')
|
|
->text($value['name'])
|
|
->attr('value', $id)
|
|
->attr('selected', true);
|
|
}
|
|
}
|
|
|
|
return $select;
|
|
}
|
|
|
|
protected function massRenderActions($column, $values)
|
|
{
|
|
$html = HTML::create('div')
|
|
->tag('input')
|
|
->attr('type', 'checkbox')
|
|
->class('input')
|
|
->attr('style', 'margin: 0 10px 0 0; float:left;')
|
|
->attr('name', "data[actions][{$values['id']}]")
|
|
->attr('value', '0')
|
|
->attr($values['id'] == 0 ? '' : 'disabled');
|
|
|
|
if ($values['id'] == 0) {
|
|
$html->tag('input')
|
|
->attr('type', 'hidden')
|
|
->attr('name', 'actionsConfig')
|
|
->attr('id', 'actionsConfig');
|
|
|
|
$select = $html->tag('select')
|
|
->class('input')
|
|
->attr('style', 'width: 100%;')
|
|
->attr('name', 'selectedAction');
|
|
|
|
$select->tag('option')->text('--------')->attr('value', -1000);
|
|
|
|
/**
|
|
* @var $action AbstractAction
|
|
*/
|
|
foreach ($this->getActions() as $i => $action) {
|
|
$option = $select->tag('option')
|
|
->text($action->getName())
|
|
->attr('value', $i);
|
|
if ($i == $values['actions']) {
|
|
$option->attr('selected', true);
|
|
}
|
|
}
|
|
}
|
|
|
|
return $html;
|
|
}
|
|
|
|
public function massRenderPosition($column, $values)
|
|
{
|
|
if ($values['id'] == 0) {
|
|
return [];
|
|
}
|
|
|
|
$fieldName = $this->listClass->getFieldArrayName($column['field']);
|
|
|
|
return HTML::create('span')
|
|
->attr('class', 'drag-drop-mover')
|
|
->tag('span')
|
|
->attr('class', 'bi bi-arrows-move handle')
|
|
->end()
|
|
->tag('input')
|
|
->attr('type', 'hidden')
|
|
->attr('name', "data[{$fieldName}][{$values['id']}]")
|
|
->attr('data-sort', $values['id'])
|
|
->attr('value', $values[$fieldName])
|
|
->end()
|
|
->end();
|
|
}
|
|
|
|
protected function getPrefetchFields($fieldOptions, $fieldName, $ids = null)
|
|
{
|
|
if (empty($this->prefetchValues[$fieldName])) {
|
|
$prefetchMethod = 'massPrefetch'.$this->stringCamelize($fieldName);
|
|
if (method_exists($this, $prefetchMethod)) {
|
|
$this->prefetchValues[$fieldName] = $this->$prefetchMethod($fieldOptions, $fieldName, $ids);
|
|
} else {
|
|
$this->prefetchValues[$fieldName] = $this->massPrefetchBase($fieldOptions, $fieldName, $ids);
|
|
}
|
|
}
|
|
|
|
return $this->prefetchValues[$fieldName];
|
|
}
|
|
|
|
protected function massPrefetchBase($fieldOptions, $fieldName, $ids = null)
|
|
{
|
|
$ids = $ids ?? array_unique(array_map(function ($item) use ($fieldName) {
|
|
return $this->listClass->getListRowValue($item, $fieldName);
|
|
}, $this->fetchedItems));
|
|
|
|
return sqlFetchAll(sqlQueryBuilder()->select('id',
|
|
($fieldOptions['field'] ?? 'name').' as name')->from($fieldOptions['table'])->where(Operator::inStringArray($ids, 'id'))
|
|
->execute(),
|
|
'id');
|
|
}
|
|
|
|
protected function massSaveString($field, $activeIds, $values)
|
|
{
|
|
foreach ($activeIds as $id) {
|
|
if ($id == 0) {
|
|
continue;
|
|
}
|
|
$value = $values[$id] ?? '';
|
|
sqlQueryBuilder()->update($this->listClass->getTableName())
|
|
->directValues([$field => $value])
|
|
->where(Operator::equals(['id' => $id]))
|
|
->execute();
|
|
}
|
|
}
|
|
|
|
protected function massSaveInt($field, $activeIds, $values)
|
|
{
|
|
foreach ($values as $id => $value) {
|
|
sqlQueryBuilder()->update($this->listClass->getTableName())
|
|
->directValues([$field => $value])
|
|
->where(Operator::equals(['id' => $id]))
|
|
->execute();
|
|
}
|
|
}
|
|
|
|
protected function massSavePosition()
|
|
{
|
|
$this->massSaveInt(...func_get_args());
|
|
}
|
|
|
|
protected function massSaveFloat($field, $activeIds, $values)
|
|
{
|
|
$this->massSaveInt($field, $activeIds, $values);
|
|
}
|
|
|
|
protected function massSaveFloatWithCurrency($field, $activeIds, $values)
|
|
{
|
|
$this->massSaveFloat($field, $activeIds, $values);
|
|
}
|
|
|
|
protected function massSavePrice($field, $activeIds, $values)
|
|
{
|
|
$vatOptions = getVal('data')["{$field}_iswithvat"] ?? [];
|
|
$vatValues = getVal('data')["{$field}_vat"] ?? [];
|
|
|
|
foreach ($activeIds as $id) {
|
|
if (($vatOptions[$id] ?? false) && ($vatValues[$id] ?? false)) {
|
|
$values[$id] = toDecimal($values[$id])->removeVat($vatValues[$id])->asFloat();
|
|
}
|
|
}
|
|
$this->massSaveFloat($field, $activeIds, $values);
|
|
}
|
|
|
|
protected function massSavePriceWithCurrency($field, $activeIds, $values)
|
|
{
|
|
$this->massSavePrice($field, $activeIds, $values);
|
|
}
|
|
|
|
protected function massSaveBool($field, $activeIds, $values)
|
|
{
|
|
foreach ($activeIds as $id) {
|
|
sqlQueryBuilder()->update($this->listClass->getTableName())
|
|
->directValues([$field => ($values[$id] ?? false) ? 'Y' : 'N'])
|
|
->where(Operator::equals(['id' => $id]))
|
|
->execute();
|
|
}
|
|
}
|
|
|
|
protected function massSaveActions($fieldName, $activeIds, $values)
|
|
{
|
|
$actionIndex = getVal('selectedAction');
|
|
if ($actionIndex == -1000) {
|
|
return;
|
|
}
|
|
|
|
$values = $values ?: [];
|
|
|
|
$this->actionCount = count($values);
|
|
foreach ($values as $id => $tmp) {
|
|
if ($id == 0) {
|
|
$this->actionCount--;
|
|
continue;
|
|
}
|
|
|
|
/* @var IAction $action */
|
|
$action = $this->getActions()[$actionIndex];
|
|
$action->setId($id);
|
|
|
|
// parse actions config
|
|
parse_str(urldecode(getVal('actionsConfig')), $actionsConfig);
|
|
|
|
$data = $actionsConfig['data'] ?? [];
|
|
|
|
$result = $action->execute($data, $actionsConfig['config'] ?? [], getVal('type'));
|
|
if (!$result->isSuccessful()) {
|
|
$this->actionsFailed[$result->getMsg()][] = $action->getId();
|
|
}
|
|
}
|
|
}
|
|
|
|
protected function massSaveList($field, $activeIds, $values)
|
|
{
|
|
$this->massSaveString($field, $activeIds, $values);
|
|
}
|
|
|
|
protected function massSaveListMultiSelect($field, $activeIds, $values)
|
|
{
|
|
$values = array_map(function ($val) {
|
|
return implode(',', $val);
|
|
}, $values ?? []);
|
|
$this->massSaveString($field, $activeIds, $values);
|
|
}
|
|
|
|
protected function massSaveAutocomplete($field, $activeIds, $values)
|
|
{
|
|
$this->massSaveList($field, $activeIds, $values);
|
|
}
|
|
|
|
protected function massSaveMultiselectAutocomplete($field, $activeIds, $values)
|
|
{
|
|
$this->massSaveListMultiSelect($field, $activeIds, $values);
|
|
}
|
|
|
|
protected function massSaveAllFields(): void
|
|
{
|
|
$data = getVal('data');
|
|
$checked = getVal('checked');
|
|
|
|
foreach ($checked as $fieldName => $activeChecks) {
|
|
$activeIds = array_keys($activeChecks);
|
|
$fieldType = $this->findFieldTypeForName($fieldName);
|
|
|
|
if ($fieldType) {
|
|
$method = 'massSave'.$this->stringCamelize($fieldType);
|
|
$this->$method($fieldName, $activeIds, $data[$fieldName]);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected function handleSave()
|
|
{
|
|
$checked = getVal('checked') ?? [];
|
|
$editedIds = array_unique(
|
|
array_reduce(
|
|
$checked,
|
|
function ($v, $activeChecks) {
|
|
return array_merge($v, array_keys($activeChecks));
|
|
},
|
|
[]
|
|
)
|
|
);
|
|
|
|
$this->massSaveAllFields();
|
|
$actionName = '';
|
|
if (getVal('selectedAction') && getVal('selectedAction') != -1000) {
|
|
$actionName = $this->actionsLocator->getServiceByActionClassName(getVal('selectedAction'))->getName();
|
|
}
|
|
|
|
$list_type = getVal('type');
|
|
$typeName = translate('navigation', $list_type, true);
|
|
$typeName = $typeName ?: $list_type;
|
|
|
|
addActivityLog(
|
|
ActivityLog::SEVERITY_NOTICE,
|
|
ActivityLog::TYPE_CHANGE,
|
|
"{$typeName}: Provedena hromadná úprava {$actionName}",
|
|
[
|
|
'item_ids' => $editedIds,
|
|
'edited_fields' => array_keys($checked ?: []),
|
|
'action' => $actionName,
|
|
'list_type' => $list_type,
|
|
'actions_failed' => $this->actionsFailed,
|
|
]
|
|
);
|
|
|
|
if (empty($this->actionsFailed)) {
|
|
$this->returnOk($GLOBALS['txt_str']['status']['saved']);
|
|
} else {
|
|
$this->addHtmlError($this->prepareError());
|
|
}
|
|
}
|
|
|
|
protected function findFieldTypeForName($name)
|
|
{
|
|
$tableDef = $this->getTableDef();
|
|
|
|
if ($name == 'actions') {
|
|
return 'actions';
|
|
}
|
|
|
|
foreach ($tableDef['fields'] as $field) {
|
|
$tableDefName = $this->listClass->getFieldArrayName($field['field']);
|
|
|
|
if ($name === $tableDefName && isset($field['fieldType'])) {
|
|
return $field['fieldType'];
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public function printListFirstRowItem($column)
|
|
{
|
|
if (empty($column['fieldType']) || !method_exists($this, $this->getRenderMethodName($column)) || $column['editable'] == 'N') {
|
|
return '-';
|
|
}
|
|
|
|
$result = $this->renderEditField($column, ['id' => 0], true);
|
|
|
|
$this->massRenderResult($result);
|
|
}
|
|
|
|
protected function massRenderResult($result)
|
|
{
|
|
$output = function ($snippet) {
|
|
echo $snippet instanceof HTML ? (string) $snippet : htmlspecialchars($snippet);
|
|
};
|
|
if (is_array($result)) {
|
|
foreach ($result as $part) {
|
|
$output($part);
|
|
}
|
|
} else {
|
|
$output($result);
|
|
}
|
|
}
|
|
|
|
protected function getRenderMethodName($column)
|
|
{
|
|
return 'massRender'.$this->stringCamelize($column['fieldType']);
|
|
}
|
|
|
|
public function printListRowItem($column, &$values)
|
|
{
|
|
if (empty($column['fieldType']) || !method_exists($this, $this->getRenderMethodName($column)) || $column['editable'] == 'N') {
|
|
return $this->listClass->printListRowItem($column, $values);
|
|
}
|
|
|
|
$result = $this->renderEditField($column, $values);
|
|
|
|
$this->massRenderResult($result);
|
|
}
|
|
|
|
public function __call($name, $arguments)
|
|
{
|
|
if (method_exists($this->listClass, $name)) {
|
|
return call_user_func_array([$this->listClass, $name], $arguments);
|
|
}
|
|
|
|
throw new \Exception("Undefined method '{$name}'");
|
|
}
|
|
|
|
public function run()
|
|
{
|
|
// Process POSTEd values
|
|
$this->handle();
|
|
|
|
// Collect template variables
|
|
$vars = $this->collectVariables();
|
|
|
|
// Init templating system
|
|
$this->listClass->init_smarty();
|
|
|
|
// Assign template variables to template
|
|
$this->listClass->assign_($vars);
|
|
|
|
// Render template
|
|
$this->listClass->display();
|
|
}
|
|
|
|
protected function collectVariables()
|
|
{
|
|
$vars = $this->get_vars();
|
|
$this->fetchedItems = $vars['SQL'] = $vars['SQL']->fetchAll();
|
|
|
|
return $vars;
|
|
}
|
|
|
|
public function handle()
|
|
{
|
|
$acn = getVal('acn');
|
|
if ($acn) {
|
|
$action = 'handle'.ucfirst($acn);
|
|
if (method_exists($this, $action)) {
|
|
call_user_func([$this, $action]);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected function prepareError()
|
|
{
|
|
$error = '<ul>';
|
|
$errorCount = 0;
|
|
foreach ($this->actionsFailed as $key => $value) {
|
|
$items = implode('', array_map(function ($x) {return "<li>{$this->getDisplayId($x)}</li>"; }, $value));
|
|
$error .= "<li>{$key}<ul>{$items}</ul></li>";
|
|
$errorCount += count($value);
|
|
}
|
|
$error .= '</ul>';
|
|
$successCount = $this->actionCount - $errorCount;
|
|
|
|
return "<strong style='text-align: center'>Úspěšně provedeno {$successCount}/{$this->actionCount} akcí.</strong>".$error;
|
|
}
|
|
|
|
protected function getDisplayId($id)
|
|
{
|
|
return $id;
|
|
}
|
|
|
|
protected function getListQueryString(): string
|
|
{
|
|
$filter = ['s', 'type', 'order', 'page'];
|
|
$params = array_filter($_GET, fn ($k) => !in_array($k, $filter), ARRAY_FILTER_USE_KEY);
|
|
|
|
return http_build_query($params);
|
|
}
|
|
|
|
protected function addCurrencySymbol($currencyId, $return)
|
|
{
|
|
if ($currencyId) {
|
|
$return[] = HTML::create('span')
|
|
->attr('style', 'margin-left: 5px;')
|
|
->text($this->getCurrency($currencyId));
|
|
}
|
|
|
|
return $return;
|
|
}
|
|
|
|
protected function getCurrency(string $currency): string
|
|
{
|
|
if (empty($this->currencies)) {
|
|
$this->currencies = $this->currencyContext->getSupported();
|
|
}
|
|
|
|
return $this->currencies[$currency]->getSymbol() ?? $currency;
|
|
}
|
|
}
|