#10782: implement form manager for task specific form elements
Dieser Commit ist enthalten in:
Ursprung
34cc327896
Commit
5367dfdb5a
@ -28,7 +28,8 @@
|
||||
"php": ">=7.1",
|
||||
"oxid-esales/oxideshop-ce": "6.3 - 6.8",
|
||||
"league/csv": "^9.0",
|
||||
"mathieuviossat/arraytotexttable": "^1.0"
|
||||
"mathieuviossat/arraytotexttable": "^1.0",
|
||||
"form-manager/form-manager": "^6.1"
|
||||
},
|
||||
"extra": {
|
||||
"oxideshop": {
|
||||
|
@ -15,6 +15,10 @@ declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\Application\Model;
|
||||
|
||||
use D3\DataWizard\Application\Model\Exceptions\InputUnvalidException;
|
||||
use FormManager\Inputs\Checkbox;
|
||||
use FormManager\Inputs\Input;
|
||||
use FormManager\Inputs\Radio;
|
||||
use OxidEsales\Eshop\Core\DatabaseProvider;
|
||||
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
|
||||
use OxidEsales\Eshop\Core\Exception\DatabaseErrorException;
|
||||
@ -22,6 +26,8 @@ use OxidEsales\Eshop\Core\Registry;
|
||||
|
||||
abstract class ActionBase implements QueryBase
|
||||
{
|
||||
protected $formElements = [];
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
@ -36,6 +42,15 @@ abstract class ActionBase implements QueryBase
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
if ($this->hasFormElements()) {
|
||||
/** @var Input $element */
|
||||
foreach ($this->getFormElements() as $element) {
|
||||
if (false === $element->isValid()) {
|
||||
throw oxNew(InputUnvalidException::class, $this, $element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->executeAction( $this->getQuery() );
|
||||
}
|
||||
|
||||
@ -81,4 +96,38 @@ abstract class ActionBase implements QueryBase
|
||||
{
|
||||
return "D3_DATAWIZARD_ACTION_SUBMIT";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Input $input
|
||||
*/
|
||||
public function registerFormElement(Input $input)
|
||||
{
|
||||
switch (get_class($input)) {
|
||||
case Radio::class:
|
||||
case Checkbox::class:
|
||||
$input->setTemplate('<p class="form-check">{{ input }} {{ label }}</p>');
|
||||
$input->setAttribute('class', 'form-check-input');
|
||||
break;
|
||||
default:
|
||||
$input->setTemplate('<p class="formElements">{{ label }} {{ input }}</p>');
|
||||
$input->setAttribute('class', 'form-control');
|
||||
}
|
||||
$this->formElements[] = $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasFormElements(): bool
|
||||
{
|
||||
return (bool) count($this->formElements);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getFormElements(): array
|
||||
{
|
||||
return $this->formElements;
|
||||
}
|
||||
}
|
@ -16,6 +16,7 @@ declare(strict_types=1);
|
||||
namespace D3\DataWizard\Application\Model;
|
||||
|
||||
use D3\DataWizard\Application\Model\Actions\FixArtextendsItems;
|
||||
use D3\DataWizard\Application\Model\Exceptions\DataWizardException;
|
||||
use D3\DataWizard\Application\Model\Exports\InactiveCategories;
|
||||
use D3\DataWizard\Application\Model\Exports\KeyFigures;
|
||||
use OxidEsales\Eshop\Core\Registry;
|
||||
@ -53,7 +54,7 @@ class Configuration
|
||||
*/
|
||||
public function registerAction($group, ActionBase $action)
|
||||
{
|
||||
$this->actions[$group][md5(serialize($action))] = $action;
|
||||
$this->actions[$group][md5(get_class($action))] = $action;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -62,7 +63,7 @@ class Configuration
|
||||
*/
|
||||
public function registerExport($group, ExportBase $export)
|
||||
{
|
||||
$this->exports[$group][md5(serialize($export))] = $export;
|
||||
$this->exports[$group][md5(get_class($export))] = $export;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -162,6 +163,12 @@ class Configuration
|
||||
*/
|
||||
public function getExportById($id) : ExportBase
|
||||
{
|
||||
return $this->getAllExports()[$id];
|
||||
$allExports = $this->getAllExports();
|
||||
|
||||
if (false == $allExports[$id]) {
|
||||
throw oxNew(DataWizardException::class, 'no export with id '.$id);
|
||||
}
|
||||
|
||||
return $allExports[$id];
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\Application\Model\Exceptions;
|
||||
|
||||
interface DataWizardException
|
||||
use OxidEsales\Eshop\Core\Exception\StandardException;
|
||||
|
||||
class DataWizardException extends StandardException
|
||||
{
|
||||
}
|
@ -19,7 +19,7 @@ use Exception;
|
||||
use OxidEsales\Eshop\Core\Exception\StandardException;
|
||||
use OxidEsales\Eshop\Core\Registry;
|
||||
|
||||
class DebugException extends StandardException implements DataWizardException
|
||||
class DebugException extends DataWizardException
|
||||
{
|
||||
public function __construct($sMessage = "not set", $iCode = 0, Exception $previous = null )
|
||||
{
|
||||
|
46
src/Application/Model/Exceptions/InputUnvalidException.php
Normale Datei
46
src/Application/Model/Exceptions/InputUnvalidException.php
Normale Datei
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* https://www.d3data.de
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
|
||||
* @link https://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\Application\Model\Exceptions;
|
||||
|
||||
use D3\DataWizard\Application\Model\QueryBase;
|
||||
use Exception;
|
||||
use FormManager\Inputs\Input;
|
||||
use OxidEsales\Eshop\Core\Exception\StandardException;
|
||||
|
||||
class InputUnvalidException extends DataWizardException
|
||||
{
|
||||
/** @var QueryBase */
|
||||
public $task;
|
||||
|
||||
public function __construct( QueryBase $task, Input $inputElement, $iCode = 0, Exception $previous = null )
|
||||
{
|
||||
$messages = [];
|
||||
foreach ($inputElement->getError()->getIterator() as $item) {
|
||||
$messages[] = $inputElement->label->innerHTML.' -> '.$item->getMessage();
|
||||
}
|
||||
|
||||
$sMessage = implode(
|
||||
' - ',
|
||||
[
|
||||
$task->getTitle(),
|
||||
implode(', ', $messages)
|
||||
]
|
||||
);
|
||||
parent::__construct( $sMessage, $iCode, $previous );
|
||||
|
||||
$this->task = $task;
|
||||
}
|
||||
}
|
@ -19,7 +19,7 @@ use Exception;
|
||||
use OxidEsales\Eshop\Core\Exception\StandardException;
|
||||
use OxidEsales\Eshop\Core\Registry;
|
||||
|
||||
class NoSuitableRendererException extends StandardException implements DataWizardException
|
||||
class NoSuitableRendererException extends DataWizardException
|
||||
{
|
||||
public function __construct($sMessage = "not set", $iCode = 0, Exception $previous = null )
|
||||
{
|
||||
|
@ -15,8 +15,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\Application\Model\Exceptions;
|
||||
|
||||
use OxidEsales\Eshop\Core\Exception\StandardException;
|
||||
|
||||
class RenderException extends StandardException implements DataWizardException
|
||||
class RenderException extends DataWizardException
|
||||
{
|
||||
}
|
@ -17,9 +17,8 @@ namespace D3\DataWizard\Application\Model\Exceptions;
|
||||
|
||||
use D3\DataWizard\Application\Model\QueryBase;
|
||||
use Exception;
|
||||
use OxidEsales\Eshop\Core\Exception\StandardException;
|
||||
|
||||
class TaskException extends StandardException implements DataWizardException
|
||||
class TaskException extends DataWizardException
|
||||
{
|
||||
/** @var QueryBase */
|
||||
public $task;
|
||||
|
@ -15,11 +15,15 @@ declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\Application\Model;
|
||||
|
||||
use D3\DataWizard\Application\Model\Exceptions\InputUnvalidException;
|
||||
use D3\DataWizard\Application\Model\ExportRenderer\RendererBridge;
|
||||
use D3\ModCfg\Application\Model\d3filesystem;
|
||||
use D3\ModCfg\Application\Model\Exception\d3_cfg_mod_exception;
|
||||
use D3\ModCfg\Application\Model\Exception\d3ShopCompatibilityAdapterException;
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use FormManager\Inputs\Checkbox;
|
||||
use FormManager\Inputs\Input;
|
||||
use FormManager\Inputs\Radio;
|
||||
use OxidEsales\Eshop\Core\DatabaseProvider;
|
||||
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
|
||||
use OxidEsales\Eshop\Core\Exception\DatabaseErrorException;
|
||||
@ -28,6 +32,8 @@ use OxidEsales\Eshop\Core\Registry;
|
||||
|
||||
abstract class ExportBase implements QueryBase
|
||||
{
|
||||
protected $formElements = [];
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
@ -50,6 +56,15 @@ abstract class ExportBase implements QueryBase
|
||||
*/
|
||||
public function run($format = RendererBridge::FORMAT_CSV)
|
||||
{
|
||||
if ($this->hasFormElements()) {
|
||||
/** @var Input $element */
|
||||
foreach ($this->getFormElements() as $element) {
|
||||
if (false === $element->isValid()) {
|
||||
throw oxNew(InputUnvalidException::class, $this, $element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ $rows, $fieldNames ] = $this->getExportData( $this->getQuery() );
|
||||
|
||||
$content = $this->renderContent($rows, $fieldNames, $format);
|
||||
@ -160,4 +175,38 @@ abstract class ExportBase implements QueryBase
|
||||
|
||||
return [ $rows, $fieldNames ];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Input $input
|
||||
*/
|
||||
public function registerFormElement(Input $input)
|
||||
{
|
||||
switch (get_class($input)) {
|
||||
case Radio::class:
|
||||
case Checkbox::class:
|
||||
$input->setTemplate('<p class="form-check">{{ input }} {{ label }}</p>');
|
||||
$input->setAttribute('class', 'form-check-input');
|
||||
break;
|
||||
default:
|
||||
$input->setTemplate('<p class="formElements">{{ label }} {{ input }}</p>');
|
||||
$input->setAttribute('class', 'form-control');
|
||||
}
|
||||
$this->formElements[] = $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasFormElements(): bool
|
||||
{
|
||||
return (bool) count($this->formElements);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getFormElements(): array
|
||||
{
|
||||
return $this->formElements;
|
||||
}
|
||||
}
|
@ -16,15 +16,45 @@
|
||||
namespace D3\DataWizard\Application\Model\Exports;
|
||||
|
||||
use D3\DataWizard\Application\Model\ExportBase;
|
||||
use FormManager\Inputs\Date;
|
||||
use OxidEsales\Eshop\Application\Model\Order;
|
||||
use OxidEsales\Eshop\Core\Registry;
|
||||
use FormManager\Factory as FormFactory;
|
||||
|
||||
class KeyFigures extends ExportBase
|
||||
{
|
||||
const STARTDATE_NAME = 'startdate';
|
||||
const ENDDATE_NAME = 'enddate';
|
||||
|
||||
/**
|
||||
* Shopkennzahlen
|
||||
*/
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
/** @var Date $startDate */
|
||||
$startDateValue = Registry::getRequest()->getRequestEscapedParameter(self::STARTDATE_NAME);
|
||||
$startDate = FormFactory::date(
|
||||
Registry::getLang()->translateString('D3_DATAWIZARD_EXPORTS_KEYFIGURES_FIELD_STARTDATE'),
|
||||
[
|
||||
'name' => self::STARTDATE_NAME,
|
||||
'value' => $startDateValue
|
||||
]
|
||||
);
|
||||
$this->registerFormElement($startDate);
|
||||
|
||||
/** @var Date $endDate */
|
||||
$endDateValue = Registry::getRequest()->getRequestEscapedParameter(self::ENDDATE_NAME);
|
||||
$endDate = FormFactory::date(
|
||||
Registry::getLang()->translateString('D3_DATAWIZARD_EXPORTS_KEYFIGURES_FIELD_ENDDATE'),
|
||||
[
|
||||
'name' => self::ENDDATE_NAME,
|
||||
'value' => $endDateValue
|
||||
]
|
||||
);
|
||||
$this->registerFormElement($endDate);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
@ -43,19 +73,25 @@ class KeyFigures extends ExportBase
|
||||
$basketsTitle = Registry::getLang()->translateString('D3_DATAWIZARD_EXPORTS_KEYFIGURES_BASKETSIZE');
|
||||
$monthTitle = Registry::getLang()->translateString('D3_DATAWIZARD_EXPORTS_KEYFIGURES_MONTH');
|
||||
|
||||
$startDateValue = Registry::getRequest()->getRequestEscapedParameter(self::STARTDATE_NAME) ?: '1970-01-01';
|
||||
$endDateValue = Registry::getRequest()->getRequestEscapedParameter(self::ENDDATE_NAME) ?: date('Y-m-d');
|
||||
|
||||
return [
|
||||
'SELECT
|
||||
DATE_FORMAT(oo.oxorderdate, "%Y-%m") as :monthTitle,
|
||||
FORMAT(COUNT(oo.oxid), 0) AS :ordersTitle,
|
||||
FORMAT(SUM(oo.OXTOTALBRUTSUM / oo.oxcurrate) / COUNT(oo.oxid), 2) as :basketsTitle
|
||||
FROM '.$orderTable.' AS oo
|
||||
GROUP BY :monthTitle
|
||||
ORDER BY :monthTitle DESC
|
||||
WHERE oo.oxorderdate >= :startDate AND oo.oxorderdate <= :endDate
|
||||
GROUP BY DATE_FORMAT(oo.oxorderdate, "%Y-%m")
|
||||
ORDER BY DATE_FORMAT(oo.oxorderdate, "%Y-%m") DESC
|
||||
LIMIT 30',
|
||||
[
|
||||
'monthTitle' => $monthTitle,
|
||||
'ordersTitle' => $ordersTitle,
|
||||
'basketsTitle' => $basketsTitle
|
||||
'startDate' => $startDateValue,
|
||||
'endDate' => $endDateValue,
|
||||
'monthTitle' => $monthTitle,
|
||||
'ordersTitle' => $ordersTitle,
|
||||
'basketsTitle' => $basketsTitle
|
||||
]
|
||||
];
|
||||
}
|
||||
|
@ -15,6 +15,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\Application\Model;
|
||||
|
||||
use FormManager\Inputs\Input;
|
||||
|
||||
interface QueryBase
|
||||
{
|
||||
public function run();
|
||||
@ -38,4 +40,19 @@ interface QueryBase
|
||||
* @return array [string $query, array $parameters]
|
||||
*/
|
||||
public function getQuery() : array;
|
||||
|
||||
/**
|
||||
* @param Input $input
|
||||
*/
|
||||
public function registerFormElement(Input $input);
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasFormElements(): bool;
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getFormElements(): array;
|
||||
}
|
@ -55,6 +55,8 @@ $aLang = array(
|
||||
'D3_DATAWIZARD_EXPORTS_INACTIVECATEGORIES_COUNT' => 'Anzahl',
|
||||
|
||||
'D3_DATAWIZARD_EXPORTS_KEYFIGURES' => 'Bestellungskennzahlen nach Monat',
|
||||
'D3_DATAWIZARD_EXPORTS_KEYFIGURES_FIELD_STARTDATE'=> 'Startdatum (optional)',
|
||||
'D3_DATAWIZARD_EXPORTS_KEYFIGURES_FIELD_ENDDATE' => 'Enddatum (optional)',
|
||||
'D3_DATAWIZARD_EXPORTS_KEYFIGURES_ORDERSPERMONTH' => 'Bestellungen pro Monat',
|
||||
'D3_DATAWIZARD_EXPORTS_KEYFIGURES_BASKETSIZE' => 'Warenkorbhöhe',
|
||||
'D3_DATAWIZARD_EXPORTS_KEYFIGURES_MONTH' => 'Monat',
|
||||
|
@ -23,6 +23,10 @@
|
||||
h5.card-header {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
.formElements label {
|
||||
display: inline-block;
|
||||
margin: .5rem 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
[{capture name="d3script"}][{strip}]
|
||||
@ -72,9 +76,17 @@
|
||||
[{$action->getTitle()}]
|
||||
</h5>
|
||||
<div class="card-body">
|
||||
<p class="card-text">
|
||||
[{$action->getDescription()}]
|
||||
</p>
|
||||
[{if $action->getDescription()}]
|
||||
<p class="card-text">
|
||||
[{$action->getDescription()}]
|
||||
</p>
|
||||
[{/if}]
|
||||
|
||||
[{if $action->hasFormElements()}]
|
||||
[{foreach from=$action->getFormElements() item="formElement"}]
|
||||
[{$formElement}]
|
||||
[{/foreach}]
|
||||
[{/if}]
|
||||
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-primary" onclick="startAction('[{$id}]')">
|
||||
|
@ -23,6 +23,10 @@
|
||||
h5.card-header {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
.formElements label {
|
||||
display: inline-block;
|
||||
margin: .5rem 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
[{capture name="d3script"}][{strip}]
|
||||
@ -74,9 +78,17 @@
|
||||
[{$export->getTitle()}]
|
||||
</h5>
|
||||
<div class="card-body">
|
||||
<p class="card-text">
|
||||
[{$export->getDescription()}]
|
||||
</p>
|
||||
[{if $export->getDescription()}]
|
||||
<p class="card-text">
|
||||
[{$export->getDescription()}]
|
||||
</p>
|
||||
[{/if}]
|
||||
|
||||
[{if $export->hasFormElements()}]
|
||||
[{foreach from=$export->getFormElements() item="formElement"}]
|
||||
[{$formElement}]
|
||||
[{/foreach}]
|
||||
[{/if}]
|
||||
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-primary" onclick="startExport('[{$id}]', 'CSV')">
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren