Compare commits

..

No commits in common. "master" and "rel_2.x" have entirely different histories.

51 changed files with 380 additions and 741 deletions

View File

@ -16,26 +16,22 @@ declare(strict_types=1);
namespace D3\DataWizard\Application\Controller\Admin; namespace D3\DataWizard\Application\Controller\Admin;
use D3\DataWizard\Application\Model\Configuration; use D3\DataWizard\Application\Model\Configuration;
use D3\DataWizard\Application\Model\Constants;
use D3\DataWizard\Application\Model\Exceptions\DataWizardException; use D3\DataWizard\Application\Model\Exceptions\DataWizardException;
use D3\DataWizard\Application\Model\Exceptions\DebugException; use D3\DataWizard\Application\Model\Exceptions\DebugException;
use D3\DataWizard\Application\Model\Exceptions\InputUnvalidException;
use D3\DataWizard\Application\Model\Exceptions\TaskException;
use D3\ModCfg\Application\Model\d3database; use D3\ModCfg\Application\Model\d3database;
use Doctrine\DBAL\Exception as DBALException; use Doctrine\DBAL\DBALException;
use OxidEsales\Eshop\Application\Controller\Admin\AdminDetailsController; use OxidEsales\Eshop\Application\Controller\Admin\AdminDetailsController;
use OxidEsales\Eshop\Core\Config;
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
use OxidEsales\Eshop\Core\Exception\DatabaseErrorException;
use OxidEsales\Eshop\Core\Registry; use OxidEsales\Eshop\Core\Registry;
use OxidEsales\EshopCommunity\Internal\Container\ContainerFactory;
use OxidEsales\EshopCommunity\Internal\Framework\Module\Facade\ModuleSettingService;
use OxidEsales\EshopCommunity\Internal\Framework\Module\Facade\ModuleSettingServiceInterface;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class d3ActionWizard extends AdminDetailsController class d3ActionWizard extends AdminDetailsController
{ {
protected $_sThisTemplate = '@'. Constants::OXID_MODULE_ID .'/admin/d3ActionWizard'; protected $_sThisTemplate = 'd3ActionWizard.tpl';
protected Configuration $configuration; /** @var Configuration */
protected $configuration;
public function __construct() public function __construct()
{ {
@ -44,78 +40,68 @@ class d3ActionWizard extends AdminDetailsController
$this->configuration = oxNew(Configuration::class); $this->configuration = oxNew(Configuration::class);
} }
public function getViewId(): string public function getViewId()
{ {
return 'd3mxDataWizard_Action'; return 'd3mxDataWizard_Action';
} }
public function getGroups(): array public function getGroups(): array
{ {
return $this->configuration->getActionGroups(); return $this->configuration->getActionGroups();
} }
public function getGroupTasks($group): array public function getGroupTasks($group)
{ {
return $this->configuration->getActionsByGroup($group); return $this->configuration->getActionsByGroup($group);
} }
/** /**
* @throws ContainerExceptionInterface * @throws DatabaseConnectionException
* @throws NotFoundExceptionInterface
*/ */
public function runTask(): void public function runTask()
{ {
try { try {
$this->execute(); $this->execute();
} catch (DataWizardException|DBALException $e) { } catch (DataWizardException|DBALException|DatabaseErrorException $e) {
Registry::getLogger()->error($e->getMessage()); Registry::getLogger()->error($e->getMessage());
Registry::getUtilsView()->addErrorToDisplay($e); Registry::getUtilsView()->addErrorToDisplay($e);
} }
} }
/** /**
* @throws ContainerExceptionInterface * @throws DatabaseConnectionException
* @throws DBALException * @throws DatabaseErrorException
* @throws DebugException
* @throws InputUnvalidException
* @throws NotFoundExceptionInterface
* @throws TaskException
*/ */
protected function execute(): void protected function execute()
{ {
$id = Registry::getRequest()->getRequestEscapedParameter('taskid'); $id = Registry::getRequest()->getRequestEscapedParameter('taskid');
$action = $this->configuration->getActionById($id); $action = $this->configuration->getActionById($id);
[ $queryString, $parameters ] = $action->getQuery(); [ $queryString, $parameters ] = $action->getQuery();
if ($this->getSettingsService()->getBoolean('d3datawizard_debug', Constants::OXID_MODULE_ID)) { if ($this->d3GetConfig()->getConfigParam('d3datawizard_debug')) {
/** @var DebugException $debug */ throw oxNew(
$debug = oxNew(
DebugException::class, DebugException::class,
d3database::getInstance()->getPreparedStatementQuery($queryString, $parameters) d3database::getInstance()->getPreparedStatementQuery($queryString, $parameters)
); );
throw $debug;
} }
$action->run(); $action->run();
} }
/** /**
* @return ModuleSettingService * @return Config
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/ */
public function getSettingsService(): ModuleSettingServiceInterface public function d3GetConfig(): Config
{ {
return ContainerFactory::getInstance()->getContainer()->get(ModuleSettingServiceInterface::class); return Registry::getConfig();
} }
public function getUserMessages(): ?string public function getUserMessages()
{ {
return null; return null;
} }
public function getHelpURL(): ?string public function getHelpURL()
{ {
return null; return null;
} }

View File

@ -16,31 +16,27 @@ declare(strict_types=1);
namespace D3\DataWizard\Application\Controller\Admin; namespace D3\DataWizard\Application\Controller\Admin;
use D3\DataWizard\Application\Model\Configuration; use D3\DataWizard\Application\Model\Configuration;
use D3\DataWizard\Application\Model\Constants;
use D3\DataWizard\Application\Model\Exceptions\DataWizardException; use D3\DataWizard\Application\Model\Exceptions\DataWizardException;
use D3\DataWizard\Application\Model\Exceptions\DebugException; use D3\DataWizard\Application\Model\Exceptions\DebugException;
use D3\DataWizard\Application\Model\Exceptions\NoSuitableRendererException; use D3\DataWizard\Application\Model\Exceptions\NoSuitableRendererException;
use D3\DataWizard\Application\Model\Exceptions\TaskException;
use D3\ModCfg\Application\Model\d3database; use D3\ModCfg\Application\Model\d3database;
use D3\ModCfg\Application\Model\Exception\d3_cfg_mod_exception; use D3\ModCfg\Application\Model\Exception\d3_cfg_mod_exception;
use D3\ModCfg\Application\Model\Exception\d3ShopCompatibilityAdapterException; use D3\ModCfg\Application\Model\Exception\d3ShopCompatibilityAdapterException;
use Doctrine\DBAL\Driver\Exception; use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Exception as DBALException;
use OxidEsales\Eshop\Application\Controller\Admin\AdminDetailsController; use OxidEsales\Eshop\Application\Controller\Admin\AdminDetailsController;
use OxidEsales\Eshop\Core\Config;
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException; use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
use OxidEsales\Eshop\Core\Exception\DatabaseErrorException; use OxidEsales\Eshop\Core\Exception\DatabaseErrorException;
use OxidEsales\Eshop\Core\Exception\StandardException; use OxidEsales\Eshop\Core\Exception\StandardException;
use OxidEsales\Eshop\Core\Registry; use OxidEsales\Eshop\Core\Registry;
use OxidEsales\EshopCommunity\Internal\Container\ContainerFactory;
use OxidEsales\EshopCommunity\Internal\Framework\Module\Facade\ModuleSettingService;
use OxidEsales\EshopCommunity\Internal\Framework\Module\Facade\ModuleSettingServiceInterface;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class d3ExportWizard extends AdminDetailsController class d3ExportWizard extends AdminDetailsController
{ {
protected $_sThisTemplate = '@'. Constants::OXID_MODULE_ID .'/admin/d3ExportWizard'; protected $_sThisTemplate = 'd3ExportWizard.tpl';
protected Configuration $configuration; /** @var Configuration */
protected $configuration;
public function __construct() public function __construct()
{ {
@ -49,7 +45,7 @@ class d3ExportWizard extends AdminDetailsController
$this->configuration = oxNew(Configuration::class); $this->configuration = oxNew(Configuration::class);
} }
public function getViewId(): string public function getViewId()
{ {
return 'd3mxDataWizard_Export'; return 'd3mxDataWizard_Export';
} }
@ -59,21 +55,18 @@ class d3ExportWizard extends AdminDetailsController
return $this->configuration->getExportGroups(); return $this->configuration->getExportGroups();
} }
public function getGroupTasks($group): array public function getGroupTasks($group)
{ {
return $this->configuration->getExportsByGroup($group); return $this->configuration->getExportsByGroup($group);
} }
/** /**
* @throws ContainerExceptionInterface
* @throws DatabaseConnectionException * @throws DatabaseConnectionException
* @throws Exception
* @throws NotFoundExceptionInterface
* @throws StandardException * @throws StandardException
* @throws d3ShopCompatibilityAdapterException * @throws d3ShopCompatibilityAdapterException
* @throws d3_cfg_mod_exception * @throws d3_cfg_mod_exception
*/ */
public function runTask(): void public function runTask()
{ {
try { try {
$this->execute(); $this->execute();
@ -87,22 +80,20 @@ class d3ExportWizard extends AdminDetailsController
* @throws DBALException * @throws DBALException
* @throws DatabaseConnectionException * @throws DatabaseConnectionException
* @throws DatabaseErrorException * @throws DatabaseErrorException
* @throws NoSuitableRendererException
* @throws StandardException * @throws StandardException
* @throws Exception * @throws NoSuitableRendererException
* @throws ContainerExceptionInterface * @throws TaskException
* @throws NotFoundExceptionInterface
* @throws d3ShopCompatibilityAdapterException * @throws d3ShopCompatibilityAdapterException
* @throws d3_cfg_mod_exception * @throws d3_cfg_mod_exception
*/ */
protected function execute(): void protected function execute()
{ {
$id = Registry::getRequest()->getRequestEscapedParameter('taskid'); $id = Registry::getRequest()->getRequestEscapedParameter('taskid');
$export = $this->configuration->getExportById($id); $export = $this->configuration->getExportById($id);
[ $queryString, $parameters ] = $export->getQuery(); [ $queryString, $parameters ] = $export->getQuery();
if ($this->getSettingsService()->getBoolean('d3datawizard_debug', Constants::OXID_MODULE_ID)) { if ($this->d3GetConfig()->getConfigParam('d3datawizard_debug')) {
throw oxNew( throw oxNew(
DebugException::class, DebugException::class,
d3database::getInstance()->getPreparedStatementQuery($queryString, $parameters) d3database::getInstance()->getPreparedStatementQuery($queryString, $parameters)
@ -113,21 +104,19 @@ class d3ExportWizard extends AdminDetailsController
} }
/** /**
* @return ModuleSettingService * @return Config
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/ */
public function getSettingsService(): ModuleSettingServiceInterface public function d3GetConfig(): Config
{ {
return ContainerFactory::getInstance()->getContainer()->get(ModuleSettingServiceInterface::class); return Registry::getConfig();
} }
public function getUserMessages(): ?string public function getUserMessages()
{ {
return null; return null;
} }
public function getHelpURL(): ?string public function getHelpURL()
{ {
return null; return null;
} }

View File

@ -16,21 +16,18 @@ declare(strict_types=1);
namespace D3\DataWizard\Application\Model; namespace D3\DataWizard\Application\Model;
use D3\DataWizard\Application\Model\Exceptions\InputUnvalidException; use D3\DataWizard\Application\Model\Exceptions\InputUnvalidException;
use D3\DataWizard\Application\Model\Exceptions\TaskException;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Exception as DBALException;
use FormManager\Inputs\Checkbox; use FormManager\Inputs\Checkbox;
use FormManager\Inputs\Input; use FormManager\Inputs\Input;
use FormManager\Inputs\Radio; use FormManager\Inputs\Radio;
use OxidEsales\Eshop\Core\Database\Adapter\DatabaseInterface;
use OxidEsales\Eshop\Core\DatabaseProvider;
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
use OxidEsales\Eshop\Core\Exception\DatabaseErrorException;
use OxidEsales\Eshop\Core\Registry; use OxidEsales\Eshop\Core\Registry;
use OxidEsales\EshopCommunity\Internal\Container\ContainerFactory;
use OxidEsales\EshopCommunity\Internal\Framework\Database\ConnectionProviderInterface;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
abstract class ActionBase implements QueryBase abstract class ActionBase implements QueryBase
{ {
protected array $formElements = []; protected $formElements = [];
/** /**
* Ensure that the translations are equally available in the frontend and the backend * Ensure that the translations are equally available in the frontend and the backend
@ -42,21 +39,16 @@ abstract class ActionBase implements QueryBase
} }
/** /**
* @throws ContainerExceptionInterface * @throws DatabaseConnectionException
* @throws DBALException * @throws DatabaseErrorException
* @throws InputUnvalidException
* @throws NotFoundExceptionInterface
* @throws TaskException
*/ */
public function run(): void public function run()
{ {
if ($this->hasFormElements()) { if ($this->hasFormElements()) {
/** @var Input $element */ /** @var Input $element */
foreach ($this->getFormElements() as $element) { foreach ($this->getFormElements() as $element) {
if (false === $element->isValid()) { if (false === $element->isValid()) {
/** @var InputUnvalidException $exception */ throw oxNew(InputUnvalidException::class, $this, $element);
$exception = oxNew(InputUnvalidException::class, $this, $element);
throw $exception;
} }
} }
} }
@ -67,33 +59,28 @@ abstract class ActionBase implements QueryBase
/** /**
* @param array $query * @param array $query
* *
* @return void * @return int
* @throws ContainerExceptionInterface * @throws DatabaseConnectionException
* @throws NotFoundExceptionInterface * @throws DatabaseErrorException
* @throws TaskException
* @throws DBALException
*/ */
public function executeAction(array $query): void public function executeAction(array $query): int
{ {
[ $queryString, $parameters ] = $query; [ $queryString, $parameters ] = $query;
$queryString = trim($queryString); $queryString = trim($queryString);
if (strtolower(substr($queryString, 0, 6)) === 'select') { if (strtolower(substr($queryString, 0, 6)) === 'select') {
/** @var TaskException $exception */ throw oxNew(
$exception = oxNew( Exceptions\TaskException::class,
TaskException::class,
$this, $this,
Registry::getLang()->translateString('D3_DATAWIZARD_ERR_ACTIONSELECT') Registry::getLang()->translateString('D3_DATAWIZARD_ERR_ACTIONSELECT')
); );
throw $exception;
} }
$affected = (int) $this->getConnection()->executeStatement($queryString, $parameters); $affected = $this->d3GetDb()->execute($queryString, $parameters);
/** @var TaskException $exception */ throw oxNew(
$exception = oxNew( Exceptions\TaskException::class,
TaskException::class,
$this, $this,
sprintf( sprintf(
Registry::getLang()->translateString( Registry::getLang()->translateString(
@ -102,12 +89,15 @@ abstract class ActionBase implements QueryBase
$affected $affected
) )
); );
throw $exception;
} }
protected function getConnection(): Connection /**
* @return DatabaseInterface|null
* @throws DatabaseConnectionException
*/
public function d3GetDb(): ?DatabaseInterface
{ {
return ContainerFactory::getInstance()->getContainer()->get(ConnectionProviderInterface::class)->get(); return DatabaseProvider::getDb(DatabaseProvider::FETCH_MODE_ASSOC);
} }
/** /**
@ -121,7 +111,7 @@ abstract class ActionBase implements QueryBase
/** /**
* @param Input $input * @param Input $input
*/ */
public function registerFormElement(Input $input): void public function registerFormElement(Input $input)
{ {
if ($input instanceof Radio || $input instanceof Checkbox) { if ($input instanceof Radio || $input instanceof Checkbox) {
$input->setTemplate('<p class="form-check">{{ input }} {{ label }}</p>'); $input->setTemplate('<p class="form-check">{{ input }} {{ label }}</p>');

View File

@ -27,8 +27,8 @@ class Configuration
public const GROUP_REMARKS = 'D3_DATAWIZARD_GROUP_REMARKS'; public const GROUP_REMARKS = 'D3_DATAWIZARD_GROUP_REMARKS';
public const GROUP_CMS = 'D3_DATAWIZARD_GROUP_CMS'; public const GROUP_CMS = 'D3_DATAWIZARD_GROUP_CMS';
protected array $actions = []; protected $actions = [];
protected array $exports = []; protected $exports = [];
public function __construct() public function __construct()
{ {
@ -44,7 +44,7 @@ class Configuration
* @param $group * @param $group
* @param ActionBase $action * @param ActionBase $action
*/ */
public function registerAction($group, ActionBase $action): void public function registerAction($group, ActionBase $action)
{ {
$this->actions[$group][md5(get_class($action))] = $action; $this->actions[$group][md5(get_class($action))] = $action;
} }
@ -53,7 +53,7 @@ class Configuration
* @param $group * @param $group
* @param ExportBase $export * @param ExportBase $export
*/ */
public function registerExport($group, ExportBase $export): void public function registerExport($group, ExportBase $export)
{ {
$this->exports[$group][md5(get_class($export))] = $export; $this->exports[$group][md5(get_class($export))] = $export;
} }
@ -93,9 +93,9 @@ class Configuration
/** /**
* @param $group * @param $group
* *
* @return array * @return mixed
*/ */
public function getActionsByGroup($group): array public function getActionsByGroup($group)
{ {
return $this->actions[$group]; return $this->actions[$group];
} }
@ -103,9 +103,9 @@ class Configuration
/** /**
* @param $group * @param $group
* *
* @return array * @return mixed
*/ */
public function getExportsByGroup($group): array public function getExportsByGroup($group)
{ {
return $this->exports[$group]; return $this->exports[$group];
} }
@ -147,7 +147,7 @@ class Configuration
{ {
$allActions = $this->getAllActions(); $allActions = $this->getAllActions();
if ( ! $allActions[ $id ] ) { if (false == $allActions[$id]) {
throw oxNew(DataWizardException::class, 'no action with id '.$id); throw oxNew(DataWizardException::class, 'no action with id '.$id);
} }
@ -163,7 +163,7 @@ class Configuration
{ {
$allExports = $this->getAllExports(); $allExports = $this->getAllExports();
if ( ! $allExports[ $id ] ) { if (false == $allExports[$id]) {
throw oxNew(DataWizardException::class, 'no export with id '.$id); throw oxNew(DataWizardException::class, 'no export with id '.$id);
} }

View File

@ -1,21 +0,0 @@
<?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 <support@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
namespace D3\DataWizard\Application\Model;
class Constants
{
public const OXID_MODULE_ID = 'd3datawizard';
}

View File

@ -21,7 +21,8 @@ use FormManager\Inputs\Input;
class InputUnvalidException extends DataWizardException class InputUnvalidException extends DataWizardException
{ {
public QueryBase $task; /** @var QueryBase */
public $task;
/** /**
* InputUnvalidException constructor. * InputUnvalidException constructor.

View File

@ -20,7 +20,8 @@ use Exception;
class TaskException extends DataWizardException class TaskException extends DataWizardException
{ {
public QueryBase $task; /** @var QueryBase */
public $task;
public function __construct(QueryBase $task, $sMessage = "not set", $iCode = 0, Exception $previous = null) public function __construct(QueryBase $task, $sMessage = "not set", $iCode = 0, Exception $previous = null)
{ {

View File

@ -15,33 +15,26 @@ declare(strict_types=1);
namespace D3\DataWizard\Application\Model; namespace D3\DataWizard\Application\Model;
use Assert\Assert;
use D3\DataWizard\Application\Model\Exceptions\ExportFileException; use D3\DataWizard\Application\Model\Exceptions\ExportFileException;
use D3\DataWizard\Application\Model\Exceptions\InputUnvalidException; use D3\DataWizard\Application\Model\Exceptions\InputUnvalidException;
use D3\DataWizard\Application\Model\Exceptions\NoSuitableRendererException;
use D3\DataWizard\Application\Model\ExportRenderer\RendererBridge; use D3\DataWizard\Application\Model\ExportRenderer\RendererBridge;
use D3\DataWizard\Application\Model\ExportRenderer\RendererInterface;
use D3\ModCfg\Application\Model\d3filesystem; use D3\ModCfg\Application\Model\d3filesystem;
use D3\ModCfg\Application\Model\Exception\d3_cfg_mod_exception; use D3\ModCfg\Application\Model\Exception\d3_cfg_mod_exception;
use D3\ModCfg\Application\Model\Exception\d3ShopCompatibilityAdapterException; use D3\ModCfg\Application\Model\Exception\d3ShopCompatibilityAdapterException;
use Doctrine\DBAL\Connection; use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Driver\Exception;
use Doctrine\DBAL\Exception as DBALException;
use FormManager\Inputs\Checkbox; use FormManager\Inputs\Checkbox;
use FormManager\Inputs\Input; use FormManager\Inputs\Input;
use FormManager\Inputs\Radio; use FormManager\Inputs\Radio;
use OxidEsales\Eshop\Core\Database\Adapter\DatabaseInterface;
use OxidEsales\Eshop\Core\DatabaseProvider;
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException; use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
use OxidEsales\Eshop\Core\Exception\DatabaseErrorException; use OxidEsales\Eshop\Core\Exception\DatabaseErrorException;
use OxidEsales\Eshop\Core\Exception\StandardException; use OxidEsales\Eshop\Core\Exception\StandardException;
use OxidEsales\Eshop\Core\Registry; use OxidEsales\Eshop\Core\Registry;
use OxidEsales\EshopCommunity\Internal\Container\ContainerFactory;
use OxidEsales\EshopCommunity\Internal\Framework\Database\ConnectionProviderInterface;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
abstract class ExportBase implements QueryBase abstract class ExportBase implements QueryBase
{ {
protected array $formElements = []; protected $formElements = [];
/** /**
* Ensure that the translations are equally available in the frontend and the backend * Ensure that the translations are equally available in the frontend and the backend
@ -54,19 +47,17 @@ abstract class ExportBase implements QueryBase
/** /**
* @param string $format * @param string $format
* @param null $path * @param $path
* *
* @return string
* @throws ContainerExceptionInterface
* @throws DBALException * @throws DBALException
* @throws DatabaseConnectionException * @throws DatabaseConnectionException
* @throws DatabaseErrorException * @throws DatabaseErrorException
* @throws Exception * @throws Exceptions\NoSuitableRendererException
* @throws NoSuitableRendererException * @throws Exceptions\TaskException
* @throws NotFoundExceptionInterface
* @throws StandardException * @throws StandardException
* @throws d3ShopCompatibilityAdapterException * @throws d3ShopCompatibilityAdapterException
* @throws d3_cfg_mod_exception * @throws d3_cfg_mod_exception
* @return string
*/ */
public function run(string $format = RendererBridge::FORMAT_CSV, $path = null): string public function run(string $format = RendererBridge::FORMAT_CSV, $path = null): string
{ {
@ -91,22 +82,31 @@ abstract class ExportBase implements QueryBase
} }
/** /**
* @throws NoSuitableRendererException * @param $format
*
* @return ExportRenderer\RendererInterface
* @throws Exceptions\NoSuitableRendererException
*/ */
public function getRenderer(string $format): RendererInterface public function getRenderer($format): ExportRenderer\RendererInterface
{ {
return $this->getRendererBridge()->getRenderer($format); return $this->getRendererBridge()->getRenderer($format);
} }
/**
* @return RendererBridge
*/
public function getRendererBridge(): RendererBridge public function getRendererBridge(): RendererBridge
{ {
return oxNew(RendererBridge::class); return oxNew(RendererBridge::class);
} }
/** /**
* @throws NoSuitableRendererException * @param $format
*
* @return string
* @throws Exceptions\NoSuitableRendererException
*/ */
public function getFileExtension(string $format): string public function getFileExtension($format): string
{ {
return $this->getRenderer($format)->getFileExtension(); return $this->getRenderer($format)->getFileExtension();
} }
@ -148,16 +148,13 @@ abstract class ExportBase implements QueryBase
* @param array $query * @param array $query
* *
* @return array * @return array
* @throws DBALException * @throws DatabaseConnectionException
* @throws Exception * @throws DatabaseErrorException
*/ */
public function getExportData(array $query): array public function getExportData(array $query): array
{ {
[ $queryString, $parameters ] = $query; [ $queryString, $parameters ] = $query;
Assert::that($queryString)->string();
Assert::that($parameters)->isArray();
$queryString = trim($queryString); $queryString = trim($queryString);
if (strtolower(substr($queryString, 0, 6)) !== 'select') { if (strtolower(substr($queryString, 0, 6)) !== 'select') {
@ -168,7 +165,7 @@ abstract class ExportBase implements QueryBase
); );
} }
$rows = $this->getConnection()->executeQuery($queryString, $parameters)->fetchAllAssociative(); $rows = $this->d3GetDb()->getAll($queryString, $parameters);
if (count($rows) <= 0) { if (count($rows) <= 0) {
throw oxNew( throw oxNew(
@ -183,12 +180,10 @@ abstract class ExportBase implements QueryBase
return [ $rows, $fieldNames ]; return [ $rows, $fieldNames ];
} }
protected function getConnection(): Connection /**
{ * @param Input $input
return ContainerFactory::getInstance()->getContainer()->get(ConnectionProviderInterface::class)->get(); */
} public function registerFormElement(Input $input)
public function registerFormElement(Input $input): void
{ {
if ($input instanceof Radio || $input instanceof Checkbox) { if ($input instanceof Radio || $input instanceof Checkbox) {
$input->setTemplate('<p class="form-check">{{ input }} {{ label }}</p>'); $input->setTemplate('<p class="form-check">{{ input }} {{ label }}</p>');
@ -218,16 +213,12 @@ abstract class ExportBase implements QueryBase
/** /**
* @param string $format * @param string $format
* @param $path * @param $path
*
* @return string * @return string
* @throws ContainerExceptionInterface
* @throws DBALException * @throws DBALException
* @throws DatabaseConnectionException * @throws DatabaseConnectionException
* @throws DatabaseErrorException * @throws DatabaseErrorException
* @throws Exception * @throws Exceptions\NoSuitableRendererException
* @throws NoSuitableRendererException
* @throws NotFoundExceptionInterface
* @throws StandardException * @throws StandardException
* @throws d3ShopCompatibilityAdapterException * @throws d3ShopCompatibilityAdapterException
* @throws d3_cfg_mod_exception * @throws d3_cfg_mod_exception
@ -236,12 +227,13 @@ abstract class ExportBase implements QueryBase
{ {
$content = $this->getContent($format); $content = $this->getContent($format);
/** @var $oFS d3filesystem */
$oFS = $this->getFileSystem(); $oFS = $this->getFileSystem();
if (is_null($path)) { if (is_null($path)) {
$oFS->startDirectDownload($oFS->filterFilename($this->getExportFileName($format)), $content); $oFS->startDirectDownload($oFS->filterFilename($this->getExportFileName($format)), $content);
} else { } else {
$filePath = $oFS->trailingslashit($path) . $oFS->filterFilename($this->getExportFileName($format)); $filePath = $oFS->trailingslashit($path) . $oFS->filterFilename($this->getExportFileName($format));
if (false === $oFS->createFile($filePath, $content)) { if (false === $oFS->createFile($filePath, $content, true)) {
throw oxNew(ExportFileException::class, $filePath); throw oxNew(ExportFileException::class, $filePath);
} }
return $filePath; return $filePath;
@ -250,7 +242,19 @@ abstract class ExportBase implements QueryBase
return ''; return '';
} }
protected function getFileSystem(): d3filesystem /**
* @return DatabaseInterface|null
* @throws DatabaseConnectionException
*/
protected function d3GetDb(): ?DatabaseInterface
{
return DatabaseProvider::getDb(DatabaseProvider::FETCH_MODE_ASSOC);
}
/**
* @return d3filesystem|mixed
*/
protected function getFileSystem()
{ {
return oxNew(d3filesystem::class); return oxNew(d3filesystem::class);
} }
@ -259,16 +263,16 @@ abstract class ExportBase implements QueryBase
* @param string $format * @param string $format
* *
* @return string * @return string
* @throws ContainerExceptionInterface * @throws DatabaseConnectionException
* @throws DBALException * @throws DatabaseErrorException
* @throws Exception * @throws Exceptions\NoSuitableRendererException
* @throws NoSuitableRendererException
* @throws NotFoundExceptionInterface
*/ */
public function getContent(string $format): string public function getContent(string $format): string
{ {
[ $rows, $fieldNames ] = $this->getExportData($this->getQuery()); [ $rows, $fieldNames ] = $this->getExportData($this->getQuery());
return $this->renderContent($rows, $fieldNames, $format); $content = $this->renderContent($rows, $fieldNames, $format);
return $content;
} }
} }

View File

@ -16,7 +16,7 @@ declare(strict_types=1);
namespace D3\DataWizard\Application\Model\ExportRenderer; namespace D3\DataWizard\Application\Model\ExportRenderer;
use D3\DataWizard\Application\Model\Exceptions\RenderException; use D3\DataWizard\Application\Model\Exceptions\RenderException;
use League\Csv\ColumnConsistency; use League\Csv\EncloseField;
use League\Csv\Exception; use League\Csv\Exception;
use League\Csv\Writer; use League\Csv\Writer;
use OxidEsales\Eshop\Core\Config; use OxidEsales\Eshop\Core\Config;
@ -24,22 +24,18 @@ use OxidEsales\Eshop\Core\Registry;
class Csv implements RendererInterface class Csv implements RendererInterface
{ {
public function __construct(protected bool $forceEnclose = false)
{}
/** /**
* @param iterable $rows * @param $rows
* @param iterable $fieldNames * @param $fieldNames
* *
* @return string * @return string
* @throws RenderException * @throws RenderException
*/ */
public function getContent(iterable $rows, iterable $fieldNames): string public function getContent($rows, $fieldNames): string
{ {
try { try {
$csv = $this->getCsv(); $csv = $this->getCsv();
$this->forceEnclose ? $csv->forceEnclosure() : $csv->relaxEnclosure(); $csv->insertOne($fieldNames);
$csv->insertOne((array) $fieldNames);
$csv->insertAll($rows); $csv->insertAll($rows);
return (string) $csv; return (string) $csv;
} catch (Exception $e) { } catch (Exception $e) {
@ -62,14 +58,20 @@ class Csv implements RendererInterface
{ {
$csv = Writer::createFromString(); $csv = Writer::createFromString();
$sEncloser = $this->d3GetConfig()->getConfigParam('sGiCsvFieldEncloser') ?? '"'; EncloseField::addTo($csv, "\t\x1f");
$sEncloser = $this->d3GetConfig()->getConfigParam('sGiCsvFieldEncloser');
if (false == $sEncloser) {
$sEncloser = '"';
}
$csv->setEnclosure($sEncloser); $csv->setEnclosure($sEncloser);
$sDelimiter = $this->d3GetConfig()->getConfigParam('sCSVSign') ?? ';'; $sDelimiter = $this->d3GetConfig()->getConfigParam('sCSVSign');
if (false == $sDelimiter) {
$sDelimiter = ';';
}
$csv->setDelimiter($sDelimiter); $csv->setDelimiter($sDelimiter);
$csv->addValidator(new ColumnConsistency(), 'columns_consistency');
return $csv; return $csv;
} }

View File

@ -21,17 +21,18 @@ use JsonException;
class Json implements RendererInterface class Json implements RendererInterface
{ {
/** /**
* @param iterable $rows * @param $rows
* @param iterable $fieldNames * @param $fieldNames
* *
* @return string * @return string
* @throws RenderException * @throws RenderException
*/ */
public function getContent( iterable $rows, iterable $fieldNames): string public function getContent($rows, $fieldNames): string
{ {
try { try {
$flags = JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES; $flags = JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR;
return json_encode($rows, $flags); $json = json_encode($rows, $flags);
return $json;
} catch (JsonException $e) { } catch (JsonException $e) {
/** @var RenderException $newException */ /** @var RenderException $newException */
$newException = oxNew(RenderException::class, $e->getMessage(), $e->getCode(), $e); $newException = oxNew(RenderException::class, $e->getMessage(), $e->getCode(), $e);

View File

@ -20,12 +20,12 @@ use MathieuViossat\Util\ArrayToTextTable;
class Pretty implements RendererInterface class Pretty implements RendererInterface
{ {
/** /**
* @param iterable $rows * @param $rows
* @param iterable $fieldNames * @param $fieldNames
* *
* @return string * @return string
*/ */
public function getContent(iterable $rows, iterable $fieldNames): string public function getContent($rows, $fieldNames): string
{ {
$renderer = $this->getArrayToTextTableInstance($rows); $renderer = $this->getArrayToTextTableInstance($rows);
return $renderer->getTable(); return $renderer->getTable();

View File

@ -45,7 +45,7 @@ class RendererBridge
/** /**
* @param RendererInterface $instance * @param RendererInterface $instance
*/ */
protected function translateRendererId(RendererInterface &$instance): void protected function translateRendererId(RendererInterface &$instance)
{ {
$instance = $instance->getTitleTranslationId(); $instance = $instance->getTitleTranslationId();
} }
@ -60,8 +60,8 @@ class RendererBridge
{ {
$format = strtolower($format); $format = strtolower($format);
$rendererList = array_change_key_case($this->getRendererList()); $rendererList = array_change_key_case($this->getRendererList(), CASE_LOWER);
$rendererListTypes = array_keys(array_change_key_case($rendererList)); $rendererListTypes = array_keys(array_change_key_case($rendererList, CASE_LOWER));
if (in_array($format, $rendererListTypes, true)) { if (in_array($format, $rendererListTypes, true)) {
return $rendererList[$format]; return $rendererList[$format];

View File

@ -18,12 +18,12 @@ namespace D3\DataWizard\Application\Model\ExportRenderer;
interface RendererInterface interface RendererInterface
{ {
/** /**
* @param iterable $rows * @param $rows
* @param iterable $fieldNames * @param $fieldNames
* *
* @return string * @return string
*/ */
public function getContent(iterable $rows, iterable $fieldNames): string; public function getContent($rows, $fieldNames): string;
/** /**
* @return string * @return string

View File

@ -14,7 +14,12 @@
// @codeCoverageIgnoreStart // @codeCoverageIgnoreStart
declare(strict_types=1); declare(strict_types=1);
return [ $sLangName = "Deutsch";
// -------------------------------
// RESOURCE IDENTITFIER = STRING
// -------------------------------
$aLang = [
//Navigation //Navigation
'charset' => 'UTF-8', 'charset' => 'UTF-8',
'd3mxDataWizard' => '<i class="fas fa-fw fa-hat-wizard"></i> Data Wizard', 'd3mxDataWizard' => '<i class="fas fa-fw fa-hat-wizard"></i> Data Wizard',

View File

@ -14,7 +14,11 @@
// @codeCoverageIgnoreStart // @codeCoverageIgnoreStart
declare(strict_types=1); declare(strict_types=1);
return [ $sLangName = "English";
// -------------------------------
// RESOURCE IDENTITFIER = STRING
// -------------------------------
$aLang = [
//Navigation //Navigation
'charset' => 'UTF-8', 'charset' => 'UTF-8',

View File

@ -1,4 +1,4 @@
[{capture assign="d3dw_backgroundimage"}]linear-gradient(22.5deg, rgba(66, 66, 66, 0.02) 0%, rgba(66, 66, 66, 0.02) 11%,rgba(135, 135, 135, 0.02) 11%, rgba(135, 135, 135, 0.02) 24%,rgba(29, 29, 29, 0.02) 24%, rgba(29, 29, 29, 0.02) 38%,rgba(15, 15, 15, 0.02) 38%, rgba(15, 15, 15, 0.02) 50%,rgba(180, 180, 180, 0.02) 50%, rgba(180, 180, 180, 0.02) 77%,rgba(205, 205, 205, 0.02) 77%, rgba(205, 205, 205, 0.02) 100%),linear-gradient(67.5deg, rgba(10, 10, 10, 0.02) 0%, rgba(10, 10, 10, 0.02) 22%,rgba(52, 52, 52, 0.02) 22%, rgba(52, 52, 52, 0.02) 29%,rgba(203, 203, 203, 0.02) 29%, rgba(203, 203, 203, 0.02) 30%,rgba(69, 69, 69, 0.02) 30%, rgba(69, 69, 69, 0.02) 75%,rgba(231, 231, 231, 0.02) 75%, rgba(231, 231, 231, 0.02) 95%,rgba(138, 138, 138, 0.02) 95%, rgba(138, 138, 138, 0.02) 100%),linear-gradient(112.5deg, rgba(221, 221, 221, 0.02) 0%, rgba(221, 221, 221, 0.02) 17%,rgba(190, 190, 190, 0.02) 17%, rgba(190, 190, 190, 0.02) 39%,rgba(186, 186, 186, 0.02) 39%, rgba(186, 186, 186, 0.02) 66%,rgba(191, 191, 191, 0.02) 66%, rgba(191, 191, 191, 0.02) 68%,rgba(16, 16, 16, 0.02) 68%, rgba(16, 16, 16, 0.02) 70%,rgba(94, 94, 94, 0.02) 70%, rgba(94, 94, 94, 0.02) 100%),linear-gradient(90deg, #ffffff,#ffffff)[{/capture}] [{capture assign="d3dw_backgroundimage"}]linear-gradient(22.5deg, rgba(66, 66, 66, 0.02) 0%, rgba(66, 66, 66, 0.02) 11%,rgba(135, 135, 135, 0.02) 11%, rgba(135, 135, 135, 0.02) 24%,rgba(29, 29, 29, 0.02) 24%, rgba(29, 29, 29, 0.02) 38%,rgba(15, 15, 15, 0.02) 38%, rgba(15, 15, 15, 0.02) 50%,rgba(180, 180, 180, 0.02) 50%, rgba(180, 180, 180, 0.02) 77%,rgba(205, 205, 205, 0.02) 77%, rgba(205, 205, 205, 0.02) 100%),linear-gradient(67.5deg, rgba(10, 10, 10, 0.02) 0%, rgba(10, 10, 10, 0.02) 22%,rgba(52, 52, 52, 0.02) 22%, rgba(52, 52, 52, 0.02) 29%,rgba(203, 203, 203, 0.02) 29%, rgba(203, 203, 203, 0.02) 30%,rgba(69, 69, 69, 0.02) 30%, rgba(69, 69, 69, 0.02) 75%,rgba(231, 231, 231, 0.02) 75%, rgba(231, 231, 231, 0.02) 95%,rgba(138, 138, 138, 0.02) 95%, rgba(138, 138, 138, 0.02) 100%),linear-gradient(112.5deg, rgba(221, 221, 221, 0.02) 0%, rgba(221, 221, 221, 0.02) 17%,rgba(190, 190, 190, 0.02) 17%, rgba(190, 190, 190, 0.02) 39%,rgba(186, 186, 186, 0.02) 39%, rgba(186, 186, 186, 0.02) 66%,rgba(191, 191, 191, 0.02) 66%, rgba(191, 191, 191, 0.02) 68%,rgba(16, 16, 16, 0.02) 68%, rgba(16, 16, 16, 0.02) 70%,rgba(94, 94, 94, 0.02) 70%, rgba(94, 94, 94, 0.02) 100%),linear-gradient(90deg, #ffffff,#ffffff)[{/capture}]
[{capture assign="d3dw_noitemmessageid"}]D3_DATAWIZARD_ERR_NOACTION_INSTALLED[{/capture}] [{capture assign="d3dw_noitemmessageid"}]D3_DATAWIZARD_ERR_NOACTION_INSTALLED[{/capture}]
[{include file="@d3datawizard/admin/inc/d3Wizards.tpl" submit="@d3datawizard/admin/inc/d3ActionSubmit.tpl"}] [{include file="d3Wizards.tpl" submit="d3ActionSubmit.tpl"}]

View File

@ -1,4 +1,4 @@
[{capture assign="d3dw_backgroundimage"}]linear-gradient(339deg, rgba(47, 47, 47,0.02) 0%, rgba(47, 47, 47,0.02) 42%,transparent 42%, transparent 99%,rgba(17, 17, 17,0.02) 99%, rgba(17, 17, 17,0.02) 100%),linear-gradient(257deg, rgba(65, 65, 65,0.02) 0%, rgba(65, 65, 65,0.02) 11%,transparent 11%, transparent 92%,rgba(53, 53, 53,0.02) 92%, rgba(53, 53, 53,0.02) 100%),linear-gradient(191deg, rgba(5, 5, 5,0.02) 0%, rgba(5, 5, 5,0.02) 1%,transparent 1%, transparent 45%,rgba(19, 19, 19,0.02) 45%, rgba(19, 19, 19,0.02) 100%),linear-gradient(29deg, rgba(28, 28, 28,0.02) 0%, rgba(28, 28, 28,0.02) 33%,transparent 33%, transparent 40%,rgba(220, 220, 220,0.02) 40%, rgba(220, 220, 220,0.02) 100%),linear-gradient(90deg, rgb(255,255,255),rgb(255,255,255))[{/capture}] [{capture assign="d3dw_backgroundimage"}]linear-gradient(339deg, rgba(47, 47, 47,0.02) 0%, rgba(47, 47, 47,0.02) 42%,transparent 42%, transparent 99%,rgba(17, 17, 17,0.02) 99%, rgba(17, 17, 17,0.02) 100%),linear-gradient(257deg, rgba(65, 65, 65,0.02) 0%, rgba(65, 65, 65,0.02) 11%,transparent 11%, transparent 92%,rgba(53, 53, 53,0.02) 92%, rgba(53, 53, 53,0.02) 100%),linear-gradient(191deg, rgba(5, 5, 5,0.02) 0%, rgba(5, 5, 5,0.02) 1%,transparent 1%, transparent 45%,rgba(19, 19, 19,0.02) 45%, rgba(19, 19, 19,0.02) 100%),linear-gradient(29deg, rgba(28, 28, 28,0.02) 0%, rgba(28, 28, 28,0.02) 33%,transparent 33%, transparent 40%,rgba(220, 220, 220,0.02) 40%, rgba(220, 220, 220,0.02) 100%),linear-gradient(90deg, rgb(255,255,255),rgb(255,255,255))[{/capture}]
[{capture assign="d3dw_noitemmessageid"}]D3_DATAWIZARD_ERR_NOEXPORT_INSTALLED[{/capture}] [{capture assign="d3dw_noitemmessageid"}]D3_DATAWIZARD_ERR_NOEXPORT_INSTALLED[{/capture}]
[{include file="@d3datawizard/admin/inc/d3Wizards.tpl" submit="@d3datawizard/admin/inc/d3ExportSubmit.tpl"}] [{include file="d3Wizards.tpl" submit="d3ExportSubmit.tpl"}]

View File

@ -143,4 +143,4 @@
</div> </div>
</div> </div>
[{include file="@d3modcfg_lib/admin/inc/inc.tpl"}] [{include file="d3_cfg_mod_inc.tpl"}]

View File

@ -1,25 +0,0 @@
<?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
*/
// @codeCoverageIgnoreStart
declare(strict_types=1);
$sLangName = 'Deutsch';
// -------------------------------
// RESOURCE IDENTITFIER = STRING
// -------------------------------
$aLang = include __DIR__."/../../de/d3DataWizard_translations.php";
// @codeCoverageIgnoreEnd

View File

@ -1,25 +0,0 @@
<?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
*/
// @codeCoverageIgnoreStart
declare(strict_types=1);
$sLangName = 'English';
// -------------------------------
// RESOURCE IDENTITFIER = STRING
// -------------------------------
$aLang = include __DIR__."/../../en/d3DataWizard_translations.php";
// @codeCoverageIgnoreEnd

View File

@ -1,25 +0,0 @@
<?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
*/
// @codeCoverageIgnoreStart
declare(strict_types=1);
$sLangName = 'Deutsch';
// -------------------------------
// RESOURCE IDENTITFIER = STRING
// -------------------------------
$aLang = include __DIR__."/../../de/d3DataWizard_translations.php";
// @codeCoverageIgnoreEnd

View File

@ -1,25 +0,0 @@
<?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
*/
// @codeCoverageIgnoreStart
declare(strict_types=1);
$sLangName = 'English';
// -------------------------------
// RESOURCE IDENTITFIER = STRING
// -------------------------------
$aLang = include __DIR__."/../../en/d3DataWizard_translations.php";
// @codeCoverageIgnoreEnd

View File

@ -4,17 +4,7 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [unreleased](https://git.d3data.de/D3Public/DataWizard/compare/3.0.0.0...rel_3.x) - 2023-09-12 ## [2.1.1.3](https://git.d3data.de/D3Public/DataWizard/compare/2.1.1.2...rel_2.x) - 2023-09-12
## [3.0.0.0](https://git.d3data.de/D3Public/DataWizard/compare/2.1.1.3...3.0.0.0) - 2024-05-13
### Added
- installable in OXID 7.0 + 7.1
- Twig support
### Removed
- support for OXID < 7
## [2.1.1.3](https://git.d3data.de/D3Public/DataWizard/compare/2.1.1.2...2.1.1.3) - 2023-09-12
### Added ### Added
- apply roles and rights - apply roles and rights

View File

@ -72,7 +72,7 @@ If you have a suggestion that would make this better, please fork the repo and c
- Push to the Branch (git push origin feature/AmazingFeature) - Push to the Branch (git push origin feature/AmazingFeature)
- Open a Pull Request - Open a Pull Request
## License ## Licence
(status: 2021-05-06) (status: 2021-05-06)
Distributed under the GPLv3 license. Distributed under the GPLv3 license.

View File

@ -25,17 +25,21 @@
"GPL-3.0-or-later" "GPL-3.0-or-later"
], ],
"require": { "require": {
"php": "^8.0", "php": ">=7.3",
"oxid-esales/oxideshop-ce": "7.0 - 7.1", "oxid-esales/oxideshop-ce": "6.8 - 6.14",
"league/csv": "^9.0", "league/csv": "^9.0",
"mathieuviossat/arraytotexttable": "^1.0", "mathieuviossat/arraytotexttable": "^1.0",
"form-manager/form-manager": "^6.1", "form-manager/form-manager": "^6.1",
"d3/modcfg": "^7.0", "d3/modcfg": "^6.0"
"beberlei/assert": "^3.3.2"
}, },
"require-dev": { "extra": {
"d3/testingtools": "^1.2.0.0", "oxideshop": {
"phpunit/phpunit": "^9.1.1" "blacklist-filter": [
"*.md",
"composer.json"
],
"target-directory": "d3/datawizard"
}
}, },
"suggest": { "suggest": {
"d3/datawizardtasks": "useful example tasks for Data Wizard", "d3/datawizardtasks": "useful example tasks for Data Wizard",
@ -44,11 +48,7 @@
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"D3\\DataWizard\\": "./" "D3\\DataWizard\\": "../../../source/modules/d3/datawizard"
} }
},
"scripts": {
"phpunit": "XDEBUG_MODE=coverage ./vendor/bin/phpunit --config=vendor/d3/datawizard/ --no-coverage",
"phpunit-coverage": "XDEBUG_MODE=coverage ./vendor/bin/phpunit --config=vendor/d3/datawizard/ --coverage-html=vendor/d3/datawizard/tests/result/coverage"
} }
} }

View File

@ -1,2 +0,0 @@
modules:
- d3modcfg_lib

View File

@ -13,11 +13,12 @@
declare(strict_types=1); declare(strict_types=1);
use D3\DataWizard\Application\Model\Constants; /**
* Metadata version
*/
$sMetadataVersion = '2.1'; $sMetadataVersion = '2.1';
$sModuleId = Constants::OXID_MODULE_ID; $sModuleId = 'd3datawizard';
$logo = '<img src="https://logos.oxidmodule.com/d3logo.svg" alt="(D3)" style="height:1em;width:1em">'; $logo = '<img src="https://logos.oxidmodule.com/d3logo.svg" alt="(D3)" style="height:1em;width:1em">';
/** /**
@ -31,7 +32,7 @@ $aModule = [
'en' => '', 'en' => '',
], ],
'thumbnail' => 'picture.svg', 'thumbnail' => 'picture.svg',
'version' => '3.0.0.0', 'version' => '2.1.1.3',
'author' => 'D&sup3; Data Development (Inh.: Thomas Dartsch)', 'author' => 'D&sup3; Data Development (Inh.: Thomas Dartsch)',
'email' => 'support@shopmodule.com', 'email' => 'support@shopmodule.com',
'url' => 'https://www.oxidmodule.com/', 'url' => 'https://www.oxidmodule.com/',
@ -42,11 +43,11 @@ $aModule = [
'extend' => [], 'extend' => [],
'events' => [], 'events' => [],
'templates' => [ 'templates' => [
'@' . Constants::OXID_MODULE_ID . '/admin/d3ExportWizard.tpl' => 'views/smarty/admin/d3ExportWizard.tpl', 'd3ExportWizard.tpl' => 'd3/datawizard/Application/views/admin/tpl/d3ExportWizard.tpl',
'@' . Constants::OXID_MODULE_ID . '/admin/d3ActionWizard.tpl' => 'views/smarty/admin/d3ActionWizard.tpl', 'd3ActionWizard.tpl' => 'd3/datawizard/Application/views/admin/tpl/d3ActionWizard.tpl',
'@' . Constants::OXID_MODULE_ID . '/admin/inc/d3Wizards.tpl' => 'views/smarty/admin/inc/Wizards.tpl', 'd3Wizards.tpl' => 'd3/datawizard/Application/views/admin/tpl/inc/Wizards.tpl',
'@' . Constants::OXID_MODULE_ID . '/admin/inc/d3ExportSubmit.tpl' => 'views/smarty/admin/inc/exportSubmit.tpl', 'd3ExportSubmit.tpl' => 'd3/datawizard/Application/views/admin/tpl/inc/exportSubmit.tpl',
'@' . Constants::OXID_MODULE_ID . '/admin/inc/d3ActionSubmit.tpl' => 'views/smarty/admin/inc/actionSubmit.tpl', 'd3ActionSubmit.tpl' => 'd3/datawizard/Application/views/admin/tpl/inc/actionSubmit.tpl',
], ],
'settings' => [ 'settings' => [
[ [

View File

@ -1,36 +0,0 @@
<?xml version="1.0"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
backupGlobals="true"
bootstrap="../../../source/bootstrap.php"
colors="false"
backupStaticAttributes="false"
convertErrorsToExceptions="true"
convertNoticesToExceptions="false"
convertWarningsToExceptions="true"
forceCoversAnnotation="false"
processIsolation="false"
stopOnError="false"
stopOnFailure="false"
stopOnIncomplete="false"
stopOnSkipped="false"
beStrictAboutTestsThatDoNotTestAnything="false"
verbose="false"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
<testsuites>
<testsuite name="Unit">
<directory>tests/unit</directory>
</testsuite>
</testsuites>
<coverage includeUncoveredFiles="true" processUncoveredFiles="true">
<include>
<directory suffix=".php">Application</directory>
</include>
<exclude>
<file>../.php-cs-fixer.php</file>
<file>../IntelliSenseHelper.php</file>
</exclude>
</coverage>
<php>
<const name="OXID_PHP_UNIT" value="true"/>
</php>
</phpunit>

View File

@ -2,14 +2,51 @@
## Requirements ## Requirements
Please install the packages listed in the composer.json in "require-dev". Unfortunately Composer does not provide an automatic installation. Both unit and acceptance tests require OXID Testing Library installed.
missing ext-sockets See https://github.com/OXID-eSales/testing_library.
### Configuration ### Configuration
Make sure the module has been activated with a valid license key. Please install the packages listed in the composer.json in "require-dev". Unfortunately Composer does not provide an automatic installation.
Configure the error reporting to `error_reporting(E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED);` in the `config.inc.php` due some deprecation issues in original OXID code
Here is an example of Testing Library configuration file `oxideshop/test_config.yml`
```
# This file is auto-generated during the composer install
mandatory_parameters:
shop_path: /var/www/oxideshop/source
shop_tests_path: /var/www/oxideshop/tests
partial_module_paths: d3/datawizard
optional_parameters:
shop_url: null
shop_serial: ''
enable_varnish: false
is_subshop: false
install_shop: false
remote_server_dir: null
shop_setup_path: null
restore_shop_after_tests_suite: false
test_database_name: null
restore_after_acceptance_tests: false
restore_after_unit_tests: false
tmp_path: /tmp/oxid_test_library/
database_restoration_class: DatabaseRestorer
activate_all_modules: false
run_tests_for_shop: false
run_tests_for_modules: true
screen_shots_path: null
screen_shots_url: null
browser_name: firefox
selenium_server_ip: 127.0.0.1
selenium_server_port: '4444'
additional_test_paths: null
```
## Unit Tests ## Unit Tests
commands are described in composer.json scripts section To execute unit tests run the following:
```
cd /var/www/oxideshop/
vendor/bin/runtests
```

View File

@ -36,6 +36,6 @@ class additional extends additional_abstract
} }
try { try {
d3GetOxidDIC()->get(additional::class); d3GetModCfgDIC()->get(additional::class);
} catch (Exception) { } catch (Exception $e) {
} }

27
tests/phpunit.xml Normal file
View File

@ -0,0 +1,27 @@
<phpunit backupGlobals="true"
backupStaticAttributes="false"
beStrictAboutTestsThatDoNotTestAnything="false"
cacheTokens="true"
colors="false"
convertErrorsToExceptions="true"
convertNoticesToExceptions="false"
convertWarningsToExceptions="true"
forceCoversAnnotation="false"
processIsolation="false"
stopOnError="false"
stopOnFailure="false"
stopOnIncomplete="false"
stopOnSkipped="false"
verbose="false">
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">../Application</directory>
<directory suffix=".php">../Modules</directory>
<directory suffix=".php">../public</directory>
<directory suffix=".php">../Setup</directory>
</whitelist>
</filter>
<logging>
<log type="junit" target="reports/logfile.xml"/>
</logging>
</phpunit>

View File

@ -17,19 +17,16 @@ namespace D3\DataWizard\tests\unit\Application\Controller\Admin;
use D3\DataWizard\Application\Controller\Admin\d3ActionWizard; use D3\DataWizard\Application\Controller\Admin\d3ActionWizard;
use D3\DataWizard\Application\Model\Configuration; use D3\DataWizard\Application\Model\Configuration;
use D3\DataWizard\Application\Model\Constants;
use D3\DataWizard\Application\Model\Exceptions\DataWizardException;
use D3\DataWizard\Application\Model\Exceptions\DebugException; use D3\DataWizard\Application\Model\Exceptions\DebugException;
use D3\DataWizard\Application\Model\ExportRenderer\RendererBridge; use D3\DataWizard\Application\Model\ExportRenderer\RendererBridge;
use D3\DataWizard\tests\tools\d3TestAction; use D3\DataWizard\tests\tools\d3TestAction;
use Doctrine\DBAL\Exception as DBALException; use OxidEsales\Eshop\Core\Config;
use OxidEsales\Eshop\Core\Registry; use OxidEsales\Eshop\Core\Registry;
use OxidEsales\Eshop\Core\Request; use OxidEsales\Eshop\Core\Request;
use OxidEsales\EshopCommunity\Internal\Framework\Module\Facade\ModuleSettingService;
use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\MockObject\MockObject;
use ReflectionException; use ReflectionException;
class d3ActionWizardTest extends d3AdminController class d3ActionWizardTest extends d3AdminControllerTest
{ {
/** @var d3ActionWizard */ /** @var d3ActionWizard */
protected $_oController; protected $_oController;
@ -121,21 +118,26 @@ class d3ActionWizardTest extends d3AdminController
$requestMock->expects($this->any())->method('getRequestEscapedParameter')->willReturnCallback([$this, 'executePassRequestCallback']); $requestMock->expects($this->any())->method('getRequestEscapedParameter')->willReturnCallback([$this, 'executePassRequestCallback']);
Registry::set(Request::class, $requestMock); Registry::set(Request::class, $requestMock);
/** @var ModuleSettingService $settingsServiceMock */ /** @var Config|MockObject $configMock */
$settingsServiceMock = $this->getMockBuilder(ModuleSettingService::class) $configMock = $this->getMockBuilder(Config::class)
->disableOriginalConstructor() ->onlyMethods(['getConfigParam'])
->onlyMethods(['getBoolean'])
->getMock(); ->getMock();
$settingsServiceMock->expects($this->once())->method('getBoolean')->with( $configMock->expects($this->atLeastOnce())->method('getConfigParam')->willReturnCallback(
$this->identicalTo('d3datawizard_debug'), function ($argName) use ($blDebug) {
$this->identicalTo(Constants::OXID_MODULE_ID) switch ($argName) {
)->willReturn($blDebug); case 'd3datawizard_debug':
return $blDebug;
default:
return Registry::getConfig()->getConfigParam($argName);
}
}
);
/** @var d3ActionWizard|MockObject $controllerMock */ /** @var d3ActionWizard|MockObject $controllerMock */
$controllerMock = $this->getMockBuilder(d3ActionWizard::class) $controllerMock = $this->getMockBuilder(d3ActionWizard::class)
->onlyMethods(['getSettingsService']) ->onlyMethods(['d3GetConfig'])
->getMock(); ->getMock();
$controllerMock->method('getSettingsService')->willReturn($settingsServiceMock); $controllerMock->method('d3GetConfig')->willReturn($configMock);
$this->_oController = $controllerMock; $this->_oController = $controllerMock;
/** @var d3TestAction|MockObject $actionMock */ /** @var d3TestAction|MockObject $actionMock */
@ -146,7 +148,7 @@ class d3ActionWizardTest extends d3AdminController
]) ])
->getMock(); ->getMock();
$actionMock->expects($this->atLeastOnce())->method('getQuery')->willReturn(['SELECT 1', ['1']]); $actionMock->expects($this->atLeastOnce())->method('getQuery')->willReturn(['SELECT 1', ['1']]);
$actionMock->expects($this->exactly((int) !$blDebug))->method('run'); $actionMock->expects($this->exactly((int) !$blDebug))->method('run')->willReturn(true);
/** @var Configuration|MockObject $configurationMock */ /** @var Configuration|MockObject $configurationMock */
$configurationMock = $this->getMockBuilder(Configuration::class) $configurationMock = $this->getMockBuilder(Configuration::class)
@ -168,11 +170,14 @@ class d3ActionWizardTest extends d3AdminController
public function executePassRequestCallback($varName) public function executePassRequestCallback($varName)
{ {
return match ( $varName ) { switch ($varName) {
'taskid' => 'testTaskId', case 'taskid':
'format' => RendererBridge::FORMAT_CSV, return 'testTaskId';
default => oxNew( Request::class )->getRequestEscapedParameter( $varName ), case 'format':
}; return RendererBridge::FORMAT_CSV;
default:
return oxNew(Request::class)->getRequestEscapedParameter($varName);
}
} }
/** /**
@ -185,15 +190,4 @@ class d3ActionWizardTest extends d3AdminController
'debug' => [true], 'debug' => [true],
]; ];
} }
/**
* @return string[][]
*/
public function runTaskFailedDataProvider(): array
{
return [
[DataWizardException::class],
[DBALException::class],
];
}
} }

View File

@ -22,19 +22,17 @@ use D3\DataWizard\Application\Model\Exceptions\DataWizardException;
use D3\DataWizard\Application\Model\Exceptions\DebugException; use D3\DataWizard\Application\Model\Exceptions\DebugException;
use D3\DataWizard\tests\tools\d3TestAction; use D3\DataWizard\tests\tools\d3TestAction;
use D3\ModCfg\Tests\unit\d3ModCfgUnitTestCase; use D3\ModCfg\Tests\unit\d3ModCfgUnitTestCase;
use Doctrine\DBAL\Exception as DBALException; use Doctrine\DBAL\DBALException;
use Exception;
use OxidEsales\Eshop\Core\Config; use OxidEsales\Eshop\Core\Config;
use OxidEsales\Eshop\Core\Exception\DatabaseErrorException; use OxidEsales\Eshop\Core\Exception\DatabaseErrorException;
use OxidEsales\Eshop\Core\Registry; use OxidEsales\Eshop\Core\Registry;
use OxidEsales\Eshop\Core\Request; use OxidEsales\Eshop\Core\Request;
use OxidEsales\Eshop\Core\UtilsView; use OxidEsales\Eshop\Core\UtilsView;
use OxidEsales\EshopCommunity\Internal\Framework\Module\Facade\ModuleSettingService;
use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\MockObject\MockObject;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use ReflectionException; use ReflectionException;
abstract class d3AdminController extends d3ModCfgUnitTestCase abstract class d3AdminControllerTest extends d3ModCfgUnitTestCase
{ {
/** @var d3ActionWizard|d3ExportWizard */ /** @var d3ActionWizard|d3ExportWizard */
protected $_oController; protected $_oController;
@ -56,7 +54,7 @@ abstract class d3AdminController extends d3ModCfgUnitTestCase
*/ */
public function testConstructor() public function testConstructor()
{ {
$this->setValue($this->_oController, 'configuration', oxNew(Configuration::class)); $this->setValue($this->_oController, 'configuration', null);
$this->callMethod( $this->callMethod(
$this->_oController, $this->_oController,
@ -72,21 +70,6 @@ abstract class d3AdminController extends d3ModCfgUnitTestCase
); );
} }
/**
* @test
* @return void
* @throws ReflectionException
* @covers \D3\DataWizard\Application\Controller\Admin\d3ActionWizard::getViewId
* @covers \D3\DataWizard\Application\Controller\Admin\d3ExportWizard::getViewId
*/
public function canGetViewId(): void
{
$viewId = $this->callMethod($this->_oController, 'getViewId');
$this->assertIsString($viewId);
$this->assertStringStartsWith('d3mxDataWizard', $viewId);
}
/** /**
* @covers \D3\DataWizard\Application\Controller\Admin\d3ActionWizard::runTask() * @covers \D3\DataWizard\Application\Controller\Admin\d3ActionWizard::runTask()
* @covers \D3\DataWizard\Application\Controller\Admin\d3ExportWizard::runTask() * @covers \D3\DataWizard\Application\Controller\Admin\d3ExportWizard::runTask()
@ -99,7 +82,7 @@ abstract class d3AdminController extends d3ModCfgUnitTestCase
$controllerMock = $this->getMockBuilder($this->testClassName) $controllerMock = $this->getMockBuilder($this->testClassName)
->onlyMethods(['execute']) ->onlyMethods(['execute'])
->getMock(); ->getMock();
$controllerMock->expects($this->once())->method('execute'); $controllerMock->expects($this->once())->method('execute')->willReturn(true);
$this->_oController = $controllerMock; $this->_oController = $controllerMock;
@ -121,8 +104,9 @@ abstract class d3AdminController extends d3ModCfgUnitTestCase
{ {
/** @var DataWizardException|DBALException|DatabaseErrorException|MockObject $exceptionMock */ /** @var DataWizardException|DBALException|DatabaseErrorException|MockObject $exceptionMock */
$exceptionMock = $this->getMockBuilder($exceptionClass) $exceptionMock = $this->getMockBuilder($exceptionClass)
->setConstructorArgs(['exc_msg', 20, new Exception()]) ->disableOriginalConstructor()
->getMock(); ->getMock();
$this->setValue($exceptionMock, 'message', 'exc_msg');
/** @var d3ActionWizard|d3ExportWizard|MockObject $controllerMock */ /** @var d3ActionWizard|d3ExportWizard|MockObject $controllerMock */
$controllerMock = $this->getMockBuilder($this->testClassName) $controllerMock = $this->getMockBuilder($this->testClassName)
@ -153,6 +137,18 @@ abstract class d3AdminController extends d3ModCfgUnitTestCase
); );
} }
/**
* @return \string[][]
*/
public function runTaskFailedDataProvider(): array
{
return [
[DataWizardException::class],
[DBALException::class],
[DatabaseErrorException::class],
];
}
/** /**
* @covers \D3\DataWizard\Application\Controller\Admin\d3ActionWizard::execute() * @covers \D3\DataWizard\Application\Controller\Admin\d3ActionWizard::execute()
* @covers \D3\DataWizard\Application\Controller\Admin\d3ExportWizard::execute() * @covers \D3\DataWizard\Application\Controller\Admin\d3ExportWizard::execute()
@ -248,19 +244,18 @@ abstract class d3AdminController extends d3ModCfgUnitTestCase
} }
/** /**
* @covers \D3\DataWizard\Application\Controller\Admin\d3ExportWizard::d3GetConfig
* @covers \D3\DataWizard\Application\Controller\Admin\d3ActionWizard::d3GetConfig
* @test * @test
* @return void
* @throws ReflectionException * @throws ReflectionException
* @covers \D3\DataWizard\Application\Controller\Admin\d3ActionWizard::getSettingsService()
* @covers \D3\DataWizard\Application\Controller\Admin\d3ExportWizard::getSettingsService()
*/ */
public function canGetSettingsService(): void public function canGetConfig()
{ {
$this->assertInstanceOf( $this->assertInstanceOf(
ModuleSettingService::class, Config::class,
$this->callMethod( $this->callMethod(
$this->_oController, $this->_oController,
'getSettingsService' 'd3GetConfig'
) )
); );
} }

View File

@ -17,21 +17,17 @@ namespace D3\DataWizard\tests\unit\Application\Controller\Admin;
use D3\DataWizard\Application\Controller\Admin\d3ExportWizard; use D3\DataWizard\Application\Controller\Admin\d3ExportWizard;
use D3\DataWizard\Application\Model\Configuration; use D3\DataWizard\Application\Model\Configuration;
use D3\DataWizard\Application\Model\Constants;
use D3\DataWizard\Application\Model\Exceptions\DataWizardException;
use D3\DataWizard\Application\Model\Exceptions\DebugException; use D3\DataWizard\Application\Model\Exceptions\DebugException;
use D3\DataWizard\Application\Model\ExportRenderer\RendererBridge; use D3\DataWizard\Application\Model\ExportRenderer\RendererBridge;
use D3\DataWizard\tests\tools\d3TestAction; use D3\DataWizard\tests\tools\d3TestAction;
use D3\DataWizard\tests\tools\d3TestExport; use D3\DataWizard\tests\tools\d3TestExport;
use Doctrine\DBAL\Exception as DBALException; use OxidEsales\Eshop\Core\Config;
use OxidEsales\Eshop\Core\Exception\DatabaseErrorException;
use OxidEsales\Eshop\Core\Registry; use OxidEsales\Eshop\Core\Registry;
use OxidEsales\Eshop\Core\Request; use OxidEsales\Eshop\Core\Request;
use OxidEsales\EshopCommunity\Internal\Framework\Module\Facade\ModuleSettingService;
use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\MockObject\MockObject;
use ReflectionException; use ReflectionException;
class d3ExportWizardTest extends d3AdminController class d3ExportWizardTest extends d3AdminControllerTest
{ {
/** @var d3ExportWizard */ /** @var d3ExportWizard */
protected $_oController; protected $_oController;
@ -124,21 +120,26 @@ class d3ExportWizardTest extends d3AdminController
//OnConsecutiveCalls('testTaskId', 'CSV'); //OnConsecutiveCalls('testTaskId', 'CSV');
Registry::set(Request::class, $requestMock); Registry::set(Request::class, $requestMock);
/** @var ModuleSettingService $settingsServiceMock */ /** @var Config|MockObject $configMock */
$settingsServiceMock = $this->getMockBuilder(ModuleSettingService::class) $configMock = $this->getMockBuilder(Config::class)
->disableOriginalConstructor() ->onlyMethods(['getConfigParam'])
->onlyMethods(['getBoolean'])
->getMock(); ->getMock();
$settingsServiceMock->expects($this->once())->method('getBoolean')->with( $configMock->expects($this->atLeastOnce())->method('getConfigParam')->willReturnCallback(
$this->identicalTo('d3datawizard_debug'), function ($argName) use ($blDebug) {
$this->identicalTo(Constants::OXID_MODULE_ID) switch ($argName) {
)->willReturn($blDebug); case 'd3datawizard_debug':
return $blDebug;
default:
return Registry::getConfig()->getConfigParam($argName);
}
}
);
/** @var d3ExportWizard|MockObject $controllerMock */ /** @var d3ExportWizard|MockObject $controllerMock */
$controllerMock = $this->getMockBuilder(d3ExportWizard::class) $controllerMock = $this->getMockBuilder(d3ExportWizard::class)
->onlyMethods(['getSettingsService']) ->onlyMethods(['d3GetConfig'])
->getMock(); ->getMock();
$controllerMock->method('getSettingsService')->willReturn($settingsServiceMock); $controllerMock->method('d3GetConfig')->willReturn($configMock);
$this->_oController = $controllerMock; $this->_oController = $controllerMock;
/** @var d3TestAction|MockObject $exportMock */ /** @var d3TestAction|MockObject $exportMock */
@ -191,16 +192,4 @@ class d3ExportWizardTest extends d3AdminController
'debug' => [true], 'debug' => [true],
]; ];
} }
/**
* @return string[][]
*/
public function runTaskFailedDataProvider(): array
{
return [
[DataWizardException::class],
[DBALException::class],
[DatabaseErrorException::class],
];
}
} }

View File

@ -18,7 +18,6 @@ namespace D3\DataWizard\tests\unit\Application\Model;
use D3\DataWizard\Application\Model\Exceptions\TaskException; use D3\DataWizard\Application\Model\Exceptions\TaskException;
use D3\DataWizard\tests\tools\d3TestAction; use D3\DataWizard\tests\tools\d3TestAction;
use D3\ModCfg\Tests\unit\d3ModCfgUnitTestCase; use D3\ModCfg\Tests\unit\d3ModCfgUnitTestCase;
use Doctrine\DBAL\Connection;
use FormManager\Inputs\Hidden; use FormManager\Inputs\Hidden;
use FormManager\Inputs\Number; use FormManager\Inputs\Number;
use FormManager\Inputs\Radio; use FormManager\Inputs\Radio;
@ -180,7 +179,7 @@ class ActionBaseTest extends d3ModCfgUnitTestCase
]) ])
->getMock(); ->getMock();
$modelMock->expects($this->atLeastOnce())->method('hasFormElements')->willReturn(false); $modelMock->expects($this->atLeastOnce())->method('hasFormElements')->willReturn(false);
$modelMock->expects($this->atLeastOnce())->method('executeAction'); $modelMock->expects($this->atLeastOnce())->method('executeAction')->willReturn(1);
$modelMock->expects($this->atLeastOnce())->method('getQuery')->willReturn([]); $modelMock->expects($this->atLeastOnce())->method('getQuery')->willReturn([]);
$this->_oModel = $modelMock; $this->_oModel = $modelMock;
@ -209,7 +208,7 @@ class ActionBaseTest extends d3ModCfgUnitTestCase
]) ])
->getMock(); ->getMock();
$modelMock->expects($this->atLeastOnce())->method('hasFormElements')->willReturn(true); $modelMock->expects($this->atLeastOnce())->method('hasFormElements')->willReturn(true);
$modelMock->expects($this->exactly((int) !$blThrowException))->method('executeAction'); $modelMock->expects($this->exactly((int) !$blThrowException))->method('executeAction')->willReturn(1);
$modelMock->expects($this->exactly((int) !$blThrowException))->method('getQuery')->willReturn([]); $modelMock->expects($this->exactly((int) !$blThrowException))->method('getQuery')->willReturn([]);
$modelMock->expects($this->atLeastOnce())->method('getFormElements')->willReturn($elements); $modelMock->expects($this->atLeastOnce())->method('getFormElements')->willReturn($elements);
$this->_oModel = $modelMock; $this->_oModel = $modelMock;
@ -259,18 +258,17 @@ class ActionBaseTest extends d3ModCfgUnitTestCase
*/ */
public function canExecuteAction($query, $throwsException) public function canExecuteAction($query, $throwsException)
{ {
/** @var Database|MockObject $connectionMock */ /** @var Database|MockObject $dbMock */
$connectionMock = $this->getMockBuilder(Connection::class) $dbMock = $this->getMockBuilder(Database::class)
->disableOriginalConstructor() ->onlyMethods(['execute'])
->onlyMethods(['executeStatement'])
->getMock(); ->getMock();
$connectionMock->expects($this->exactly((int) !$throwsException))->method('executeStatement')->willReturn(1); $dbMock->expects($this->exactly((int) !$throwsException))->method('execute')->willReturn(true);
/** @var d3TestAction|MockObject $modelMock */ /** @var d3TestAction|MockObject $modelMock */
$modelMock = $this->getMockBuilder(d3TestAction::class) $modelMock = $this->getMockBuilder(d3TestAction::class)
->onlyMethods(['getConnection']) ->onlyMethods(['d3GetDb'])
->getMock(); ->getMock();
$modelMock->expects($this->exactly((int) !$throwsException))->method('getConnection')->willReturn($connectionMock); $modelMock->expects($this->exactly((int) !$throwsException))->method('d3GetDb')->willReturn($dbMock);
$this->_oModel = $modelMock; $this->_oModel = $modelMock;
@ -282,9 +280,9 @@ class ActionBaseTest extends d3ModCfgUnitTestCase
); );
} catch (TaskException $e) { } catch (TaskException $e) {
if ($throwsException) { if ($throwsException) {
$this->assertStringContainsString('keine SELECTs exportieren', $e->getMessage()); $this->assertStringContainsString('ACTIONSELECT', $e->getMessage());
} else { } else {
$this->assertStringContainsString('1 Eintrag verändert', $e->getMessage()); $this->assertStringContainsString('ACTIONRESULT', $e->getMessage());
} }
} }
} }
@ -301,17 +299,17 @@ class ActionBaseTest extends d3ModCfgUnitTestCase
} }
/** /**
* @covers \D3\DataWizard\Application\Model\ActionBase::getConnection * @covers \D3\DataWizard\Application\Model\ActionBase::d3GetDb
* @test * @test
* @throws ReflectionException * @throws ReflectionException
*/ */
public function canGetConnection() public function canGetDb()
{ {
$this->assertInstanceOf( $this->assertInstanceOf(
Connection::class, Database::class,
$this->callMethod( $this->callMethod(
$this->_oModel, $this->_oModel,
'getConnection' 'd3GetDb'
) )
); );
} }

View File

@ -267,7 +267,7 @@ class ConfigurationTest extends d3ModCfgUnitTestCase
*/ */
public function canGetActionsByGroup() public function canGetActionsByGroup()
{ {
$actionList = ['abc' => ['123'], 'def' => ['456']]; $actionList = ['abc' => '123', 'def' => '456'];
$this->setValue( $this->setValue(
$this->_oModel, $this->_oModel,
@ -276,7 +276,7 @@ class ConfigurationTest extends d3ModCfgUnitTestCase
); );
$this->assertSame( $this->assertSame(
['456'], '456',
$this->callMethod( $this->callMethod(
$this->_oModel, $this->_oModel,
'getActionsByGroup', 'getActionsByGroup',
@ -292,7 +292,7 @@ class ConfigurationTest extends d3ModCfgUnitTestCase
*/ */
public function canGetExportsByGroup() public function canGetExportsByGroup()
{ {
$exportList = ['abc' => ['123'], 'def' => ['456']]; $exportList = ['abc' => '123', 'def' => '456'];
$this->setValue( $this->setValue(
$this->_oModel, $this->_oModel,
@ -301,7 +301,7 @@ class ConfigurationTest extends d3ModCfgUnitTestCase
); );
$this->assertSame( $this->assertSame(
['456'], '456',
$this->callMethod( $this->callMethod(
$this->_oModel, $this->_oModel,
'getExportsByGroup', 'getExportsByGroup',

View File

@ -18,7 +18,6 @@ namespace D3\DataWizard\tests\unit\Application\Model\Exceptions;
use D3\DataWizard\Application\Model\Exceptions\DebugException; use D3\DataWizard\Application\Model\Exceptions\DebugException;
use D3\ModCfg\Tests\unit\d3ModCfgUnitTestCase; use D3\ModCfg\Tests\unit\d3ModCfgUnitTestCase;
use Exception; use Exception;
use OxidEsales\Eshop\Core\Registry;
use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\MockObject\MockObject;
use ReflectionException; use ReflectionException;
@ -52,7 +51,7 @@ class DebugExceptionTest extends d3ModCfgUnitTestCase
); );
$this->assertStringContainsString( $this->assertStringContainsString(
'Debug: testMessage', 'DEBUG',
$this->callMethod( $this->callMethod(
$this->_oModel, $this->_oModel,
'getMessage' 'getMessage'

View File

@ -18,7 +18,6 @@ namespace D3\DataWizard\tests\unit\Application\Model\Exceptions;
use D3\DataWizard\Application\Model\Exceptions\ExportFileException; use D3\DataWizard\Application\Model\Exceptions\ExportFileException;
use D3\ModCfg\Tests\unit\d3ModCfgUnitTestCase; use D3\ModCfg\Tests\unit\d3ModCfgUnitTestCase;
use Exception; use Exception;
use OxidEsales\Eshop\Core\Registry;
use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\MockObject\MockObject;
use ReflectionException; use ReflectionException;
@ -52,7 +51,7 @@ class ExportFileExceptionTest extends d3ModCfgUnitTestCase
); );
$this->assertStringContainsString( $this->assertStringContainsString(
'kann nicht angelegt werden', 'EXPORTFILEERROR',
$this->callMethod( $this->callMethod(
$this->_oModel, $this->_oModel,
'getMessage' 'getMessage'

View File

@ -69,7 +69,7 @@ class InputUnvalidExceptionTest extends d3ModCfgUnitTestCase
[$taskMock, $invalidField, $code, $exception] [$taskMock, $invalidField, $code, $exception]
); );
$this->assertMatchesRegularExpression( $this->assertRegExp(
'/^testTitle\s-\s*->\s.*\sless\s/m', '/^testTitle\s-\s*->\s.*\sless\s/m',
$this->callMethod( $this->callMethod(
$this->_oModel, $this->_oModel,

View File

@ -18,7 +18,6 @@ namespace D3\DataWizard\tests\unit\Application\Model\Exceptions;
use D3\DataWizard\Application\Model\Exceptions\NoSuitableRendererException; use D3\DataWizard\Application\Model\Exceptions\NoSuitableRendererException;
use D3\ModCfg\Tests\unit\d3ModCfgUnitTestCase; use D3\ModCfg\Tests\unit\d3ModCfgUnitTestCase;
use Exception; use Exception;
use OxidEsales\Eshop\Core\Registry;
use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\MockObject\MockObject;
use ReflectionException; use ReflectionException;
@ -52,7 +51,7 @@ class NoSuitableRendererExceptionTest extends d3ModCfgUnitTestCase
); );
$this->assertStringContainsString( $this->assertStringContainsString(
'kein Renderer f', 'NOSUITABLERENDERER',
$this->callMethod( $this->callMethod(
$this->_oModel, $this->_oModel,
'getMessage' 'getMessage'

View File

@ -23,14 +23,11 @@ use D3\DataWizard\Application\Model\ExportRenderer\RendererInterface;
use D3\DataWizard\tests\tools\d3TestExport; use D3\DataWizard\tests\tools\d3TestExport;
use D3\ModCfg\Application\Model\d3filesystem; use D3\ModCfg\Application\Model\d3filesystem;
use D3\ModCfg\Tests\unit\d3ModCfgUnitTestCase; use D3\ModCfg\Tests\unit\d3ModCfgUnitTestCase;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Driver\Result;
use FormManager\Inputs\Hidden; use FormManager\Inputs\Hidden;
use FormManager\Inputs\Number; use FormManager\Inputs\Number;
use FormManager\Inputs\Radio; use FormManager\Inputs\Radio;
use OxidEsales\Eshop\Core\Database\Adapter\Doctrine\Database; use OxidEsales\Eshop\Core\Database\Adapter\Doctrine\Database;
use OxidEsales\Eshop\Core\Exception\StandardException; use OxidEsales\Eshop\Core\Exception\StandardException;
use OxidEsales\Eshop\Core\Registry;
use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\MockObject\MockObject;
use ReflectionException; use ReflectionException;
@ -323,17 +320,17 @@ class ExportBaseTest extends d3ModCfgUnitTestCase
} }
/** /**
* @covers \D3\DataWizard\Application\Model\ExportBase::getConnection * @covers \D3\DataWizard\Application\Model\ExportBase::d3GetDb
* @test * @test
* @throws ReflectionException * @throws ReflectionException
*/ */
public function canGetConnection() public function canGetDb()
{ {
$this->assertInstanceOf( $this->assertInstanceOf(
Connection::class, Database::class,
$this->callMethod( $this->callMethod(
$this->_oModel, $this->_oModel,
'getConnection' 'd3GetDb'
) )
); );
} }
@ -527,7 +524,7 @@ class ExportBaseTest extends d3ModCfgUnitTestCase
$this->_oModel = $modelMock; $this->_oModel = $modelMock;
$this->assertMatchesRegularExpression( $this->assertRegExp(
'/^base_(\d{4})-(\d{2})-(\d{2})_(\d{2})-(\d{2})-(\d{2})\.extension$/m', '/^base_(\d{4})-(\d{2})-(\d{2})_(\d{2})-(\d{2})-(\d{2})\.extension$/m',
$this->callMethod( $this->callMethod(
$this->_oModel, $this->_oModel,
@ -545,26 +542,19 @@ class ExportBaseTest extends d3ModCfgUnitTestCase
*/ */
public function canGetExportData($query, $throwsException, $dbResult) public function canGetExportData($query, $throwsException, $dbResult)
{ {
/** @var Result|MockObject $resultMock */ /** @var Database|MockObject $dbMock */
$resultMock = $this->getMockBuilder(Result::class) $dbMock = $this->getMockBuilder(Database::class)
->onlyMethods(get_class_methods(Result::class)) ->onlyMethods(['getAll'])
->getMock(); ->getMock();
$resultMock->method('fetchAllAssociative')->willReturn($dbResult); $dbMock->expects($this->exactly((int) !$throwsException))->method('getAll')->willReturn($dbResult);
/** @var Database|MockObject $connectionMock */
$connectionMock = $this->getMockBuilder(Connection::class)
->disableOriginalConstructor()
->onlyMethods(['executeQuery'])
->getMock();
$connectionMock->expects($this->exactly((int) !$throwsException))->method('executeQuery')->willReturn($resultMock);
/** @var d3TestExport|MockObject $modelMock */ /** @var d3TestExport|MockObject $modelMock */
$modelMock = $this->getMockBuilder(d3TestExport::class) $modelMock = $this->getMockBuilder(d3TestExport::class)
->onlyMethods([ ->onlyMethods([
'getConnection', 'd3GetDb',
]) ])
->getMock(); ->getMock();
$modelMock->expects($this->exactly((int) !$throwsException))->method('getConnection')->willReturn($connectionMock); $modelMock->expects($this->exactly((int) !$throwsException))->method('d3GetDb')->willReturn($dbMock);
$this->_oModel = $modelMock; $this->_oModel = $modelMock;
@ -572,7 +562,7 @@ class ExportBaseTest extends d3ModCfgUnitTestCase
$result = $this->callMethod( $result = $this->callMethod(
$this->_oModel, $this->_oModel,
'getExportData', 'getExportData',
[[$query, ['param1', 'param2']]] [[$query], ['param1', 'param2']]
); );
$this->assertSame( $this->assertSame(
@ -592,7 +582,7 @@ class ExportBaseTest extends d3ModCfgUnitTestCase
); );
} catch (TaskException $e) { } catch (TaskException $e) {
if ($throwsException) { if ($throwsException) {
$this->assertStringContainsString('Export kann nicht ausgefĂĽhrt werden', $e->getMessage()); $this->assertStringContainsString('NOEXPORTSELECT', $e->getMessage());
} elseif (!count($dbResult)) { } elseif (!count($dbResult)) {
$this->assertStringContainsString('kein Inhalt', $e->getMessage()); $this->assertStringContainsString('kein Inhalt', $e->getMessage());
} }

View File

@ -17,7 +17,6 @@ namespace D3\DataWizard\tests\unit\Application\Model\ExportRenderer;
use D3\DataWizard\Application\Model\Exceptions\RenderException; use D3\DataWizard\Application\Model\Exceptions\RenderException;
use D3\DataWizard\Application\Model\ExportRenderer\Csv; use D3\DataWizard\Application\Model\ExportRenderer\Csv;
use Generator;
use League\Csv\Exception; use League\Csv\Exception;
use League\Csv\Writer; use League\Csv\Writer;
use OxidEsales\Eshop\Core\Config; use OxidEsales\Eshop\Core\Config;
@ -37,34 +36,6 @@ class CsvTest extends ExportRendererTest
$this->_oModel = oxNew(Csv::class); $this->_oModel = oxNew(Csv::class);
} }
/**
* @test
*
* @param bool $force
*
* @return void
* @throws ReflectionException
* @covers \D3\DataWizard\Application\Model\ExportRenderer\Csv::__construct
* @dataProvider canForceEncloseDataProvider
*/
public function canForceEnclose(bool $force): void
{
$noForce = oxNew(Csv::class, $force);
$this->assertSame(
$force,
$this->getValue(
$noForce,
'forceEnclose'
)
);
}
public function canForceEncloseDataProvider(): Generator
{
yield 'noForce' => [true];
yield 'force' => [false];
}
/** /**
* @covers \D3\DataWizard\Application\Model\ExportRenderer\Csv::getContent * @covers \D3\DataWizard\Application\Model\ExportRenderer\Csv::getContent
* @test * @test
@ -151,10 +122,13 @@ class CsvTest extends ExportRendererTest
->getMock(); ->getMock();
$configMock->expects($this->atLeastOnce())->method('getConfigParam')->willReturnCallback( $configMock->expects($this->atLeastOnce())->method('getConfigParam')->willReturnCallback(
function ($argName) { function ($argName) {
return match ( $argName ) { switch ($argName) {
'sGiCsvFieldEncloser', 'sCSVSign' => null, case 'sGiCsvFieldEncloser':
default => Registry::getConfig()->getConfigParam( $argName ), case 'sCSVSign':
}; return false;
default:
return Registry::getConfig()->getConfigParam($argName);
}
} }
); );

View File

@ -38,7 +38,7 @@ abstract class ExportRendererTest extends d3ModCfgUnitTestCase
*/ */
public function canGetFileExtension() public function canGetFileExtension()
{ {
$this->assertMatchesRegularExpression( $this->assertRegExp(
"/^[a-z0-9._-]*$/i", "/^[a-z0-9._-]*$/i",
$this->callMethod( $this->callMethod(
$this->_oModel, $this->_oModel,

View File

@ -55,12 +55,12 @@ class JsonTest extends ExportRendererTest
} }
/** /**
* @return string[][] * @return \string[][]
*/ */
public function canGetContentDataProvider(): array public function canGetContentDataProvider(): array
{ {
return [ return [
'valid' => [['value1', "value2"], false], 'valid' => [['value1', 'value2'], false],
'invalid' => [["text" => "\xB1\x31"], true], // malformed UTF8 chars 'invalid' => [["text" => "\xB1\x31"], true], // malformed UTF8 chars
]; ];
} }

View File

@ -1,4 +0,0 @@
{% set d3dw_backgroundimage %}linear-gradient(22.5deg, rgba(66, 66, 66, 0.02) 0%, rgba(66, 66, 66, 0.02) 11%,rgba(135, 135, 135, 0.02) 11%, rgba(135, 135, 135, 0.02) 24%,rgba(29, 29, 29, 0.02) 24%, rgba(29, 29, 29, 0.02) 38%,rgba(15, 15, 15, 0.02) 38%, rgba(15, 15, 15, 0.02) 50%,rgba(180, 180, 180, 0.02) 50%, rgba(180, 180, 180, 0.02) 77%,rgba(205, 205, 205, 0.02) 77%, rgba(205, 205, 205, 0.02) 100%),linear-gradient(67.5deg, rgba(10, 10, 10, 0.02) 0%, rgba(10, 10, 10, 0.02) 22%,rgba(52, 52, 52, 0.02) 22%, rgba(52, 52, 52, 0.02) 29%,rgba(203, 203, 203, 0.02) 29%, rgba(203, 203, 203, 0.02) 30%,rgba(69, 69, 69, 0.02) 30%, rgba(69, 69, 69, 0.02) 75%,rgba(231, 231, 231, 0.02) 75%, rgba(231, 231, 231, 0.02) 95%,rgba(138, 138, 138, 0.02) 95%, rgba(138, 138, 138, 0.02) 100%),linear-gradient(112.5deg, rgba(221, 221, 221, 0.02) 0%, rgba(221, 221, 221, 0.02) 17%,rgba(190, 190, 190, 0.02) 17%, rgba(190, 190, 190, 0.02) 39%,rgba(186, 186, 186, 0.02) 39%, rgba(186, 186, 186, 0.02) 66%,rgba(191, 191, 191, 0.02) 66%, rgba(191, 191, 191, 0.02) 68%,rgba(16, 16, 16, 0.02) 68%, rgba(16, 16, 16, 0.02) 70%,rgba(94, 94, 94, 0.02) 70%, rgba(94, 94, 94, 0.02) 100%),linear-gradient(90deg, #ffffff,#ffffff){% endset %}
{% set d3dw_noitemmessageid %}D3_DATAWIZARD_ERR_NOACTION_INSTALLED{% endset %}
{% include "@d3datawizard/admin/inc/Wizards.html.twig" with {submit: "@d3datawizard/admin/inc/actionSubmit.html.twig"} %}

View File

@ -1,4 +0,0 @@
{% set d3dw_backgroundimage %}linear-gradient(339deg, rgba(47, 47, 47,0.02) 0%, rgba(47, 47, 47,0.02) 42%,transparent 42%, transparent 99%,rgba(17, 17, 17,0.02) 99%, rgba(17, 17, 17,0.02) 100%),linear-gradient(257deg, rgba(65, 65, 65,0.02) 0%, rgba(65, 65, 65,0.02) 11%,transparent 11%, transparent 92%,rgba(53, 53, 53,0.02) 92%, rgba(53, 53, 53,0.02) 100%),linear-gradient(191deg, rgba(5, 5, 5,0.02) 0%, rgba(5, 5, 5,0.02) 1%,transparent 1%, transparent 45%,rgba(19, 19, 19,0.02) 45%, rgba(19, 19, 19,0.02) 100%),linear-gradient(29deg, rgba(28, 28, 28,0.02) 0%, rgba(28, 28, 28,0.02) 33%,transparent 33%, transparent 40%,rgba(220, 220, 220,0.02) 40%, rgba(220, 220, 220,0.02) 100%),linear-gradient(90deg, rgb(255,255,255),rgb(255,255,255)){% endset %}
{% set d3dw_noitemmessageid %}D3_DATAWIZARD_ERR_NOEXPORT_INSTALLED{% endset %}
{% include "@d3datawizard/admin/inc/Wizards.html.twig" with {submit: "@d3datawizard/admin/inc/exportSubmit.html.twig"} %}

View File

@ -1,137 +0,0 @@
{% include "headitem.html.twig" with {title: "GENERAL_ADMIN_TITLE"|translate} %}
{{ style({ include: "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" }) }}
{{ script({ include: "https://code.jquery.com/jquery-3.2.1.slim.min.js", dynamic: __oxid_include_dynamic }) }}
{{ script({ include: "https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js", dynamic: __oxid_include_dynamic }) }}
{{ script({ include: "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js", dynamic: __oxid_include_dynamic }) }}
{{ style({ include: "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/solid.min.css" }) }}
<style>
button {
margin: 1em 1em 1em 5em;
}
html {
font-size: 0.8em;
}
/* Image courtesy of gradientmagic.com */
body {
background-image: {{ d3dw_backgroundimage }};
}
h4 .btn {
font-size: 1.3rem;
}
h5.card-header {
font-size: 1.1rem;
}
.formElements label {
display: inline-block;
margin: .5rem 0;
}
</style>
{% capture assign = "d3script" %}{% apply spaceless %}
function startTask(id, format = '') {
let elements = document.getElementsByClassName('errorbox');
for (var i = 0; i < elements.length; i++){
elements[i].style.display = 'none';
}
setTimeout(function(){
document.getElementById('mask').className='';
document.getElementById('popup2').className='d3loader-2';
}, 3000);
document.getElementById('mask').className='on';
document.getElementById('popup2').className='d3loader-2 on';
document.getElementById('taskid').value = id;
document.getElementById('format').value = format;
document.getElementById('myedit').submit();
}
{% endapply %}{% endcapture %}
{{ script({ add: d3script, dynamic: __oxid_include_dynamic }) }}
<form name="myedit" id="myedit" action="{{ oViewConf.getSelfLink() }}" method="post" style="padding: 0;margin: 0;height:0;">
{{ oViewConf.getHiddenSid()|raw }}
<input type="hidden" name="cl" value="{{ oViewConf.getActiveClassName() }}">
<input type="hidden" name="fnc" value="runTask">
<input type="hidden" name="taskid" id="taskid" value="">
<input type="hidden" name="format" id="format" value="CSV">
{% set groups = oView.getGroups() %}
{% if groups|length %}
<div id="accordion">
{% for group in oView.getGroups() %}
<div class="card mb-2">
<div class="card-header p-1" id="heading{{ group }}">
<h4 class="mb-0">
<span class="btn p-1" data-toggle="collapse" data-target="#collapse{{ group }}" aria-expanded="false" aria-controls="collapse{{ group }}">
{{ translate({ ident: group }) }}
</span>
</h4>
</div>
<div id="collapse{{ group }}" class="collapse" aria-labelledby="heading{{ group }}" data-parent="#accordion">
<div class="card-body pb-0">
<div class="row">
{% for id, item in oView.getGroupTasks(group) %}
<div class="col-sm-6 col-md-4 col-lg-3 pb-4">
<div class="card">
<h5 class="card-header">
{{ item.getTitle() }}
</h5>
<div class="card-body">
{% if item.getDescription() %}
{% set description = item.getDescription() %}
{% set sectionlength = "100" %}
{% if description|length <= sectionlength %}
<p class="card-text">{{ description }}</p>
{% else %}
{% set shorttext = description|truncate(sectionlength, '') %}
<p class="card-text" data-toggle="collapse" data-target="#collapseExample" aria-expanded="false" aria-controls="collapseExample" style="cursor: pointer">
{{ shorttext }}...
</p>
<p class="card-text collapse" id="collapseExample">
...{{ description|replace({shorttext:''}) }}
</p>
{% endif %}
{% endif %}
{% if item.hasFormElements() %}
{% for formElement in item.getFormElements() %}
{{ formElement|raw }}
{% endfor %}
{% endif %}
{% block exportSubmit %}
{% include submit %}
{% endblock %}
</div>
</div>
</div>
{% endfor %}
</div>
<div class="clear"></div>
</div>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="alert alert-primary" role="alert">
{{ translate({ ident: d3dw_noitemmessageid }) }}
</div>
{% endif %}
</form>
<div id="mask" class=""></div>
<div id="popup2" class="d3loader-2">
<div class="d3loader-spinner">
<div class="d3loader-circle-1"></div>
<div class="d3loader-circle-2"></div>
<div class="d3loader-circle-3"></div>
</div>
</div>
{% include "@d3modcfg_lib/admin/inc/inc.html.twig" %}

View File

@ -1,8 +0,0 @@
{% block submitElements %}
<div class="btn-group">
<button type="button" class="btn btn-primary" onclick="if (confirm('{{ translate({ ident: "D3_DATAWIZARD_ACTION_SUBMIT_CONFIRM" }) }}') === true) {startTask('{{ id }}')}">
<i class="fas fa-fw fa-magic"></i>
{{ translate({ ident: item.getButtonText() }) }}
</button>
</div>
{% endblock %}

View File

@ -1,24 +0,0 @@
{% block submitElements %}
<div class="btn-group">
<button type="button" class="btn btn-primary" onclick="startTask('{{ id }}', 'CSV')">
<i class="fas fa-fw fa-magic"></i>
{{ translate({ ident: item.getButtonText() }) }}
</button>
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="sr-only">
<i class="fas fa-fw fa-magic"></i>
{{ translate({ ident: item.getButtonText() }) }}
</span>
</button>
<div class="dropdown-menu">
{% block dataWizardFormat %}
{% set rendererBridge = item.getRendererBridge() %}
{% for key, translationId in rendererBridge.getTranslatedRendererIdList() %}
<button class="dropdown-item" onclick="startTask('{{ id }}', '{{ key }}')">
{{ translate({ ident: translationId }) }}
</button>
{% endfor %}
{% endblock %}
</div>
</div>
{% endblock %}