Comparer les révisions

...

24 Révisions

Auteur SHA1 Message Date
445a58a819 add ViewId tests 2024-05-13 16:24:34 +02:00
957de3ac0f adjust changelog 2024-05-13 16:04:56 +02:00
9f2a97c560 fix assignment in template 2024-05-13 15:45:25 +02:00
76d72c8546 align test fixtures to strict types 2024-05-13 15:45:25 +02:00
76fd879554 adjust tests 2024-05-13 15:45:25 +02:00
be873efb32 set argument types 2024-05-13 15:45:25 +02:00
201b01db4c fix unicode char issues 2024-05-13 15:45:24 +02:00
185caeeac3 refactor CSV format class
- add column consistency check
- can force enclosure optionally
2024-05-13 15:45:24 +02:00
760b7b2509 assert right argument types 2024-05-13 15:45:24 +02:00
f730a380ec use current module setting service 2024-05-13 15:45:24 +02:00
4cfcfb6d44 fix type in Twig template 2024-05-13 15:45:23 +02:00
69b33d3538 fix tests 2024-05-13 15:45:23 +02:00
36ee1a5957 fix tests 2024-05-13 15:45:23 +02:00
3fd5f2dc98 fix test issues 2024-05-13 15:45:23 +02:00
bb7b9c2025 add Twig templates and translations, move Smarty templates to appropriate folder 2024-05-13 15:45:23 +02:00
7ed3a7be0e make installable in OXID 7.1 2024-05-13 15:45:22 +02:00
baeb293048 add module dependency
available from OXID 7.1
2024-05-13 15:45:22 +02:00
908068abfa improve code 2024-05-13 15:45:22 +02:00
4548be2986 retrieve module settings from settings service instead from outdated configuration 2024-05-13 15:45:21 +02:00
42fe5c8ca2 adjust translation file structure 2024-05-13 15:45:21 +02:00
58dcf94255 adjust translation file structure 2024-05-13 15:45:21 +02:00
34f04b8835 refactor Smarty template integration 2024-05-13 15:45:21 +02:00
b77642666b improve code for PHP 8 2024-05-13 15:44:15 +02:00
220f8a1c7c adjust composer file 2024-05-13 15:44:15 +02:00
51 fichiers modifiés avec 741 ajouts et 380 suppressions

Voir le fichier

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

Voir le fichier

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

Voir le fichier

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

Voir le fichier

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

Voir le fichier

@ -0,0 +1,21 @@
<?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';
}

Voir le fichier

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

Voir le fichier

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

Voir le fichier

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

Voir le fichier

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

Voir le fichier

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

Voir le fichier

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

Voir le fichier

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

Voir le fichier

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

Voir le fichier

@ -0,0 +1,25 @@
<?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

Voir le fichier

@ -0,0 +1,25 @@
<?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

Voir le fichier

@ -0,0 +1,25 @@
<?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

Voir le fichier

@ -0,0 +1,25 @@
<?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

Voir le fichier

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

Voir le fichier

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

Voir le fichier

@ -4,7 +4,17 @@ 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/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [2.1.1.3](https://git.d3data.de/D3Public/DataWizard/compare/2.1.1.2...rel_2.x) - 2023-09-12
## [unreleased](https://git.d3data.de/D3Public/DataWizard/compare/3.0.0.0...rel_3.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
- apply roles and rights

Voir le fichier

@ -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)
- Open a Pull Request
## Licence
## License
(status: 2021-05-06)
Distributed under the GPLv3 license.

Voir le fichier

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

2
dependencies.yaml Fichier normal
Voir le fichier

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

Voir le fichier

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

36
phpunit.xml Fichier normal
Voir le fichier

@ -0,0 +1,36 @@
<?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>

Voir le fichier

@ -2,51 +2,14 @@
## Requirements
Both unit and acceptance tests require OXID Testing Library installed.
See https://github.com/OXID-eSales/testing_library.
Please install the packages listed in the composer.json in "require-dev". Unfortunately Composer does not provide an automatic installation.
missing ext-sockets
### Configuration
Please install the packages listed in the composer.json in "require-dev". Unfortunately Composer does not provide an automatic installation.
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
```
Make sure the module has been activated with a valid license key.
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
## Unit Tests
To execute unit tests run the following:
```
cd /var/www/oxideshop/
vendor/bin/runtests
```
commands are described in composer.json scripts section

Voir le fichier

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

Voir le fichier

@ -1,27 +0,0 @@
<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>

Voir le fichier

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

Voir le fichier

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

Voir le fichier

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

Voir le fichier

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

Voir le fichier

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

Voir le fichier

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

Voir le fichier

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

Voir le fichier

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

Voir le fichier

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

Voir le fichier

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

Voir le fichier

@ -17,6 +17,7 @@ namespace D3\DataWizard\tests\unit\Application\Model\ExportRenderer;
use D3\DataWizard\Application\Model\Exceptions\RenderException;
use D3\DataWizard\Application\Model\ExportRenderer\Csv;
use Generator;
use League\Csv\Exception;
use League\Csv\Writer;
use OxidEsales\Eshop\Core\Config;
@ -36,6 +37,34 @@ class CsvTest extends ExportRendererTest
$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
* @test
@ -122,13 +151,10 @@ class CsvTest extends ExportRendererTest
->getMock();
$configMock->expects($this->atLeastOnce())->method('getConfigParam')->willReturnCallback(
function ($argName) {
switch ($argName) {
case 'sGiCsvFieldEncloser':
case 'sCSVSign':
return false;
default:
return Registry::getConfig()->getConfigParam($argName);
}
return match ( $argName ) {
'sGiCsvFieldEncloser', 'sCSVSign' => null,
default => Registry::getConfig()->getConfigParam( $argName ),
};
}
);

Voir le fichier

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

Voir le fichier

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

Voir le fichier

@ -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_noitemmessageid"}]D3_DATAWIZARD_ERR_NOACTION_INSTALLED[{/capture}]
[{include file="d3Wizards.tpl" submit="d3ActionSubmit.tpl"}]
[{include file="@d3datawizard/admin/inc/d3Wizards.tpl" submit="@d3datawizard/admin/inc/d3ActionSubmit.tpl"}]

Voir le fichier

@ -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_noitemmessageid"}]D3_DATAWIZARD_ERR_NOEXPORT_INSTALLED[{/capture}]
[{include file="d3Wizards.tpl" submit="d3ExportSubmit.tpl"}]
[{include file="@d3datawizard/admin/inc/d3Wizards.tpl" submit="@d3datawizard/admin/inc/d3ExportSubmit.tpl"}]

Voir le fichier

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

Voir le fichier

@ -0,0 +1,4 @@
{% 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"} %}

Voir le fichier

@ -0,0 +1,4 @@
{% 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"} %}

Voir le fichier

@ -0,0 +1,137 @@
{% 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" %}

Voir le fichier

@ -0,0 +1,8 @@
{% 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 %}

Voir le fichier

@ -0,0 +1,24 @@
{% 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 %}