Compare commits
95 Commits
Author | SHA1 | Date |
---|---|---|
Daniel Seifert | 445a58a819 | |
Daniel Seifert | 957de3ac0f | |
Daniel Seifert | 9f2a97c560 | |
Daniel Seifert | 76d72c8546 | |
Daniel Seifert | 76fd879554 | |
Daniel Seifert | be873efb32 | |
Daniel Seifert | 201b01db4c | |
Daniel Seifert | 185caeeac3 | |
Daniel Seifert | 760b7b2509 | |
Daniel Seifert | f730a380ec | |
Daniel Seifert | 4cfcfb6d44 | |
Daniel Seifert | 69b33d3538 | |
Daniel Seifert | 36ee1a5957 | |
Daniel Seifert | 3fd5f2dc98 | |
Daniel Seifert | bb7b9c2025 | |
Daniel Seifert | 7ed3a7be0e | |
Daniel Seifert | baeb293048 | |
Daniel Seifert | 908068abfa | |
Daniel Seifert | 4548be2986 | |
Daniel Seifert | 42fe5c8ca2 | |
Daniel Seifert | 58dcf94255 | |
Daniel Seifert | 34f04b8835 | |
Daniel Seifert | b77642666b | |
Daniel Seifert | 220f8a1c7c | |
Daniel Seifert | 4b726bb678 | |
Markus Gärtner | c414eb3683 | |
Markus Gärtner | 5ddd1a3923 | |
Daniel Seifert | aac67d8550 | |
Daniel Seifert | 3debde96c9 | |
Daniel Seifert | 03f31f3e8b | |
Daniel Seifert | 3d83650f7c | |
Daniel Seifert | cf6dd76aa9 | |
Daniel Seifert | 0213f2e6b3 | |
Daniel Seifert | 1fd00635f9 | |
Daniel Seifert | 640152b6a6 | |
Daniel Seifert | 7d8ed628eb | |
Daniel Seifert | 8356ff3a62 | |
Daniel Seifert | 7c479d02c8 | |
Daniel Seifert | b1e3bd98f0 | |
Daniel Seifert | 72478c06e7 | |
Daniel Seifert | bd4dfaf36c | |
Daniel Seifert | 7e1e65cb37 | |
Daniel Seifert | 0c0d564554 | |
Daniel Seifert | 51642b57c7 | |
Daniel Seifert | d0464d4a20 | |
Daniel Seifert | 6aa028fb8c | |
Daniel Seifert | 143173be2f | |
Daniel Seifert | f3b80607b0 | |
Daniel Seifert | e05278da19 | |
Daniel Seifert | 69bf942608 | |
Daniel Seifert | bcd91cf709 | |
Daniel Seifert | e604b84849 | |
Daniel Seifert | 67c462ccda | |
Daniel Seifert | 2549003c71 | |
Daniel Seifert | f86e3a9daf | |
Daniel Seifert | 91b18a9196 | |
Daniel Seifert | 675b18aaa8 | |
Daniel Seifert | a0788ba666 | |
Daniel Seifert | 3aa64f8f63 | |
Daniel Seifert | b1946c4aae | |
Daniel Seifert | 61827e7825 | |
Daniel Seifert | 5fda1baecb | |
Daniel Seifert | e0bd9f02b6 | |
Daniel Seifert | f5d35021f5 | |
Daniel Seifert | 5251490b74 | |
Daniel Seifert | e134a4c14a | |
Daniel Seifert | b5d6936074 | |
Daniel Seifert | ac7ae90310 | |
Daniel Seifert | 067326e704 | |
Daniel Seifert | ae09cf88a5 | |
Daniel Seifert | 3b47f4da05 | |
Daniel Seifert | 903d178124 | |
Daniel Seifert | bd90f18a87 | |
Daniel Seifert | 74edceafc8 | |
Daniel Seifert | ea77239510 | |
Daniel Seifert | e1502b274e | |
Daniel Seifert | 500f226399 | |
Daniel Seifert | 1023bd2fa6 | |
Daniel Seifert | dd7b8ed1e6 | |
Daniel Seifert | a1cd84b415 | |
Daniel Seifert | af10e80086 | |
Daniel Seifert | 148f4f8213 | |
Daniel Seifert | f2935209ed | |
Daniel Seifert | a7e6c91042 | |
Daniel Seifert | 9e9a0fdd4c | |
Daniel Seifert | eef594d970 | |
Daniel Seifert | 759e8a377d | |
Daniel Seifert | f42c42cbe4 | |
Daniel Seifert | baf30ef196 | |
Daniel Seifert | 8b354993ca | |
Daniel Seifert | 4c91b0d699 | |
Daniel Seifert | 34b2b0b061 | |
Daniel Seifert | 9e9bab88f0 | |
Daniel Seifert | 466e751a5c | |
Daniel Seifert | 5367dfdb5a |
|
@ -0,0 +1,5 @@
|
|||
* text=auto
|
||||
|
||||
/.gitattributes export-ignore
|
||||
/.gitignore export-ignore
|
||||
/.php-cs-fixer.php export-ignore
|
|
@ -0,0 +1 @@
|
|||
.php-cs-fixer.cache
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
$finder = PhpCsFixer\Finder::create()
|
||||
->in(__DIR__)
|
||||
;
|
||||
|
||||
$config = new PhpCsFixer\Config();
|
||||
return $config->setRules([
|
||||
'@PHP73Migration' => true,
|
||||
'@PSR12' => true
|
||||
])
|
||||
->setFinder($finder)
|
||||
;
|
|
@ -0,0 +1,122 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* https://www.d3data.de
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
|
||||
* @link https://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\Application\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\Exception as DBALException;
|
||||
use OxidEsales\Eshop\Application\Controller\Admin\AdminDetailsController;
|
||||
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 = '@'. Constants::OXID_MODULE_ID .'/admin/d3ActionWizard';
|
||||
|
||||
protected Configuration $configuration;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->configuration = oxNew(Configuration::class);
|
||||
}
|
||||
|
||||
public function getViewId(): string
|
||||
{
|
||||
return 'd3mxDataWizard_Action';
|
||||
}
|
||||
|
||||
public function getGroups(): array
|
||||
{
|
||||
return $this->configuration->getActionGroups();
|
||||
}
|
||||
|
||||
public function getGroupTasks($group): array
|
||||
{
|
||||
return $this->configuration->getActionsByGroup($group);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function runTask(): void
|
||||
{
|
||||
try {
|
||||
$this->execute();
|
||||
} catch (DataWizardException|DBALException $e) {
|
||||
Registry::getLogger()->error($e->getMessage());
|
||||
Registry::getUtilsView()->addErrorToDisplay($e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws DBALException
|
||||
* @throws DebugException
|
||||
* @throws InputUnvalidException
|
||||
* @throws NotFoundExceptionInterface
|
||||
* @throws TaskException
|
||||
*/
|
||||
protected function execute(): void
|
||||
{
|
||||
$id = Registry::getRequest()->getRequestEscapedParameter('taskid');
|
||||
$action = $this->configuration->getActionById($id);
|
||||
|
||||
[ $queryString, $parameters ] = $action->getQuery();
|
||||
|
||||
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 ModuleSettingService
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function getSettingsService(): ModuleSettingServiceInterface
|
||||
{
|
||||
return ContainerFactory::getInstance()->getContainer()->get(ModuleSettingServiceInterface::class);
|
||||
}
|
||||
|
||||
public function getUserMessages(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getHelpURL(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* https://www.d3data.de
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
|
||||
* @link https://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\Application\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\ModCfg\Application\Model\d3database;
|
||||
use D3\ModCfg\Application\Model\Exception\d3_cfg_mod_exception;
|
||||
use D3\ModCfg\Application\Model\Exception\d3ShopCompatibilityAdapterException;
|
||||
use Doctrine\DBAL\Driver\Exception;
|
||||
use Doctrine\DBAL\Exception as DBALException;
|
||||
use OxidEsales\Eshop\Application\Controller\Admin\AdminDetailsController;
|
||||
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 = '@'. Constants::OXID_MODULE_ID .'/admin/d3ExportWizard';
|
||||
|
||||
protected Configuration $configuration;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->configuration = oxNew(Configuration::class);
|
||||
}
|
||||
|
||||
public function getViewId(): string
|
||||
{
|
||||
return 'd3mxDataWizard_Export';
|
||||
}
|
||||
|
||||
public function getGroups(): array
|
||||
{
|
||||
return $this->configuration->getExportGroups();
|
||||
}
|
||||
|
||||
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(): void
|
||||
{
|
||||
try {
|
||||
$this->execute();
|
||||
} catch (DataWizardException|DBALException|DatabaseErrorException $e) {
|
||||
Registry::getLogger()->error($e->getMessage());
|
||||
Registry::getUtilsView()->addErrorToDisplay($e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws DBALException
|
||||
* @throws DatabaseConnectionException
|
||||
* @throws DatabaseErrorException
|
||||
* @throws NoSuitableRendererException
|
||||
* @throws StandardException
|
||||
* @throws Exception
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
* @throws d3ShopCompatibilityAdapterException
|
||||
* @throws d3_cfg_mod_exception
|
||||
*/
|
||||
protected function execute(): void
|
||||
{
|
||||
$id = Registry::getRequest()->getRequestEscapedParameter('taskid');
|
||||
$export = $this->configuration->getExportById($id);
|
||||
|
||||
[ $queryString, $parameters ] = $export->getQuery();
|
||||
|
||||
if ($this->getSettingsService()->getBoolean('d3datawizard_debug', Constants::OXID_MODULE_ID)) {
|
||||
throw oxNew(
|
||||
DebugException::class,
|
||||
d3database::getInstance()->getPreparedStatementQuery($queryString, $parameters)
|
||||
);
|
||||
}
|
||||
|
||||
$export->run(Registry::getRequest()->getRequestEscapedParameter('format'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ModuleSettingService
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function getSettingsService(): ModuleSettingServiceInterface
|
||||
{
|
||||
return ContainerFactory::getInstance()->getContainer()->get(ModuleSettingServiceInterface::class);
|
||||
}
|
||||
|
||||
public function getUserMessages(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getHelpURL(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* https://www.d3data.de
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
|
||||
* @link https://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\Application\Model;
|
||||
|
||||
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\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 array $formElements = [];
|
||||
|
||||
/**
|
||||
* Ensure that the translations are equally available in the frontend and the backend
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws DBALException
|
||||
* @throws InputUnvalidException
|
||||
* @throws NotFoundExceptionInterface
|
||||
* @throws TaskException
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
if ($this->hasFormElements()) {
|
||||
/** @var Input $element */
|
||||
foreach ($this->getFormElements() as $element) {
|
||||
if (false === $element->isValid()) {
|
||||
/** @var InputUnvalidException $exception */
|
||||
$exception = oxNew(InputUnvalidException::class, $this, $element);
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->executeAction($this->getQuery());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $query
|
||||
*
|
||||
* @return void
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
* @throws TaskException
|
||||
* @throws DBALException
|
||||
*/
|
||||
public function executeAction(array $query): void
|
||||
{
|
||||
[ $queryString, $parameters ] = $query;
|
||||
|
||||
$queryString = trim($queryString);
|
||||
|
||||
if (strtolower(substr($queryString, 0, 6)) === 'select') {
|
||||
/** @var TaskException $exception */
|
||||
$exception = oxNew(
|
||||
TaskException::class,
|
||||
$this,
|
||||
Registry::getLang()->translateString('D3_DATAWIZARD_ERR_ACTIONSELECT')
|
||||
);
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
$affected = (int) $this->getConnection()->executeStatement($queryString, $parameters);
|
||||
|
||||
/** @var TaskException $exception */
|
||||
$exception = oxNew(
|
||||
TaskException::class,
|
||||
$this,
|
||||
sprintf(
|
||||
Registry::getLang()->translateString(
|
||||
$affected === 1 ? 'D3_DATAWIZARD_ERR_ACTIONRESULT' : 'D3_DATAWIZARD_ERR_ACTIONRESULTS'
|
||||
),
|
||||
$affected
|
||||
)
|
||||
);
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
protected function getConnection(): Connection
|
||||
{
|
||||
return ContainerFactory::getInstance()->getContainer()->get(ConnectionProviderInterface::class)->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getButtonText(): string
|
||||
{
|
||||
return "D3_DATAWIZARD_ACTION_SUBMIT";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Input $input
|
||||
*/
|
||||
public function registerFormElement(Input $input): void
|
||||
{
|
||||
if ($input instanceof Radio || $input instanceof Checkbox) {
|
||||
$input->setTemplate('<p class="form-check">{{ input }} {{ label }}</p>');
|
||||
$input->setAttribute('class', 'form-check-input');
|
||||
} else {
|
||||
$input->setTemplate('<p class="formElements">{{ label }} {{ input }}</p>');
|
||||
$input->setAttribute('class', 'form-control');
|
||||
}
|
||||
$this->formElements[] = $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasFormElements(): bool
|
||||
{
|
||||
return (bool) count($this->formElements);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getFormElements(): array
|
||||
{
|
||||
return $this->formElements;
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
/**
|
||||
* 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)
|
||||
|
@ -15,22 +15,20 @@ declare(strict_types=1);
|
|||
|
||||
namespace D3\DataWizard\Application\Model;
|
||||
|
||||
use D3\DataWizard\Application\Model\Actions\FixArtextendsItems;
|
||||
use D3\DataWizard\Application\Model\Exports\InactiveCategories;
|
||||
use D3\DataWizard\Application\Model\Exports\KeyFigures;
|
||||
use OxidEsales\Eshop\Core\Registry;
|
||||
use D3\DataWizard\Application\Model\Exceptions\DataWizardException;
|
||||
|
||||
class Configuration
|
||||
{
|
||||
const GROUP_SHOP = 'D3_DATAWIZARD_GROUP_SHOP';
|
||||
const GROUP_CATEGORY = 'D3_DATAWIZARD_GROUP_CATEGORIES';
|
||||
const GROUP_ARTICLES = 'D3_DATAWIZARD_GROUP_ARTICLES';
|
||||
const GROUP_USERS = 'D3_DATAWIZARD_GROUP_USERS';
|
||||
const GROUP_ORDERS = 'D3_DATAWIZARD_GROUP_ORDERS';
|
||||
const GROUP_REMARKS = 'D3_DATAWIZARD_GROUP_REMARKS';
|
||||
public const GROUP_SHOP = 'D3_DATAWIZARD_GROUP_SHOP';
|
||||
public const GROUP_CATEGORY = 'D3_DATAWIZARD_GROUP_CATEGORIES';
|
||||
public const GROUP_ARTICLES = 'D3_DATAWIZARD_GROUP_ARTICLES';
|
||||
public const GROUP_USERS = 'D3_DATAWIZARD_GROUP_USERS';
|
||||
public const GROUP_ORDERS = 'D3_DATAWIZARD_GROUP_ORDERS';
|
||||
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()
|
||||
{
|
||||
|
@ -39,30 +37,25 @@ class Configuration
|
|||
|
||||
public function configure()
|
||||
{
|
||||
if (false === Registry::getConfig()->getConfigParam('d3datawizard_hideexamples', false)) {
|
||||
$this->registerAction(self::GROUP_ARTICLES, oxNew(FixArtextendsItems::class));
|
||||
|
||||
$this->registerExport(self::GROUP_CATEGORY, oxNew(InactiveCategories::class));
|
||||
$this->registerExport(self::GROUP_SHOP, oxNew(KeyFigures::class));
|
||||
}
|
||||
// extend to add exports and actions via 'registerAction()' or 'registerExport()' method
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $group
|
||||
* @param ActionBase $action
|
||||
*/
|
||||
public function registerAction($group, ActionBase $action)
|
||||
public function registerAction($group, ActionBase $action): void
|
||||
{
|
||||
$this->actions[$group][md5(serialize($action))] = $action;
|
||||
$this->actions[$group][md5(get_class($action))] = $action;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $group
|
||||
* @param ExportBase $export
|
||||
*/
|
||||
public function registerExport($group, ExportBase $export)
|
||||
public function registerExport($group, ExportBase $export): void
|
||||
{
|
||||
$this->exports[$group][md5(serialize($export))] = $export;
|
||||
$this->exports[$group][md5(get_class($export))] = $export;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -100,9 +93,9 @@ class Configuration
|
|||
/**
|
||||
* @param $group
|
||||
*
|
||||
* @return mixed
|
||||
* @return array
|
||||
*/
|
||||
public function getActionsByGroup($group)
|
||||
public function getActionsByGroup($group): array
|
||||
{
|
||||
return $this->actions[$group];
|
||||
}
|
||||
|
@ -110,9 +103,9 @@ class Configuration
|
|||
/**
|
||||
* @param $group
|
||||
*
|
||||
* @return mixed
|
||||
* @return array
|
||||
*/
|
||||
public function getExportsByGroup($group)
|
||||
public function getExportsByGroup($group): array
|
||||
{
|
||||
return $this->exports[$group];
|
||||
}
|
||||
|
@ -120,7 +113,7 @@ class Configuration
|
|||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getAllActions() : array
|
||||
public function getAllActions(): array
|
||||
{
|
||||
$all = [];
|
||||
|
||||
|
@ -134,7 +127,7 @@ class Configuration
|
|||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getAllExports() : array
|
||||
public function getAllExports(): array
|
||||
{
|
||||
$all = [];
|
||||
|
||||
|
@ -150,9 +143,15 @@ class Configuration
|
|||
*
|
||||
* @return ActionBase
|
||||
*/
|
||||
public function getActionById($id) : ActionBase
|
||||
public function getActionById($id): ActionBase
|
||||
{
|
||||
return $this->getAllActions()[$id];
|
||||
$allActions = $this->getAllActions();
|
||||
|
||||
if ( ! $allActions[ $id ] ) {
|
||||
throw oxNew(DataWizardException::class, 'no action with id '.$id);
|
||||
}
|
||||
|
||||
return $allActions[$id];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -160,8 +159,14 @@ class Configuration
|
|||
*
|
||||
* @return ExportBase
|
||||
*/
|
||||
public function getExportById($id) : ExportBase
|
||||
public function getExportById($id): ExportBase
|
||||
{
|
||||
return $this->getAllExports()[$id];
|
||||
$allExports = $this->getAllExports();
|
||||
|
||||
if ( ! $allExports[ $id ] ) {
|
||||
throw oxNew(DataWizardException::class, 'no export with id '.$id);
|
||||
}
|
||||
|
||||
return $allExports[$id];
|
||||
}
|
||||
}
|
|
@ -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';
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
/**
|
||||
* 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)
|
||||
|
@ -17,6 +17,6 @@ namespace D3\DataWizard\Application\Model\Exceptions;
|
|||
|
||||
use OxidEsales\Eshop\Core\Exception\StandardException;
|
||||
|
||||
class RenderException extends StandardException implements DataWizardException
|
||||
class DataWizardException extends StandardException
|
||||
{
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
/**
|
||||
* 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)
|
||||
|
@ -16,18 +16,17 @@ declare(strict_types=1);
|
|||
namespace D3\DataWizard\Application\Model\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use OxidEsales\Eshop\Core\Exception\StandardException;
|
||||
use OxidEsales\Eshop\Core\Registry;
|
||||
|
||||
class DebugException extends StandardException implements DataWizardException
|
||||
class DebugException extends DataWizardException
|
||||
{
|
||||
public function __construct($sMessage = "not set", $iCode = 0, Exception $previous = null )
|
||||
public function __construct($sMessage = "not set", $iCode = 0, Exception $previous = null)
|
||||
{
|
||||
$sMessage = sprintf(
|
||||
Registry::getLang()->translateString('D3_DATAWIZARD_DEBUG'),
|
||||
$sMessage
|
||||
);
|
||||
|
||||
parent::__construct($sMessage, $iCode, $previous );
|
||||
parent::__construct($sMessage, $iCode, $previous);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* https://www.d3data.de
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
|
||||
* @link https://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\Application\Model\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use OxidEsales\Eshop\Core\Registry;
|
||||
|
||||
class ExportFileException extends DataWizardException
|
||||
{
|
||||
public function __construct($sMessage = "not set", $iCode = 0, Exception $previous = null)
|
||||
{
|
||||
$sMessage = sprintf(
|
||||
Registry::getLang()->translateString('D3_DATAWIZARD_ERR_EXPORTFILEERROR'),
|
||||
$sMessage
|
||||
);
|
||||
|
||||
parent::__construct($sMessage, $iCode, $previous);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* https://www.d3data.de
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
|
||||
* @link https://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\Application\Model\Exceptions;
|
||||
|
||||
use D3\DataWizard\Application\Model\QueryBase;
|
||||
use Exception;
|
||||
use FormManager\Inputs\Input;
|
||||
|
||||
class InputUnvalidException extends DataWizardException
|
||||
{
|
||||
public QueryBase $task;
|
||||
|
||||
/**
|
||||
* InputUnvalidException constructor.
|
||||
* @param QueryBase $task
|
||||
* @param Input $inputElement
|
||||
* @param int $iCode
|
||||
* @param Exception|null $previous
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __construct(QueryBase $task, Input $inputElement, $iCode = 0, Exception $previous = null)
|
||||
{
|
||||
$messages = [];
|
||||
foreach ($inputElement->getError()->getIterator() as $item) {
|
||||
$messages[] = $inputElement->label->innerHTML.' -> '.$item->getMessage();
|
||||
}
|
||||
|
||||
$sMessage = implode(
|
||||
' - ',
|
||||
[
|
||||
$task->getTitle(),
|
||||
implode(', ', $messages),
|
||||
]
|
||||
);
|
||||
parent::__construct($sMessage, $iCode, $previous);
|
||||
|
||||
$this->task = $task;
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
/**
|
||||
* 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)
|
||||
|
@ -16,18 +16,17 @@ declare(strict_types=1);
|
|||
namespace D3\DataWizard\Application\Model\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use OxidEsales\Eshop\Core\Exception\StandardException;
|
||||
use OxidEsales\Eshop\Core\Registry;
|
||||
|
||||
class NoSuitableRendererException extends StandardException implements DataWizardException
|
||||
class NoSuitableRendererException extends DataWizardException
|
||||
{
|
||||
public function __construct($sMessage = "not set", $iCode = 0, Exception $previous = null )
|
||||
public function __construct($sMessage = "not set", $iCode = 0, Exception $previous = null)
|
||||
{
|
||||
$sMessage = sprintf(
|
||||
Registry::getLang()->translateString('D3_DATAWIZARD_ERR_NOSUITABLERENDERER'),
|
||||
$sMessage
|
||||
);
|
||||
|
||||
parent::__construct($sMessage, $iCode, $previous );
|
||||
parent::__construct($sMessage, $iCode, $previous);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
/**
|
||||
* 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)
|
||||
|
@ -15,6 +15,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace D3\DataWizard\Application\Model\Exceptions;
|
||||
|
||||
interface DataWizardException
|
||||
class RenderException extends DataWizardException
|
||||
{
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
/**
|
||||
* 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)
|
||||
|
@ -17,24 +17,22 @@ namespace D3\DataWizard\Application\Model\Exceptions;
|
|||
|
||||
use D3\DataWizard\Application\Model\QueryBase;
|
||||
use Exception;
|
||||
use OxidEsales\Eshop\Core\Exception\StandardException;
|
||||
|
||||
class TaskException extends StandardException implements DataWizardException
|
||||
class TaskException extends DataWizardException
|
||||
{
|
||||
/** @var QueryBase */
|
||||
public $task;
|
||||
public QueryBase $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)
|
||||
{
|
||||
$sMessage = implode(
|
||||
' - ',
|
||||
[
|
||||
$task->getTitle(),
|
||||
$sMessage
|
||||
$sMessage,
|
||||
]
|
||||
);
|
||||
parent::__construct( $sMessage, $iCode, $previous );
|
||||
parent::__construct($sMessage, $iCode, $previous);
|
||||
|
||||
$this->task = $task;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,274 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* https://www.d3data.de
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
|
||||
* @link https://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\Application\Model;
|
||||
|
||||
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\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\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 array $formElements = [];
|
||||
|
||||
/**
|
||||
* Ensure that the translations are equally available in the frontend and the backend
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $format
|
||||
* @param null $path
|
||||
*
|
||||
* @return string
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws DBALException
|
||||
* @throws DatabaseConnectionException
|
||||
* @throws DatabaseErrorException
|
||||
* @throws Exception
|
||||
* @throws NoSuitableRendererException
|
||||
* @throws NotFoundExceptionInterface
|
||||
* @throws StandardException
|
||||
* @throws d3ShopCompatibilityAdapterException
|
||||
* @throws d3_cfg_mod_exception
|
||||
*/
|
||||
public function run(string $format = RendererBridge::FORMAT_CSV, $path = null): string
|
||||
{
|
||||
if ($this->hasFormElements()) {
|
||||
/** @var Input $element */
|
||||
foreach ($this->getFormElements() as $element) {
|
||||
if (false === $element->isValid()) {
|
||||
throw oxNew(InputUnvalidException::class, $this, $element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->executeExport($format, $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getButtonText(): string
|
||||
{
|
||||
return "D3_DATAWIZARD_EXPORT_SUBMIT";
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NoSuitableRendererException
|
||||
*/
|
||||
public function getRenderer(string $format): RendererInterface
|
||||
{
|
||||
return $this->getRendererBridge()->getRenderer($format);
|
||||
}
|
||||
|
||||
public function getRendererBridge(): RendererBridge
|
||||
{
|
||||
return oxNew(RendererBridge::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NoSuitableRendererException
|
||||
*/
|
||||
public function getFileExtension(string $format): string
|
||||
{
|
||||
return $this->getRenderer($format)->getFileExtension();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $rows
|
||||
* @param $fieldnames
|
||||
* @param $format
|
||||
*
|
||||
* @return string
|
||||
* @throws Exceptions\NoSuitableRendererException
|
||||
*/
|
||||
public function renderContent($rows, $fieldnames, $format): string
|
||||
{
|
||||
$renderer = $this->getRenderer($format);
|
||||
return $renderer->getContent($rows, $fieldnames);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getExportFilenameBase(): string
|
||||
{
|
||||
return $this->getTitle();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $format
|
||||
*
|
||||
* @return string
|
||||
* @throws Exceptions\NoSuitableRendererException
|
||||
*/
|
||||
public function getExportFileName($format): string
|
||||
{
|
||||
return $this->getExportFilenameBase().'_'.date('Y-m-d_H-i-s').'.'.$this->getFileExtension($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $query
|
||||
*
|
||||
* @return array
|
||||
* @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') {
|
||||
throw oxNew(
|
||||
Exceptions\TaskException::class,
|
||||
$this,
|
||||
Registry::getLang()->translateString('D3_DATAWIZARD_ERR_NOEXPORTSELECT')
|
||||
);
|
||||
}
|
||||
|
||||
$rows = $this->getConnection()->executeQuery($queryString, $parameters)->fetchAllAssociative();
|
||||
|
||||
if (count($rows) <= 0) {
|
||||
throw oxNew(
|
||||
Exceptions\TaskException::class,
|
||||
$this,
|
||||
Registry::getLang()->translateString('D3_DATAWIZARD_ERR_NOEXPORTCONTENT', null, true)
|
||||
);
|
||||
}
|
||||
|
||||
$fieldNames = array_keys($rows[0]);
|
||||
|
||||
return [ $rows, $fieldNames ];
|
||||
}
|
||||
|
||||
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>');
|
||||
$input->setAttribute('class', 'form-check-input');
|
||||
} else {
|
||||
$input->setTemplate('<p class="formElements">{{ label }} {{ input }}</p>');
|
||||
$input->setAttribute('class', 'form-control');
|
||||
}
|
||||
$this->formElements[] = $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasFormElements(): bool
|
||||
{
|
||||
return (bool) count($this->formElements);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getFormElements(): array
|
||||
{
|
||||
return $this->formElements;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $format
|
||||
* @param $path
|
||||
*
|
||||
* @return string
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws DBALException
|
||||
* @throws DatabaseConnectionException
|
||||
* @throws DatabaseErrorException
|
||||
* @throws Exception
|
||||
* @throws NoSuitableRendererException
|
||||
* @throws NotFoundExceptionInterface
|
||||
* @throws StandardException
|
||||
* @throws d3ShopCompatibilityAdapterException
|
||||
* @throws d3_cfg_mod_exception
|
||||
*/
|
||||
protected function executeExport(string $format, $path): string
|
||||
{
|
||||
$content = $this->getContent($format);
|
||||
|
||||
$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)) {
|
||||
throw oxNew(ExportFileException::class, $filePath);
|
||||
}
|
||||
return $filePath;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
protected function getFileSystem(): d3filesystem
|
||||
{
|
||||
return oxNew(d3filesystem::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $format
|
||||
*
|
||||
* @return string
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws DBALException
|
||||
* @throws Exception
|
||||
* @throws NoSuitableRendererException
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function getContent(string $format): string
|
||||
{
|
||||
[ $rows, $fieldNames ] = $this->getExportData($this->getQuery());
|
||||
|
||||
return $this->renderContent($rows, $fieldNames, $format);
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
/**
|
||||
* 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)
|
||||
|
@ -16,33 +16,37 @@ 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;
|
||||
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 );
|
||||
$csv->insertAll( $rows );
|
||||
$this->forceEnclose ? $csv->forceEnclosure() : $csv->relaxEnclosure();
|
||||
$csv->insertOne((array) $fieldNames);
|
||||
$csv->insertAll($rows);
|
||||
return (string) $csv;
|
||||
} catch (Exception $e) {
|
||||
/** @var RenderException $newException */
|
||||
$newException = oxNew(RenderException::class, $e->getMessage(), $e->getCode(), $e );
|
||||
$newException = oxNew(RenderException::class, $e->getMessage(), $e->getCode(), $e);
|
||||
throw $newException;
|
||||
}
|
||||
|
||||
return $csv->getContent();
|
||||
}
|
||||
|
||||
public function getFileExtension(): string
|
||||
|
@ -58,20 +62,30 @@ class Csv implements RendererInterface
|
|||
{
|
||||
$csv = Writer::createFromString();
|
||||
|
||||
EncloseField::addTo($csv, "\t\x1f");
|
||||
|
||||
$sEncloser = Registry::getConfig()->getConfigParam('sGiCsvFieldEncloser');
|
||||
if (false == $sEncloser) {
|
||||
$sEncloser = '"';
|
||||
}
|
||||
$sEncloser = $this->d3GetConfig()->getConfigParam('sGiCsvFieldEncloser') ?? '"';
|
||||
$csv->setEnclosure($sEncloser);
|
||||
|
||||
$sDelimiter = Registry::getConfig()->getConfigParam('sCSVSign');
|
||||
if (false == $sDelimiter) {
|
||||
$sDelimiter = ';';
|
||||
}
|
||||
$sDelimiter = $this->d3GetConfig()->getConfigParam('sCSVSign') ?? ';';
|
||||
$csv->setDelimiter($sDelimiter);
|
||||
|
||||
$csv->addValidator(new ColumnConsistency(), 'columns_consistency');
|
||||
|
||||
return $csv;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitleTranslationId(): string
|
||||
{
|
||||
return 'D3_DATAWIZARD_EXPORT_FORMAT_CSV';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Config
|
||||
*/
|
||||
public function d3GetConfig(): Config
|
||||
{
|
||||
return Registry::getConfig();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* https://www.d3data.de
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
|
||||
* @link https://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\Application\Model\ExportRenderer;
|
||||
|
||||
use D3\DataWizard\Application\Model\Exceptions\RenderException;
|
||||
use JsonException;
|
||||
|
||||
class Json implements RendererInterface
|
||||
{
|
||||
/**
|
||||
* @param iterable $rows
|
||||
* @param iterable $fieldNames
|
||||
*
|
||||
* @return string
|
||||
* @throws RenderException
|
||||
*/
|
||||
public function getContent( iterable $rows, iterable $fieldNames): string
|
||||
{
|
||||
try {
|
||||
$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);
|
||||
throw $newException;
|
||||
}
|
||||
}
|
||||
|
||||
public function getFileExtension(): string
|
||||
{
|
||||
return 'json';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitleTranslationId(): string
|
||||
{
|
||||
return "D3_DATAWIZARD_EXPORT_FORMAT_JSON";
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
/**
|
||||
* 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)
|
||||
|
@ -20,17 +20,26 @@ 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 = oxNew(ArrayToTextTable::class, $rows);
|
||||
$renderer = $this->getArrayToTextTableInstance($rows);
|
||||
return $renderer->getTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $rows
|
||||
* @return ArrayToTextTable
|
||||
*/
|
||||
public function getArrayToTextTableInstance($rows): ArrayToTextTable
|
||||
{
|
||||
return oxNew(ArrayToTextTable::class, $rows);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
|
@ -38,4 +47,12 @@ class Pretty implements RendererInterface
|
|||
{
|
||||
return 'txt';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitleTranslationId(): string
|
||||
{
|
||||
return "D3_DATAWIZARD_EXPORT_FORMAT_PRETTY";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* https://www.d3data.de
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
|
||||
* @link https://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\Application\Model\ExportRenderer;
|
||||
|
||||
use D3\DataWizard\Application\Model\Exceptions\NoSuitableRendererException;
|
||||
|
||||
class RendererBridge
|
||||
{
|
||||
public const FORMAT_CSV = 'CSV';
|
||||
public const FORMAT_PRETTY = 'Pretty';
|
||||
public const FORMAT_JSON = 'JSON';
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getRendererList(): array
|
||||
{
|
||||
return [
|
||||
self::FORMAT_CSV => oxNew(Csv::class),
|
||||
self::FORMAT_PRETTY => oxNew(Pretty::class),
|
||||
self::FORMAT_JSON => oxNew(Json::class),
|
||||
];
|
||||
}
|
||||
|
||||
public function getTranslatedRendererIdList(): array
|
||||
{
|
||||
$rendererList = $this->getRendererList();
|
||||
array_walk($rendererList, [$this, 'translateRendererId']);
|
||||
return $rendererList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RendererInterface $instance
|
||||
*/
|
||||
protected function translateRendererId(RendererInterface &$instance): void
|
||||
{
|
||||
$instance = $instance->getTitleTranslationId();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $format
|
||||
*
|
||||
* @return RendererInterface
|
||||
* @throws NoSuitableRendererException
|
||||
*/
|
||||
public function getRenderer(string $format = self::FORMAT_CSV): RendererInterface
|
||||
{
|
||||
$format = strtolower($format);
|
||||
|
||||
$rendererList = array_change_key_case($this->getRendererList());
|
||||
$rendererListTypes = array_keys(array_change_key_case($rendererList));
|
||||
|
||||
if (in_array($format, $rendererListTypes, true)) {
|
||||
return $rendererList[$format];
|
||||
}
|
||||
|
||||
/** @var NoSuitableRendererException $e */
|
||||
$e = oxNew(NoSuitableRendererException::class, $format);
|
||||
throw $e;
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
/**
|
||||
* 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)
|
||||
|
@ -18,15 +18,20 @@ 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
|
||||
*/
|
||||
public function getFileExtension() : string;
|
||||
}
|
||||
public function getFileExtension(): string;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitleTranslationId(): string;
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
/**
|
||||
* 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)
|
||||
|
@ -15,27 +15,46 @@ declare(strict_types=1);
|
|||
|
||||
namespace D3\DataWizard\Application\Model;
|
||||
|
||||
use FormManager\Inputs\Input;
|
||||
|
||||
interface QueryBase
|
||||
{
|
||||
public function run();
|
||||
|
||||
/**
|
||||
* Ensure that the translations are equally available in the frontend and the backend
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle() : string;
|
||||
public function getTitle(): string;
|
||||
|
||||
/**
|
||||
* Ensure that the translations are equally available in the frontend and the backend
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(): string;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription() : string;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getButtonText() : string;
|
||||
public function getButtonText(): string;
|
||||
|
||||
/**
|
||||
* @return array [string $query, array $parameters]
|
||||
*/
|
||||
public function getQuery() : array;
|
||||
}
|
||||
public function getQuery(): array;
|
||||
|
||||
/**
|
||||
* @param Input $input
|
||||
*/
|
||||
public function registerFormElement(Input $input);
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasFormElements(): bool;
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getFormElements(): array;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -3,7 +3,7 @@
|
|||
/**
|
||||
* 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)
|
||||
|
@ -11,14 +11,10 @@
|
|||
* @link https://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
declare(strict_types=1);
|
||||
|
||||
$sLangName = "Deutsch";
|
||||
// -------------------------------
|
||||
// RESOURCE IDENTITFIER = STRING
|
||||
// -------------------------------
|
||||
$aLang = array(
|
||||
|
||||
return [
|
||||
//Navigation
|
||||
'charset' => 'UTF-8',
|
||||
'd3mxDataWizard' => '<i class="fas fa-fw fa-hat-wizard"></i> Data Wizard',
|
||||
|
@ -27,20 +23,22 @@ $aLang = array(
|
|||
|
||||
'SHOP_MODULE_GROUP_d3datawizard_general' => 'Grundeinstellungen',
|
||||
'SHOP_MODULE_d3datawizard_debug' => 'zeigt Abfragen anstatt diese auszufĂĽhren',
|
||||
'SHOP_MODULE_d3datawizard_hideexamples' => 'Beispielexporte ausblenden',
|
||||
|
||||
'D3_DATAWIZARD_GROUP_ARTICLES' => 'Artikel',
|
||||
'D3_DATAWIZARD_GROUP_CATEGORIES' => 'Kategorien',
|
||||
'D3_DATAWIZARD_GROUP_ORDERS' => 'Bestellungen',
|
||||
'D3_DATAWIZARD_GROUP_REMARKS' => 'Bewertungen',
|
||||
'D3_DATAWIZARD_GROUP_SHOP' => 'Shop',
|
||||
'D3_DATAWIZARD_GROUP_CMS' => 'CMS-Texte',
|
||||
'D3_DATAWIZARD_GROUP_USERS' => 'Benutzer',
|
||||
|
||||
'D3_DATAWIZARD_EXPORT_SUBMIT' => 'Export starten',
|
||||
'D3_DATAWIZARD_EXPORT_FORMAT_CSV' => 'CSV-Format',
|
||||
'D3_DATAWIZARD_EXPORT_FORMAT_PRETTY' => 'Pretty-Format',
|
||||
'D3_DATAWIZARD_EXPORT_FORMAT_JSON' => 'JSON-Format',
|
||||
|
||||
'D3_DATAWIZARD_ACTION_SUBMIT' => 'Aktion starten',
|
||||
'D3_DATAWIZARD_ACTION_SUBMIT_CONFIRM' => 'Soll die Aktion gestartet werden?',
|
||||
|
||||
'D3_DATAWIZARD_DEBUG' => 'Debug: %1$s',
|
||||
|
||||
|
@ -48,20 +46,11 @@ $aLang = array(
|
|||
'D3_DATAWIZARD_ERR_NOEXPORT_INSTALLED' => 'Es sind keine Exporte installiert oder aktiviert.',
|
||||
'D3_DATAWIZARD_ERR_NOEXPORTCONTENT' => 'Export ist leer, kein Inhalt zum Download verfĂĽgbar',
|
||||
'D3_DATAWIZARD_ERR_NOSUITABLERENDERER' => 'kein Renderer fĂĽr Format "%1$s" registriert',
|
||||
|
||||
'D3_DATAWIZARD_EXPORTS_INACTIVECATEGORIES' => 'deaktivierte Kategorien, mit aktiven Artikel',
|
||||
'D3_DATAWIZARD_EXPORTS_INACTIVECATEGORIES_TREE' => 'Baum',
|
||||
'D3_DATAWIZARD_EXPORTS_INACTIVECATEGORIES_TITLE' => 'Titel',
|
||||
'D3_DATAWIZARD_EXPORTS_INACTIVECATEGORIES_COUNT' => 'Anzahl',
|
||||
|
||||
'D3_DATAWIZARD_EXPORTS_KEYFIGURES' => 'Bestellungskennzahlen nach Monat',
|
||||
'D3_DATAWIZARD_EXPORTS_KEYFIGURES_ORDERSPERMONTH' => 'Bestellungen pro Monat',
|
||||
'D3_DATAWIZARD_EXPORTS_KEYFIGURES_BASKETSIZE' => 'Warenkorbhöhe',
|
||||
'D3_DATAWIZARD_EXPORTS_KEYFIGURES_MONTH' => 'Monat',
|
||||
'D3_DATAWIZARD_ERR_EXPORTFILEERROR' => 'Exportdatei "%1$s" kann nicht angelegt werden',
|
||||
|
||||
'D3_DATAWIZARD_ERR_ACTIONSELECT' => 'Aktion kann nicht ausgeführt werden. Aktionen können keine SELECTs exportieren.',
|
||||
'D3_DATAWIZARD_ERR_NOACTION_INSTALLED' => 'Es sind keine Aktionen installiert oder aktiviert.',
|
||||
'D3_DATAWIZARD_ERR_ACTIONRESULT' => '%1$s Eintrag verändert',
|
||||
'D3_DATAWIZARD_ERR_ACTIONRESULTS' => '%1$s Einträge verändert',
|
||||
'D3_DATAWIZARD_ACTIONS_FIXARTEXTENDSITEMS' => 'fehlende oxartextends-Einträge nachtragen',
|
||||
);
|
||||
];
|
||||
// @codeCoverageIgnoreEnd
|
|
@ -0,0 +1,57 @@
|
|||
<?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);
|
||||
|
||||
return [
|
||||
|
||||
//Navigation
|
||||
'charset' => 'UTF-8',
|
||||
'd3mxDataWizard' => '<i class="fas fa-fw fa-hat-wizard"></i> Data Wizard',
|
||||
'd3mxDataWizard_Export' => 'exports',
|
||||
'd3mxDataWizard_Action' => 'actions',
|
||||
|
||||
'SHOP_MODULE_GROUP_d3datawizard_general' => 'basic settings',
|
||||
'SHOP_MODULE_d3datawizard_debug' => 'shows queries instead of executing them',
|
||||
|
||||
'D3_DATAWIZARD_GROUP_ARTICLES' => 'articles',
|
||||
'D3_DATAWIZARD_GROUP_CATEGORIES' => 'categories',
|
||||
'D3_DATAWIZARD_GROUP_ORDERS' => 'orders',
|
||||
'D3_DATAWIZARD_GROUP_REMARKS' => 'remarks',
|
||||
'D3_DATAWIZARD_GROUP_SHOP' => 'shop',
|
||||
'D3_DATAWIZARD_GROUP_CMS' => 'CMS items',
|
||||
'D3_DATAWIZARD_GROUP_USERS' => 'users',
|
||||
|
||||
'D3_DATAWIZARD_EXPORT_SUBMIT' => 'generate export',
|
||||
'D3_DATAWIZARD_EXPORT_FORMAT_CSV' => 'CSV format',
|
||||
'D3_DATAWIZARD_EXPORT_FORMAT_PRETTY' => 'Pretty format',
|
||||
'D3_DATAWIZARD_EXPORT_FORMAT_JSON' => 'JSON format',
|
||||
|
||||
'D3_DATAWIZARD_ACTION_SUBMIT' => 'run action',
|
||||
'D3_DATAWIZARD_ACTION_SUBMIT_CONFIRM' => 'Should the action be executed?',
|
||||
|
||||
'D3_DATAWIZARD_DEBUG' => 'Debug: %1$s',
|
||||
|
||||
'D3_DATAWIZARD_ERR_NOEXPORTSELECT' => 'Export cannot be executed. Exports require SELECT Query.',
|
||||
'D3_DATAWIZARD_ERR_NOEXPORT_INSTALLED' => 'No exports are installed or activated.',
|
||||
'D3_DATAWIZARD_ERR_NOEXPORTCONTENT' => 'Export is empty, no content available for download',
|
||||
'D3_DATAWIZARD_ERR_NOSUITABLERENDERER' => 'No renderer registered for format "%1$s"',
|
||||
'D3_DATAWIZARD_ERR_EXPORTFILEERROR' => 'Export file "%1$s" cannot be created',
|
||||
|
||||
'D3_DATAWIZARD_ERR_ACTIONSELECT' => 'Action cannot be executed. Actions cannot export SELECTs.',
|
||||
'D3_DATAWIZARD_ERR_NOACTION_INSTALLED' => 'No actions are installed or activated.',
|
||||
'D3_DATAWIZARD_ERR_ACTIONRESULT' => '%1$s entry changed',
|
||||
'D3_DATAWIZARD_ERR_ACTIONRESULTS' => '%1$s entries changed',
|
||||
];
|
||||
// @codeCoverageIgnoreEnd
|
82
CHANGELOG.md
82
CHANGELOG.md
|
@ -1,5 +1,85 @@
|
|||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## 1.0.0.0 (2021-06-22)
|
||||
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).
|
||||
|
||||
## [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
|
||||
|
||||
## [2.1.1.2](https://git.d3data.de/D3Public/DataWizard/compare/2.1.1.1...2.1.1.2) - 2023-03-30
|
||||
### Fixed
|
||||
- fix JavaScript for multiple forms
|
||||
|
||||
## [2.1.1.1](https://git.d3data.de/D3Public/DataWizard/compare/2.1.1.0...2.1.1.1) - 2023-03-22
|
||||
### Fixed
|
||||
- wrong cascaded HTML elements
|
||||
|
||||
## [2.1.1.0](https://git.d3data.de/D3Public/DataWizard/compare/2.1.0.0...2.1.1.0) - 2022-12-24
|
||||
### Added
|
||||
- installable in OXID 6.5.0 and 6.5.1
|
||||
- request confirmation before execute action
|
||||
|
||||
### Changed
|
||||
- documentation extended
|
||||
|
||||
## [2.1.0.0](https://git.d3data.de/D3Public/DataWizard/compare/2.0.0.0...2.1.0.0) - 2021-12-21
|
||||
### Changed
|
||||
- adjust to CLI extension which can export to STDOUT
|
||||
|
||||
## [2.0.0.0](https://git.d3data.de/D3Public/DataWizard/compare/1.4.0.0...2.0.0.0) - 2021-12-20
|
||||
### Added
|
||||
- add tests
|
||||
- make installable in OXID 6.4
|
||||
|
||||
### Changed
|
||||
- adjust code to PHP 7.3 and up
|
||||
|
||||
## [1.4.0.0](https://git.d3data.de/D3Public/DataWizard/compare/1.3.1.0...1.4.0.0) - 2021-11-11
|
||||
### Added
|
||||
- add JSON export renderer
|
||||
- add tpl block for easier extension
|
||||
- enable controller based exception handling
|
||||
|
||||
### Changed
|
||||
- change deprecated CSV export code
|
||||
- show registered export renderers in admin submit without required tpl block extension
|
||||
- force get translations from admin
|
||||
|
||||
## [1.3.1.0](https://git.d3data.de/D3Public/DataWizard/compare/1.2.0.0...1.3.0.0) - 2021-09-10
|
||||
### Added
|
||||
- installable in OXID 6.3.1
|
||||
|
||||
## [1.3.0.0](https://git.d3data.de/D3Public/DataWizard/compare/1.2.0.0...1.3.0.0) - 2021-07-29
|
||||
### Changed
|
||||
- can handle long task description text
|
||||
- has more generic admin controller templates
|
||||
|
||||
## [1.2.0.0](https://git.d3data.de/D3Public/DataWizard/compare/1.1.0.0...1.2.0.0) - 2021-07-27
|
||||
### Added
|
||||
- adjustments for CLI extension
|
||||
|
||||
### Fixed
|
||||
- fix OXID 6.1 incompatibilities
|
||||
|
||||
## [1.1.0.0](https://git.d3data.de/D3Public/DataWizard/compare/1.0.0.0...1.1.0.0) - 2021-06-25
|
||||
### Added
|
||||
- implement form builder
|
||||
|
||||
### Fixed
|
||||
- fix key figures export
|
||||
|
||||
## [1.0.0.0](https://git.d3data.de/D3Public/DataWizard/releases/tag/1.0.0.0) - 2021-06-22
|
||||
### Added
|
||||
- initial implementation
|
89
README.en.md
89
README.en.md
|
@ -1,4 +1,5 @@
|
|||
> [deutsche Version](README.md)
|
||||
[![deutsche Version](https://logos.oxidmodule.com/de2_xs.svg)](README.md)
|
||||
[![english version](https://logos.oxidmodule.com/en2_xs.svg)](README.en.md)
|
||||
|
||||
# DÂł Data Wizard for OXID eShop
|
||||
|
||||
|
@ -6,65 +7,75 @@ The module `DataWizard` offers a framework for the simple integration of exports
|
|||
|
||||
The exports are defined via database queries or ready-made data lists. Various export formats are available. The generation is possible at any time and always recurring (within the system limits). These are offered as downloads in the browser.
|
||||
|
||||
All exports are grouped together for better clarity.
|
||||
All exports and tasks are grouped together for better clarity.
|
||||
|
||||
Sample exports are included in the scope of delivery. These are intended to serve as an implementation reference for individual exports. The display of the sample exports can be deactivated in the basic module settings.
|
||||
Sample exports are included in the package `d3/datawizardtasks`. These are intended to serve as an implementation reference for individual exports.
|
||||
|
||||
Translated with www.DeepL.com/Translator (free version)
|
||||
![administration area](assets/administration_exports.jpg "administration area")
|
||||
|
||||
## Table of content
|
||||
|
||||
- [Installation](#installation)
|
||||
- [Usage](#usage)
|
||||
- [Extensibility](#extensibility)
|
||||
- [Extension packages](#extension-packages)
|
||||
- [Changelog](#changelog)
|
||||
- [Contributing](#contributing)
|
||||
- [License](#license)
|
||||
- [Further licences and terms of use](#further-licences-and-terms-of-use)
|
||||
|
||||
## Installation
|
||||
|
||||
In the console in the shop root (above source and vendor), execute the following command:
|
||||
This package requires an Composer installed OXID eShop as defined in [composer.json](composer.json).
|
||||
|
||||
Open a command line interface and navigate to the shop root directory (parent of source and vendor). Execute the following command. Adapt the paths to your environment.
|
||||
|
||||
```bash
|
||||
php composer require d3/datawizard
|
||||
php composer require d3/datawizard:^2.0
|
||||
```
|
||||
|
||||
Activate in the admin area of the shop under "Extensions -> Modules".
|
||||
Activate the module in the admin area of the shop in "Extensions -> Modules".
|
||||
|
||||
# Extensibility
|
||||
## Usage
|
||||
|
||||
These package doesn't contain any export or action items. See [Extension packages](#extension_packages) for installable example items.
|
||||
|
||||
Log in to the admin area of your shop and navigate to "DÂł Modules -> Data Wizard". Go to "Exports" or "Actions" (as desired). Choose your desired item and export or execute it.
|
||||
|
||||
## Extensibility
|
||||
|
||||
The module represents the technical basic framework of the exports and does not claim to be complete. In order to adapt the scope to individual requirements, the following extensions are prepared:
|
||||
|
||||
- Add exports
|
||||
- Add exports or tasks
|
||||
- Use existing and new groups
|
||||
- Add export formats
|
||||
|
||||
Independently of this, all extension options are available that the OXID Shop provides for modules.
|
||||
|
||||
## Add exports
|
||||
### Extension packages
|
||||
|
||||
### Define export
|
||||
|
||||
Each export is defined in a separate class. This export class must extend the class `D3\DataWizard\Application\Model\ExportBase`. All necessary functions are predefined in it. The following methods are available:
|
||||
|
||||
#### mandatory method calls:
|
||||
- getTitle() - defines the title in the admin area and the base of the later export file name.
|
||||
- getQuery() - contains the query as a prepared statement that defines the data to be exported
|
||||
|
||||
#### optional method calls:
|
||||
- getDescription() - contains a short additional description of the export, this will be shown in the admin area
|
||||
- getButtonText() - defines the text of the submit button in the admin area
|
||||
- getExportFilenameBase() - defines the base of the later export filename
|
||||
- executeQuery() - returns the compiled export data
|
||||
- further methods, the adaptation of which, however, can lead to changed module behaviour and should therefore only be changed with caution
|
||||
|
||||
### Register exports
|
||||
|
||||
In order to be able to use the created export in the module, it must be registered. For this purpose there is the class `D3\DataWizard\Application\Model\Configuration`. This is to be overloaded with the possibilities of the OXID shop and the method `configure()` contained therein is to be supplemented. The following call is available for registering an export:
|
||||
|
||||
```
|
||||
$this->registerExport(self::GROUP_CATEGORY, oxNew(myCustomExport::class));
|
||||
```
|
||||
|
||||
The first parameter contains the language identifier for the export group. Typical identifiers are already prepared in constants of the configuration class. The instance of the export class is expected as the 2nd parameter.
|
||||
- `d3/datawizardtasks` - provides sample exports and their implementation reference
|
||||
- `d3/datawizardcli` - provides the execution of exports or tasks via the command prompt (e.g. as cronjobs)
|
||||
- `d3/datawizardlink` - provides URLs to generate exports from third party systems
|
||||
|
||||
## Changelog
|
||||
|
||||
See [CHANGELOG](CHANGELOG.md) for further informations.
|
||||
|
||||
## Licence of this software (d3/datawizard)
|
||||
(status: 06.05.2021)
|
||||
## Contributing
|
||||
|
||||
If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue. Don't forget to give the project a star! Thanks again!
|
||||
|
||||
- Fork the Project
|
||||
- Create your Feature Branch (git checkout -b feature/AmazingFeature)
|
||||
- Commit your Changes (git commit -m 'Add some AmazingFeature')
|
||||
- Push to the Branch (git push origin feature/AmazingFeature)
|
||||
- Open a Pull Request
|
||||
|
||||
## License
|
||||
(status: 2021-05-06)
|
||||
|
||||
Distributed under the GPLv3 license.
|
||||
|
||||
```
|
||||
Copyright (c) D3 Data Development (Inh. Thomas Dartsch)
|
||||
|
@ -92,7 +103,7 @@ Gradients available on the site are free to use on personal and commercial proje
|
|||
The following software packages are not part of this module. However, they are required for use. The linked packages are under the following licences:
|
||||
|
||||
### league/csv [MIT]
|
||||
(https://github.com/thephpleague/csv - status: 06.05.2021)
|
||||
(https://github.com/thephpleague/csv - status: 2021-05-06)
|
||||
|
||||
```
|
||||
Copyright (c) 2013-2017 ignace nyamagana butera
|
||||
|
@ -116,7 +127,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
```
|
||||
|
||||
### mathieuviossat/arraytotexttable [MIT]
|
||||
(https://github.com/viossat/arraytotexttable - status: 06.05.2021)
|
||||
(https://github.com/viossat/arraytotexttable - status: 2021-05-06)
|
||||
|
||||
```
|
||||
Copyright (c) 2015 Mathieu Viossat
|
||||
|
@ -138,4 +149,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
```
|
||||
```
|
84
README.md
84
README.md
|
@ -1,67 +1,83 @@
|
|||
> [english version](README.en.md)
|
||||
[![deutsche Version](https://logos.oxidmodule.com/de2_xs.svg)](README.md)
|
||||
[![english version](https://logos.oxidmodule.com/en2_xs.svg)](README.en.md)
|
||||
|
||||
# DÂł Data Wizard fĂĽr OXID eShop
|
||||
|
||||
Das Modul `DataWizard` bietet ein Framework zur einfachen Integration von Exporten ĂĽber den Adminbereich des OXID Shops.
|
||||
Das Modul `DataWizard` bietet ein Framework zur einfachen Integration von Exporten und ausfĂĽhrbaren Tasks ĂĽber den Adminbereich des OXID Shops.
|
||||
|
||||
Die Exporte werden über Datenbankabfragen oder fertige Datenlisten definiert. Es stehen verschiedene Exportformate zur Verfügung. Die Generierung ist jederzeit und immer wiederkehrend möglich (im Rahmen der Systemgrenzen). Diese werden im Browser als Download angeboten.
|
||||
|
||||
Alle Exporte sind fĂĽr eine bessere Ăśbersichtlichkeit in Gruppen zusammengefasst.
|
||||
Alle Exporte bzw. Tasks sind fĂĽr eine bessere Ăśbersichtlichkeit in Gruppen zusammengefasst.
|
||||
|
||||
Im Lieferumfang sind Beispielexporte enthalten. Diese sollen als Implementierungsreferenz fĂĽr individuelle Exporte dienen. Die Anzeige der Beispielexporte kann in den Modulgrundeinstellungen deaktiviert werden.
|
||||
Im Paket `d3/datawizardtasks` sind Beispielexporte enthalten. Diese sollen als Implementierungsreferenz fĂĽr individuelle Exporte dienen.
|
||||
|
||||
## Schnellinstallation
|
||||
![Adminbereich](assets/administration_exports.jpg "Adminbereich")
|
||||
|
||||
## Inhaltsverzeichnis
|
||||
|
||||
- [Installation](#installation)
|
||||
- [Verwendung](#verwendung)
|
||||
- [Erweiterbarkeit](#erweiterbarkeit)
|
||||
- [Erweiterungspakete](#erweiterungspakete)
|
||||
- [Changelog](#changelog)
|
||||
- [Beitragen](#beitragen)
|
||||
- [Lizenz](#lizenz)
|
||||
- [weitere Lizenzen und Nutzungsbedingungen](#weitere-lizenzen-und-nutzungsbedingungen)
|
||||
|
||||
## Installation
|
||||
|
||||
Dieses Paket erfordert einen mit Composer installierten OXID eShop in einer in der [composer.json](composer.json) definierten Version.
|
||||
|
||||
Ă–ffnen Sie eine Kommandozeile und navigieren Sie zum Stammverzeichnis des Shops (Elternverzeichnis von source und vendor). FĂĽhren Sie den folgenden Befehl aus. Passen Sie die Pfadangaben an Ihre Installationsumgebung an.
|
||||
|
||||
Auf der Konsole im Shoproot (oberhalb von source und vendor) folgenden Befehl ausfĂĽhren:
|
||||
|
||||
```bash
|
||||
php composer require d3/datawizard
|
||||
php composer require d3/datawizard:^2.0
|
||||
```
|
||||
|
||||
Aktivieren Sie das Modul im Shopadmin unter "Erweiterungen -> Module".
|
||||
|
||||
## Verwendung
|
||||
|
||||
Dieses Paket enthält keine Exporte oder Aktionen. In [Erweiterungspakete](#erweiterungspakete) finden Sie installierbare Beispieleinträge.
|
||||
|
||||
Melden Sie sich im Adminbereich Ihres Shops an und navigieren Sie zu "D³ Module -> Data Wizard". Wechseln Sie je nach Wunsch zu "Exporte" oder "Aktionen". Wählen Sie den gewünschten Eintrag und starten Sie den Export bzw. die Aktion.
|
||||
|
||||
## Erweiterbarkeit
|
||||
|
||||
Das Modul stellt das technische Grundgerüst der Exporte dar und erhebt keinen Anspruch auf Vollständigkeit. Um den Umfang an die individuellen Anforderungen anzupassen, sind folgende Erweiterungen vorbereitet:
|
||||
|
||||
- Exporte hinzufĂĽgen
|
||||
- Exporte oder Tasks hinzufĂĽgen
|
||||
- Verwendung bestehender und neuer Gruppen
|
||||
- Exportformate ergänzen
|
||||
|
||||
Unabhängig dessen stehen alle Erweiterungsmöglichkeiten zur Verfügung, die der OXID Shop für Module bereitstellt.
|
||||
|
||||
### Exporte hinzufĂĽgen
|
||||
### Erweiterungspakete
|
||||
|
||||
#### Export definieren
|
||||
|
||||
Jeder Export wird in einer separaten Klasse definiert. Diese Exportklasse muss die Klasse `D3\DataWizard\Application\Model\ExportBase` erweitern. Darin sind alle nötigen Funktionen vordefiniert. Folgende Methoden stehen hierbei zur Verfügung:
|
||||
|
||||
##### verpflichtende Methodenaufrufe:
|
||||
- getTitle() - definiert den Titel im Adminbereich und die Basis des späteren Exportdateinamens
|
||||
- getQuery() - enthält den Abfragequery als prepared statement, der die zu exportierenden Daten definiert
|
||||
|
||||
##### optionale Methodenaufrufe:
|
||||
- getDescription() - enthält eine kurze zusätzliche Beschreibung des Exports, dieser wird im Adminbereich gezeigt
|
||||
- getButtonText() - definiert den Text des Absenden-Buttons im Adminbereich
|
||||
- getExportFilenameBase() - definiert die Basis des späteren Exportdateinamens
|
||||
- executeQuery() - liefert die zusammengestellten Exportdaten
|
||||
- weitere Methoden, deren Anpassung jedoch zum geänderten Modulverhalten führen können und daher nur mit Vorsicht zu verändern sind
|
||||
|
||||
#### Exporte registrieren
|
||||
|
||||
Um den erstellten Export auch im Modul verwenden zu können, muss dieser noch registriert werden. Hierzu gibt des die Klasse `D3\DataWizard\Application\Model\Configuration`. Diese ist mit den Möglichkeiten des OXID Shops zu überladen und die darin enthaltene Methode `configure()` zu ergänzen. Für die Registrierung eines Exportes steht Ihnen dazu folgender Aufruf zur Verfügung:
|
||||
|
||||
```
|
||||
$this->registerExport(self::GROUP_CATEGORY, oxNew(myCustomExport::class));
|
||||
```
|
||||
|
||||
Der erste Parameter enthält den Sprachident für die Exportgruppe. In Konstanten der configuration-Klasse sind schon typische Idents vorbereitet. Als 2. Parameter wird die Instanz der Exportklasse erwartet.
|
||||
- `d3/datawizardtasks` - liefert Beispielexporte und deren Implementierungsreferenz
|
||||
- `d3/datawizardcli` - ermöglicht die Ausführung der Exporte oder Tasks über die Eingabeaufforderung (z.B. als Cronjobs)
|
||||
- `d3/datawizardlink` - stellt URLs zur VerfĂĽgung, um Exporte von Drittsystemen generieren zu lassen
|
||||
|
||||
## Changelog
|
||||
|
||||
Siehe [CHANGELOG](CHANGELOG.md) fĂĽr weitere Informationen.
|
||||
|
||||
## Lizenz dieser Software (d3/datawizard)
|
||||
## Beitragen
|
||||
|
||||
Wenn Sie eine Verbesserungsvorschlag haben, legen Sie einen Fork des Repositories an und erstellen Sie einen Pull Request. Alternativ können Sie einfach ein Issue erstellen. Fügen Sie das Projekt zu Ihren Favoriten hinzu. Vielen Dank.
|
||||
|
||||
- Erstellen Sie einen Fork des Projekts
|
||||
- Erstellen Sie einen Feature Branch (git checkout -b feature/AmazingFeature)
|
||||
- FĂĽgen Sie Ihre Ă„nderungen hinzu (git commit -m 'Add some AmazingFeature')
|
||||
- Ăśbertragen Sie den Branch (git push origin feature/AmazingFeature)
|
||||
- Ă–ffnen Sie einen Pull Request
|
||||
|
||||
## Lizenz
|
||||
(Stand: 06.05.2021)
|
||||
|
||||
Vertrieben unter der GPLv3 Lizenz.
|
||||
|
||||
```
|
||||
Copyright (c) D3 Data Development (Inh. Thomas Dartsch)
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 76 KiB |
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "d3/datawizard",
|
||||
"description": "das magische Datenwerkzeug",
|
||||
"description": "the magical data tool /\n das magische Datenwerkzeug",
|
||||
"type": "oxideshop-module",
|
||||
"keywords": [
|
||||
"oxid",
|
||||
|
@ -25,20 +25,30 @@
|
|||
"GPL-3.0-or-later"
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.1",
|
||||
"oxid-esales/oxideshop-ce": "6.3 - 6.8",
|
||||
"php": "^8.0",
|
||||
"oxid-esales/oxideshop-ce": "7.0 - 7.1",
|
||||
"league/csv": "^9.0",
|
||||
"mathieuviossat/arraytotexttable": "^1.0"
|
||||
"mathieuviossat/arraytotexttable": "^1.0",
|
||||
"form-manager/form-manager": "^6.1",
|
||||
"d3/modcfg": "^7.0",
|
||||
"beberlei/assert": "^3.3.2"
|
||||
},
|
||||
"extra": {
|
||||
"oxideshop": {
|
||||
"source-directory": "/src",
|
||||
"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",
|
||||
"d3/datawizardcli": "command line implementation for fully automated Data Wizard tasks",
|
||||
"d3/datawizardlink": "remote http link for Data Wizard module exports"
|
||||
},
|
||||
"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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
modules:
|
||||
- d3modcfg_lib
|
|
@ -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">';
|
||||
|
||||
/**
|
||||
|
@ -31,34 +30,31 @@ $aModule = [
|
|||
'de' => '',
|
||||
'en' => '',
|
||||
],
|
||||
'thumbnail' => '',
|
||||
'version' => '0.1',
|
||||
'thumbnail' => 'picture.svg',
|
||||
'version' => '3.0.0.0',
|
||||
'author' => 'D³ Data Development (Inh.: Thomas Dartsch)',
|
||||
'email' => 'support@shopmodule.com',
|
||||
'url' => 'https://www.oxidmodule.com/',
|
||||
'controllers' => [
|
||||
'd3ExportWizard' => D3\DataWizard\Application\Controller\Admin\d3ExportWizard::class,
|
||||
'd3ActionWizard' => D3\DataWizard\Application\Controller\Admin\d3ActionWizard::class
|
||||
'd3ActionWizard' => D3\DataWizard\Application\Controller\Admin\d3ActionWizard::class,
|
||||
],
|
||||
'extend' => [],
|
||||
'events' => [],
|
||||
'templates' => [
|
||||
'd3ExportWizard.tpl' => 'd3/datawizard/Application/views/admin/tpl/d3ExportWizard.tpl',
|
||||
'd3ActionWizard.tpl' => 'd3/datawizard/Application/views/admin/tpl/d3ActionWizard.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' => [
|
||||
[
|
||||
'group' => $sModuleId.'_general',
|
||||
'name' => $sModuleId.'_debug',
|
||||
'type' => 'bool',
|
||||
'value' => false
|
||||
],
|
||||
[
|
||||
'group' => $sModuleId.'_general',
|
||||
'name' => $sModuleId.'_hideexamples',
|
||||
'type' => 'bool',
|
||||
'value' => false
|
||||
'value' => false,
|
||||
],
|
||||
],
|
||||
'blocks' => []
|
||||
'blocks' => [],
|
||||
];
|
|
@ -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>
|
|
@ -0,0 +1,84 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 14.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 43363) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="201px" height="124px" viewBox="0 0 201 124" enable-background="new 0 0 201 124" xml:space="preserve">
|
||||
<g>
|
||||
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="47.0591" y1="67.5117" x2="47.0591" y2="54.6143">
|
||||
<stop offset="0.0056" style="stop-color:#3266A9"/>
|
||||
<stop offset="1" style="stop-color:#0099FF"/>
|
||||
</linearGradient>
|
||||
<path fill="url(#SVGID_1_)" d="M50.282,55.502c-0.784-0.592-2.104-0.888-3.961-0.888h-1.376l-2.283,12.898h1.779
|
||||
c3.76,0,6.032-2.245,6.815-6.733c0.134-0.871,0.202-1.642,0.202-2.313C51.457,57.081,51.064,56.093,50.282,55.502z"/>
|
||||
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="65.9609" y1="49.104" x2="65.9609" y2="36.9434">
|
||||
<stop offset="0.0056" style="stop-color:#3266A9"/>
|
||||
<stop offset="1" style="stop-color:#0099FF"/>
|
||||
</linearGradient>
|
||||
<path fill="url(#SVGID_2_)" d="M65.72,40.482c1.074,0,1.611,0.381,1.611,1.143c0,0.701-0.321,1.201-0.962,1.5
|
||||
c-0.209,0.119-0.366,0.194-0.471,0.224c-0.065,0.019-0.158,0.037-0.271,0.056c1.98,1.621,3.702,3.544,5.097,5.699
|
||||
c0.117-0.321,0.21-0.658,0.277-1.013l0.09-1.008c0-1.223-0.568-2.081-1.701-2.574c0.776-0.402,1.376-0.94,1.801-1.611
|
||||
c0.425-0.672,0.638-1.418,0.638-2.239c0-0.642-0.198-1.265-0.593-1.868c-0.396-0.605-0.98-1.049-1.757-1.333
|
||||
c-0.433-0.193-0.876-0.328-1.332-0.402c-0.456-0.075-1.003-0.113-1.645-0.113c-0.82,0-1.663,0.124-2.529,0.37
|
||||
c-0.865,0.246-1.6,0.563-2.204,0.952s-1.13,0.907-1.578,1.557c-0.036,0.052-0.066,0.109-0.101,0.163
|
||||
c1.196,0.534,2.341,1.163,3.426,1.874C63.947,40.943,64.68,40.482,65.72,40.482z"/>
|
||||
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="50.0576" y1="87.0566" x2="50.0576" y2="37.8525">
|
||||
<stop offset="0.0056" style="stop-color:#3266A9"/>
|
||||
<stop offset="1" style="stop-color:#0099FF"/>
|
||||
</linearGradient>
|
||||
<path fill="url(#SVGID_3_)" d="M70.725,49.104c-0.433,1.189-1.208,2.147-2.331,2.871c-1.425,0.918-3.182,1.377-5.271,1.377
|
||||
c-1.179,0-2.175-0.176-2.988-0.525c-0.813-0.35-1.444-0.864-1.891-1.543c-0.448-0.678-0.671-1.481-0.671-2.405l0.022-0.694
|
||||
l0.156-0.693h4.367l-0.028,0.179v0.179v0.246c0,1.164,0.628,1.746,1.884,1.746c0.635,0,1.201-0.217,1.696-0.649
|
||||
c0.495-0.434,0.742-0.94,0.742-1.522c0-0.522-0.194-0.887-0.582-1.097c-0.329-0.208-1.007-0.313-2.036-0.313l0.47-2.754
|
||||
l1.141-0.067c0.083-0.011,0.154-0.022,0.221-0.033c-0.674-0.551-1.378-1.067-2.11-1.546c-0.044,0.096-0.087,0.195-0.125,0.302
|
||||
h-4.185c0.192-0.837,0.49-1.56,0.884-2.175c-3.064-1.372-6.46-2.133-10.034-2.133c-13.588,0-24.603,11.014-24.603,24.601
|
||||
c0,13.59,11.015,24.604,24.603,24.604S74.66,76.043,74.66,62.453C74.66,57.532,73.214,52.949,70.725,49.104z M59.413,59.233
|
||||
l-0.168,1.275c-0.538,2.953-1.511,5.404-2.921,7.35c-1.298,1.835-3.016,3.179-5.153,4.028c-2.138,0.851-4.494,1.274-7.067,1.274
|
||||
H33.731l4.264-24.198h10.441c1.141,0,2.204,0.073,3.189,0.218c0.984,0.146,1.868,0.364,2.651,0.655
|
||||
c1.611,0.537,2.887,1.471,3.827,2.802c0.94,1.332,1.41,2.992,1.41,4.984L59.413,59.233z"/>
|
||||
</g>
|
||||
<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="107.3027" y1="105.8555" x2="93.0727" y2="16.0106">
|
||||
<stop offset="0" style="stop-color:#B2B2B2;stop-opacity:0"/>
|
||||
<stop offset="0.2" style="stop-color:#B2B2B2"/>
|
||||
<stop offset="0.8" style="stop-color:#B2B2B2"/>
|
||||
<stop offset="1" style="stop-color:#B2B2B2;stop-opacity:0"/>
|
||||
</linearGradient>
|
||||
<rect x="99.875" y="14.933" fill="url(#SVGID_4_)" width="0.625" height="92"/>
|
||||
<script xmlns=""></script>
|
||||
<g>
|
||||
<g>
|
||||
<path fill="none" d="M153.855,40.748H140.76v9.354c0,1.034-0.839,1.872-1.871,1.872h-9.354v20.582
|
||||
c0,1.031,0.838,1.869,1.871,1.869h22.45c0.083,0,0.159-0.014,0.239-0.023l-5.59-5.588h-13.358c-1.032,0-1.871-0.84-1.871-1.871
|
||||
c0-1.033,0.839-1.871,1.871-1.871h9.617l-3.742-3.743h-5.875c-1.032,0-1.871-0.837-1.871-1.871c0-1.034,0.839-1.871,1.871-1.871
|
||||
h3.215c-0.183-1.584,0.68-3.495,2.505-5.326c0.765-0.765,2.763-2.533,4.869-2.533c0.546,0,1.063,0.117,1.527,0.339
|
||||
c0.346,0.133,0.668,0.338,0.945,0.615l7.52,7.517V42.618C155.728,41.585,154.889,40.748,153.855,40.748z"/>
|
||||
<polygon fill="none" points="137.018,43.393 132.18,48.231 137.018,48.231 "/>
|
||||
<path d="M133.275,66.941c0,1.031,0.839,1.871,1.871,1.871h13.358l-3.741-3.742h-9.617
|
||||
C134.114,65.07,133.275,65.908,133.275,66.941z"/>
|
||||
<path d="M133.275,59.457c0,1.033,0.839,1.871,1.871,1.871h5.875l-1.73-1.73c-0.272-0.272-0.476-0.587-0.613-0.923
|
||||
c-0.169-0.339-0.272-0.705-0.316-1.089h-3.215C134.114,57.585,133.275,58.423,133.275,59.457z"/>
|
||||
<path d="M153.855,74.424h-22.45c-1.033,0-1.871-0.838-1.871-1.869V51.973h9.354c1.032,0,1.871-0.838,1.871-1.872v-9.354h13.096
|
||||
c1.033,0,1.872,0.837,1.872,1.871v15.579l1.419,1.42l1.301-1.736l-0.989-2.9c-0.358-1.065-0.215-2.155,0.394-3.001
|
||||
c0.401-0.559,0.971-0.953,1.617-1.147v-8.215c0-3.1-2.514-5.613-5.613-5.613h-14.967c-0.496,0-0.973,0.197-1.322,0.548
|
||||
L126.34,48.779c-0.351,0.352-0.548,0.827-0.548,1.323v22.453c0,3.1,2.514,5.611,5.613,5.611h22.45
|
||||
c1.139,0,2.196-0.342,3.081-0.924l-2.842-2.842C154.015,74.41,153.938,74.424,153.855,74.424z M137.018,43.393v4.838h-4.838
|
||||
L137.018,43.393z"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path fill="#010002" d="M159.092,62.488l3.655-0.048c0.479-0.006,1.107,0.314,1.388,0.71l2.109,2.982
|
||||
c0.281,0.393,0.624,0.34,0.769-0.125l1.089-3.486c0.14-0.466,0.636-0.96,1.098-1.103l3.487-1.084
|
||||
c0.465-0.142,0.52-0.488,0.126-0.768l-2.985-2.112c-0.396-0.281-0.716-0.903-0.705-1.385l0.044-3.656
|
||||
c0.006-0.479-0.305-0.644-0.694-0.352l-2.929,2.186c-0.385,0.289-1.076,0.397-1.536,0.246l-3.46-1.177
|
||||
c-0.459-0.153-0.709,0.093-0.555,0.549l1.179,3.46c0.15,0.455,0.043,1.149-0.24,1.539l-2.19,2.926
|
||||
C158.447,62.182,158.61,62.492,159.092,62.488z"/>
|
||||
<path fill="#010002" d="M175.635,82.078l0.061-0.063l-29.578-29.571l-0.033,0.032c-0.005-0.002-0.005-0.006-0.009-0.007
|
||||
c-0.489-0.496-1.99,0.201-3.343,1.552c-1.348,1.353-2.045,2.848-1.553,3.343c0.003,0.005,0.009,0.005,0.01,0.006l-0.033,0.036
|
||||
l29.575,29.578l0.059-0.064c0.587,0.313,1.962-0.367,3.215-1.625C175.267,84.037,175.943,82.662,175.635,82.078z
|
||||
M149.582,60.874c-0.715,0.715-1.469,1.239-2.096,1.51l-4.374-4.4c0.624-0.272,1.368-0.795,2.08-1.503
|
||||
c0.705-0.708,1.222-1.446,1.497-2.066l4.385,4.41C150.801,59.443,150.28,60.174,149.582,60.874z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 6.4 KiB |
|
@ -1,91 +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
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\Application\Controller\Admin;
|
||||
|
||||
use D3\DataWizard\Application\Model\Configuration;
|
||||
use D3\DataWizard\Application\Model\Exceptions\DataWizardException;
|
||||
use D3\DataWizard\Application\Model\Exceptions\DebugException;
|
||||
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 OxidEsales\Eshop\Application\Controller\Admin\AdminDetailsController;
|
||||
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
|
||||
use OxidEsales\Eshop\Core\Exception\DatabaseErrorException;
|
||||
use OxidEsales\Eshop\Core\Exception\StandardException;
|
||||
use OxidEsales\Eshop\Core\Registry;
|
||||
|
||||
class d3ActionWizard extends AdminDetailsController
|
||||
{
|
||||
protected $_sThisTemplate = 'd3ActionWizard.tpl';
|
||||
|
||||
/** @var Configuration */
|
||||
protected $configuration;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->configuration = oxNew(Configuration::class);
|
||||
}
|
||||
|
||||
public function getGroups()
|
||||
{
|
||||
return $this->configuration->getActionGroups();
|
||||
}
|
||||
|
||||
public function getGroupActions($group)
|
||||
{
|
||||
return $this->configuration->getActionsByGroup($group);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws DatabaseConnectionException
|
||||
* @throws StandardException
|
||||
* @throws d3ShopCompatibilityAdapterException
|
||||
* @throws d3_cfg_mod_exception
|
||||
*/
|
||||
public function doAction()
|
||||
{
|
||||
try {
|
||||
$id = Registry::getRequest()->getRequestEscapedParameter('actionid');
|
||||
$action = $this->configuration->getActionById($id);
|
||||
|
||||
[ $queryString, $parameters ] = $action->getQuery();
|
||||
|
||||
if (Registry::getConfig()->getConfigParam('d3datawizard_debug')) {
|
||||
throw oxNew(
|
||||
DebugException::class,
|
||||
d3database::getInstance()->getPreparedStatementQuery($queryString, $parameters)
|
||||
);
|
||||
}
|
||||
|
||||
$action->run();
|
||||
} catch (DataWizardException|DBALException|DatabaseErrorException $e) {
|
||||
Registry::getUtilsView()->addErrorToDisplay($e);
|
||||
}
|
||||
}
|
||||
|
||||
public function getUserMessages()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getHelpURL()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,91 +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
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\Application\Controller\Admin;
|
||||
|
||||
use D3\DataWizard\Application\Model\Configuration;
|
||||
use D3\DataWizard\Application\Model\Exceptions\DataWizardException;
|
||||
use D3\DataWizard\Application\Model\Exceptions\DebugException;
|
||||
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 OxidEsales\Eshop\Application\Controller\Admin\AdminDetailsController;
|
||||
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
|
||||
use OxidEsales\Eshop\Core\Exception\DatabaseErrorException;
|
||||
use OxidEsales\Eshop\Core\Exception\StandardException;
|
||||
use OxidEsales\Eshop\Core\Registry;
|
||||
|
||||
class d3ExportWizard extends AdminDetailsController
|
||||
{
|
||||
protected $_sThisTemplate = 'd3ExportWizard.tpl';
|
||||
|
||||
/** @var Configuration */
|
||||
protected $configuration;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->configuration = oxNew(Configuration::class);
|
||||
}
|
||||
|
||||
public function getGroups()
|
||||
{
|
||||
return $this->configuration->getExportGroups();
|
||||
}
|
||||
|
||||
public function getGroupExports($group)
|
||||
{
|
||||
return $this->configuration->getExportsByGroup($group);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws DatabaseConnectionException
|
||||
* @throws StandardException
|
||||
* @throws d3ShopCompatibilityAdapterException
|
||||
* @throws d3_cfg_mod_exception
|
||||
*/
|
||||
public function doExport()
|
||||
{
|
||||
try {
|
||||
$id = Registry::getRequest()->getRequestEscapedParameter('exportid');
|
||||
$export = $this->configuration->getExportById($id);
|
||||
|
||||
[ $queryString, $parameters ] = $export->getQuery();
|
||||
|
||||
if (Registry::getConfig()->getConfigParam('d3datawizard_debug')) {
|
||||
throw oxNew(
|
||||
DebugException::class,
|
||||
d3database::getInstance()->getPreparedStatementQuery($queryString, $parameters)
|
||||
);
|
||||
}
|
||||
|
||||
$export->run(Registry::getRequest()->getRequestEscapedParameter('exportformat'));
|
||||
} catch (DataWizardException|DBALException|DatabaseErrorException $e) {
|
||||
Registry::getUtilsView()->addErrorToDisplay($e);
|
||||
}
|
||||
}
|
||||
|
||||
public function getUserMessages()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getHelpURL()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,84 +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
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\Application\Model;
|
||||
|
||||
use OxidEsales\Eshop\Core\DatabaseProvider;
|
||||
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
|
||||
use OxidEsales\Eshop\Core\Exception\DatabaseErrorException;
|
||||
use OxidEsales\Eshop\Core\Registry;
|
||||
|
||||
abstract class ActionBase implements QueryBase
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription() : string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws DatabaseConnectionException
|
||||
* @throws DatabaseErrorException
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->executeAction( $this->getQuery() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $query
|
||||
*
|
||||
* @return int
|
||||
* @throws DatabaseConnectionException
|
||||
* @throws DatabaseErrorException
|
||||
*/
|
||||
public function executeAction( array $query ): int
|
||||
{
|
||||
[ $queryString, $parameters ] = $query;
|
||||
|
||||
$queryString = trim($queryString);
|
||||
|
||||
if ( strtolower( substr( $queryString, 0, 6 ) ) === 'select' ) {
|
||||
throw oxNew(
|
||||
Exceptions\TaskException::class,
|
||||
$this,
|
||||
Registry::getLang()->translateString( 'D3_DATAWIZARD_ERR_ACTIONSELECT' )
|
||||
);
|
||||
}
|
||||
|
||||
$affected = DatabaseProvider::getDb( DatabaseProvider::FETCH_MODE_ASSOC )->execute( $queryString, $parameters );
|
||||
|
||||
throw oxNew(
|
||||
Exceptions\TaskException::class,
|
||||
$this,
|
||||
sprintf(
|
||||
Registry::getLang()->translateString(
|
||||
$affected === 1 ? 'D3_DATAWIZARD_ERR_ACTIONRESULT' : 'D3_DATAWIZARD_ERR_ACTIONRESULTS'
|
||||
),
|
||||
$affected
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getButtonText() : string
|
||||
{
|
||||
return "D3_DATAWIZARD_ACTION_SUBMIT";
|
||||
}
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This Software is the property of Data Development and is protected
|
||||
* by copyright law - it is NOT Freeware.
|
||||
* Any unauthorized use of this software without a valid license
|
||||
* is a violation of the license agreement and will be prosecuted by
|
||||
* civil and criminal law.
|
||||
* http://www.shopmodule.com
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <support@shopmodule.com>
|
||||
* @link http://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\Application\Model\Actions;
|
||||
|
||||
use D3\DataWizard\Application\Model\ActionBase;
|
||||
use OxidEsales\Eshop\Core\Model\BaseModel;
|
||||
use OxidEsales\Eshop\Core\Model\MultiLanguageModel;
|
||||
use OxidEsales\Eshop\Core\Registry;
|
||||
|
||||
class FixArtextendsItems extends ActionBase
|
||||
{
|
||||
/**
|
||||
* fehlende oxartextends-Einträge nachtragen
|
||||
*/
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle() : string
|
||||
{
|
||||
return Registry::getLang()->translateString('D3_DATAWIZARD_ACTIONS_FIXARTEXTENDSITEMS');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getQuery() : array
|
||||
{
|
||||
$aDefaultValueFields = array(
|
||||
'oxtimestamp' => "''",
|
||||
);
|
||||
|
||||
$aNonArtExtendsFields = array(
|
||||
'oxid' => 'oxarticles.oxid',
|
||||
);
|
||||
|
||||
$aArtExtendsFields = array_fill_keys($this->getArtExtendsFields(), "''");
|
||||
$aMergedFields = array_merge($aNonArtExtendsFields, $aArtExtendsFields);
|
||||
$aQueryFields = array_diff_key($aMergedFields, $aDefaultValueFields);
|
||||
|
||||
$sArtExtendsFields = implode(', ', array_keys($aQueryFields));
|
||||
|
||||
$select = "SELECT ".implode(', ', $aQueryFields).
|
||||
" FROM oxarticles".
|
||||
" LEFT JOIN oxartextends AS arx ON oxarticles.oxid = arx.oxid".
|
||||
" WHERE arx.oxid IS NULL";
|
||||
|
||||
$query = "INSERT INTO oxartextends ($sArtExtendsFields) ".
|
||||
$select;
|
||||
|
||||
return [$query, []];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getArtExtendsFields(): array
|
||||
{
|
||||
/** @var $oArtExtends MultiLanguageModel */
|
||||
$oArtExtends = oxNew(BaseModel::class);
|
||||
$oArtExtends->init('oxartextends', false);
|
||||
|
||||
$aFieldNames = $oArtExtends->getFieldNames();
|
||||
|
||||
if (false == $aFieldNames) {
|
||||
$oArtExtends->disableLazyLoading();
|
||||
$aFieldNames = $oArtExtends->getFieldNames();
|
||||
}
|
||||
|
||||
unset($aFieldNames[array_search('oxid', $aFieldNames)]);
|
||||
|
||||
return $aFieldNames;
|
||||
}
|
||||
}
|
|
@ -1,163 +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
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\Application\Model;
|
||||
|
||||
use D3\DataWizard\Application\Model\ExportRenderer\RendererBridge;
|
||||
use D3\ModCfg\Application\Model\d3filesystem;
|
||||
use D3\ModCfg\Application\Model\Exception\d3_cfg_mod_exception;
|
||||
use D3\ModCfg\Application\Model\Exception\d3ShopCompatibilityAdapterException;
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use 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;
|
||||
|
||||
abstract class ExportBase implements QueryBase
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription() : string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $format
|
||||
*
|
||||
* @throws DBALException
|
||||
* @throws DatabaseConnectionException
|
||||
* @throws DatabaseErrorException
|
||||
* @throws Exceptions\NoSuitableRendererException
|
||||
* @throws Exceptions\TaskException
|
||||
* @throws StandardException
|
||||
* @throws d3ShopCompatibilityAdapterException
|
||||
* @throws d3_cfg_mod_exception
|
||||
*/
|
||||
public function run($format = RendererBridge::FORMAT_CSV)
|
||||
{
|
||||
[ $rows, $fieldNames ] = $this->getExportData( $this->getQuery() );
|
||||
|
||||
$content = $this->renderContent($rows, $fieldNames, $format);
|
||||
|
||||
/** @var $oFS d3filesystem */
|
||||
$oFS = oxNew(d3filesystem::class);
|
||||
$oFS->startDirectDownload(
|
||||
$oFS->filterFilename($this->getExportFileName($format)),
|
||||
$content
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getButtonText() : string
|
||||
{
|
||||
return "D3_DATAWIZARD_EXPORT_SUBMIT";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $format
|
||||
*
|
||||
* @return ExportRenderer\RendererInterface
|
||||
* @throws Exceptions\NoSuitableRendererException
|
||||
*/
|
||||
public function getRenderer($format): ExportRenderer\RendererInterface
|
||||
{
|
||||
return oxNew(RendererBridge::class)->getRenderer($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $format
|
||||
*
|
||||
* @return string
|
||||
* @throws Exceptions\NoSuitableRendererException
|
||||
*/
|
||||
public function getFileExtension($format): string
|
||||
{
|
||||
return $this->getRenderer($format)->getFileExtension();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $rows
|
||||
* @param $fieldnames
|
||||
* @param $format
|
||||
*
|
||||
* @return string
|
||||
* @throws Exceptions\NoSuitableRendererException
|
||||
*/
|
||||
public function renderContent($rows, $fieldnames, $format): string
|
||||
{
|
||||
$renderer = $this->getRenderer($format);
|
||||
return $renderer->getContent($rows, $fieldnames);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getExportFilenameBase() : string
|
||||
{
|
||||
return $this->getTitle();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $format
|
||||
*
|
||||
* @return string
|
||||
* @throws Exceptions\NoSuitableRendererException
|
||||
*/
|
||||
public function getExportFileName($format) : string
|
||||
{
|
||||
return $this->getExportFilenameBase().'_'.date('Y-m-d_H-i-s').'.'.$this->getFileExtension($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $query
|
||||
*
|
||||
* @return array
|
||||
* @throws DatabaseConnectionException
|
||||
* @throws DatabaseErrorException
|
||||
*/
|
||||
public function getExportData( array $query ): array
|
||||
{
|
||||
[ $queryString, $parameters ] = $query;
|
||||
|
||||
$queryString = trim($queryString);
|
||||
|
||||
if ( strtolower( substr( $queryString, 0, 6 ) ) !== 'select' ) {
|
||||
throw oxNew(
|
||||
Exceptions\TaskException::class,
|
||||
$this,
|
||||
Registry::getLang()->translateString( 'D3_DATAWIZARD_ERR_NOEXPORTSELECT' )
|
||||
);
|
||||
}
|
||||
|
||||
$rows = DatabaseProvider::getDb( DatabaseProvider::FETCH_MODE_ASSOC )->getAll( $queryString, $parameters );
|
||||
|
||||
if ( count( $rows ) <= 0 ) {
|
||||
throw oxNew(
|
||||
Exceptions\TaskException::class,
|
||||
$this,
|
||||
Registry::getLang()->translateString( 'D3_DATAWIZARD_ERR_NOEXPORTCONTENT' )
|
||||
);
|
||||
}
|
||||
|
||||
$fieldNames = array_keys( $rows[0] );
|
||||
|
||||
return [ $rows, $fieldNames ];
|
||||
}
|
||||
}
|
|
@ -1,44 +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
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\Application\Model\ExportRenderer;
|
||||
|
||||
use D3\DataWizard\Application\Model\Exceptions\NoSuitableRendererException;
|
||||
|
||||
class RendererBridge
|
||||
{
|
||||
const FORMAT_CSV = 'CSV';
|
||||
const FORMAT_PRETTY = 'Pretty';
|
||||
|
||||
/**
|
||||
* @param string $format
|
||||
*
|
||||
* @throws NoSuitableRendererException
|
||||
* @return RendererInterface
|
||||
*/
|
||||
public function getRenderer($format = self::FORMAT_CSV): RendererInterface
|
||||
{
|
||||
switch ($format) {
|
||||
case self::FORMAT_CSV:
|
||||
return oxNew(Csv::class);
|
||||
case self::FORMAT_PRETTY:
|
||||
return oxNew(Pretty::class);
|
||||
}
|
||||
|
||||
/** @var NoSuitableRendererException $e */
|
||||
$e = oxNew(NoSuitableRendererException::class, $format);
|
||||
throw $e;
|
||||
}
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This Software is the property of Data Development and is protected
|
||||
* by copyright law - it is NOT Freeware.
|
||||
* Any unauthorized use of this software without a valid license
|
||||
* is a violation of the license agreement and will be prosecuted by
|
||||
* civil and criminal law.
|
||||
* http://www.shopmodule.com
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <support@shopmodule.com>
|
||||
* @link http://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
namespace D3\DataWizard\Application\Model\Exports;
|
||||
|
||||
use D3\DataWizard\Application\Model\ExportBase;
|
||||
use OxidEsales\Eshop\Application\Model\Article;
|
||||
use OxidEsales\Eshop\Application\Model\Category;
|
||||
use OxidEsales\Eshop\Application\Model\Object2Category;
|
||||
use OxidEsales\Eshop\Core\Registry;
|
||||
|
||||
class InactiveCategories extends ExportBase
|
||||
{
|
||||
/**
|
||||
* Kategorien -deaktiviert, mit aktiven Artikel
|
||||
*/
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle() : string
|
||||
{
|
||||
return Registry::getLang()->translateString('D3_DATAWIZARD_EXPORTS_INACTIVECATEGORIES');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getQuery() : array
|
||||
{
|
||||
$categoryTableName = oxNew(Category::class)->getCoreTableName();
|
||||
$object2categoryTableName = oxNew(Object2Category::class)->getCoreTableName();
|
||||
$articleTableName = oxNew(Article::class)->getCoreTableName();
|
||||
|
||||
$treeTitle = Registry::getLang()->translateString('D3_DATAWIZARD_EXPORTS_INACTIVECATEGORIES_TREE');
|
||||
$titleTitle = Registry::getLang()->translateString('D3_DATAWIZARD_EXPORTS_INACTIVECATEGORIES_TITLE');
|
||||
$countTitle = Registry::getLang()->translateString('D3_DATAWIZARD_EXPORTS_INACTIVECATEGORIES_COUNT');
|
||||
|
||||
return [
|
||||
"SELECT
|
||||
oc.OXID,
|
||||
oc.OXSHOPID,
|
||||
oc.oxtitle as :titleTitle,
|
||||
(
|
||||
SELECT GROUP_CONCAT(oxtitle ORDER BY oxleft ASC SEPARATOR ' > ')
|
||||
from ".$categoryTableName."
|
||||
WHERE OXLEFT < oc.oxleft AND OXRIGHT > oc.oxright AND OXROOTID = oc.OXROOTID AND OXSHOPID = oc.OXSHOPID
|
||||
) as :treeTitle,
|
||||
COUNT(oa.oxid) as :countTitle
|
||||
FROM ".$categoryTableName." oc
|
||||
LEFT JOIN ".$object2categoryTableName." o2c ON oc.OXID = o2c.OXCATNID
|
||||
LEFT JOIN ".$articleTableName." oa ON o2c.OXOBJECTID = oa.OXID
|
||||
WHERE oc.OXACTIVE = :categoryActive AND oa.OXACTIVE = :articleActive
|
||||
GROUP BY oc.oxid
|
||||
ORDER BY oc.oxleft ASC",
|
||||
[
|
||||
'categoryActive' => 0,
|
||||
'articleActive' => 1,
|
||||
'titleTitle' => $titleTitle,
|
||||
'treeTitle' => $treeTitle,
|
||||
'countTitle' => $countTitle
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This Software is the property of Data Development and is protected
|
||||
* by copyright law - it is NOT Freeware.
|
||||
* Any unauthorized use of this software without a valid license
|
||||
* is a violation of the license agreement and will be prosecuted by
|
||||
* civil and criminal law.
|
||||
* http://www.shopmodule.com
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <support@shopmodule.com>
|
||||
* @link http://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
namespace D3\DataWizard\Application\Model\Exports;
|
||||
|
||||
use D3\DataWizard\Application\Model\ExportBase;
|
||||
use OxidEsales\Eshop\Application\Model\Order;
|
||||
use OxidEsales\Eshop\Core\Registry;
|
||||
|
||||
class KeyFigures extends ExportBase
|
||||
{
|
||||
/**
|
||||
* Shopkennzahlen
|
||||
*/
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle() : string
|
||||
{
|
||||
return Registry::getLang()->translateString('D3_DATAWIZARD_EXPORTS_KEYFIGURES');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getQuery() : array
|
||||
{
|
||||
$orderTable = oxNew(Order::class)->getCoreTableName();
|
||||
$ordersTitle = Registry::getLang()->translateString('D3_DATAWIZARD_EXPORTS_KEYFIGURES_ORDERSPERMONTH');
|
||||
$basketsTitle = Registry::getLang()->translateString('D3_DATAWIZARD_EXPORTS_KEYFIGURES_BASKETSIZE');
|
||||
$monthTitle = Registry::getLang()->translateString('D3_DATAWIZARD_EXPORTS_KEYFIGURES_MONTH');
|
||||
|
||||
return [
|
||||
'SELECT
|
||||
DATE_FORMAT(oo.oxorderdate, "%Y-%m") as :monthTitle,
|
||||
FORMAT(COUNT(oo.oxid), 0) AS :ordersTitle,
|
||||
FORMAT(SUM(oo.OXTOTALBRUTSUM / oo.oxcurrate) / COUNT(oo.oxid), 2) as :basketsTitle
|
||||
FROM '.$orderTable.' AS oo
|
||||
GROUP BY :monthTitle
|
||||
ORDER BY :monthTitle DESC
|
||||
LIMIT 30',
|
||||
[
|
||||
'monthTitle' => $monthTitle,
|
||||
'ordersTitle' => $ordersTitle,
|
||||
'basketsTitle' => $basketsTitle
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
[{include file="headitem.tpl" title="GENERAL_ADMIN_TITLE"|oxmultilangassign}]
|
||||
|
||||
[{oxstyle include="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"}]
|
||||
[{oxscript include="https://code.jquery.com/jquery-3.2.1.slim.min.js"}]
|
||||
[{oxscript include="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"}]
|
||||
[{oxscript include="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"}]
|
||||
[{oxstyle 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: 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);
|
||||
}
|
||||
h4 .btn {
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
h5.card-header {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
[{capture name="d3script"}][{strip}]
|
||||
function startAction(id) {
|
||||
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('actionid').value = id;
|
||||
document.getElementById('myedit').submit();
|
||||
}
|
||||
[{/strip}][{/capture}]
|
||||
[{oxscript add=$smarty.capture.d3script}]
|
||||
|
||||
<form name="myedit" id="myedit" action="[{$oViewConf->getSelfLink()}]" method="post" style="padding: 0;margin: 0;height:0;">
|
||||
[{$oViewConf->getHiddenSid()}]
|
||||
<input type="hidden" name="cl" value="[{$oViewConf->getActiveClassName()}]">
|
||||
<input type="hidden" name="fnc" value="doAction">
|
||||
<input type="hidden" name="actionid" id="actionid" value="">
|
||||
|
||||
[{assign var="groups" value=$oView->getGroups()}]
|
||||
[{if $groups|@count}]
|
||||
<div id="accordion">
|
||||
[{foreach from=$oView->getGroups() item="group"}]
|
||||
<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}]">
|
||||
[{oxmultilang 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">
|
||||
[{foreach from=$oView->getGroupActions($group) key="id" item="action"}]
|
||||
<div class="col-sm-6 col-md-4 col-lg-3 pb-4">
|
||||
<div class="card">
|
||||
<h5 class="card-header">
|
||||
[{$action->getTitle()}]
|
||||
</h5>
|
||||
<div class="card-body">
|
||||
<p class="card-text">
|
||||
[{$action->getDescription()}]
|
||||
</p>
|
||||
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-primary" onclick="startAction('[{$id}]')">
|
||||
<i class="fas fa-magic"></i>
|
||||
[{oxmultilang ident=$action->getButtonText()}]
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
[{/foreach}]
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
[{/foreach}]
|
||||
</div>
|
||||
[{else}]
|
||||
<div class="alert alert-primary" role="alert">
|
||||
[{oxmultilang ident="D3_DATAWIZARD_ERR_NOACTION_INSTALLED"}]
|
||||
</div>
|
||||
[{/if}]
|
||||
</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 file="d3_cfg_mod_inc.tpl"}]
|
|
@ -1,133 +0,0 @@
|
|||
[{include file="headitem.tpl" title="GENERAL_ADMIN_TITLE"|oxmultilangassign}]
|
||||
|
||||
[{oxstyle include="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"}]
|
||||
[{oxscript include="https://code.jquery.com/jquery-3.2.1.slim.min.js"}]
|
||||
[{oxscript include="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"}]
|
||||
[{oxscript include="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"}]
|
||||
[{oxstyle 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: 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));
|
||||
}
|
||||
h4 .btn {
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
h5.card-header {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
[{capture name="d3script"}][{strip}]
|
||||
function startExport(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('exportid').value = id;
|
||||
document.getElementById('exportformat').value = format;
|
||||
document.getElementById('myedit').submit();
|
||||
}
|
||||
[{/strip}][{/capture}]
|
||||
[{oxscript add=$smarty.capture.d3script}]
|
||||
|
||||
<form name="myedit" id="myedit" action="[{$oViewConf->getSelfLink()}]" method="post" style="padding: 0;margin: 0;height:0;">
|
||||
[{$oViewConf->getHiddenSid()}]
|
||||
<input type="hidden" name="cl" value="[{$oViewConf->getActiveClassName()}]">
|
||||
<input type="hidden" name="fnc" value="doExport">
|
||||
<input type="hidden" name="exportid" id="exportid" value="">
|
||||
<input type="hidden" name="exportformat" id="exportformat" value="CSV">
|
||||
|
||||
[{assign var="groups" value=$oView->getGroups()}]
|
||||
[{if $groups|@count}]
|
||||
<div id="accordion">
|
||||
[{foreach from=$oView->getGroups() item="group"}]
|
||||
<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}]">
|
||||
[{oxmultilang 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">
|
||||
[{foreach from=$oView->getGroupExports($group) key="id" item="export"}]
|
||||
<div class="col-sm-6 col-md-4 col-lg-3 pb-4">
|
||||
<div class="card">
|
||||
<h5 class="card-header">
|
||||
[{$export->getTitle()}]
|
||||
</h5>
|
||||
<div class="card-body">
|
||||
<p class="card-text">
|
||||
[{$export->getDescription()}]
|
||||
</p>
|
||||
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-primary" onclick="startExport('[{$id}]', 'CSV')">
|
||||
<i class="fas fa-magic"></i>
|
||||
[{oxmultilang ident=$export->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-magic"></i>
|
||||
[{oxmultilang ident=$export->getButtonText()}]
|
||||
</span>
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
[{block name="dataWizardExportFormat"}]
|
||||
<button class="dropdown-item" onclick="startExport('[{$id}]', 'CSV')">
|
||||
[{oxmultilang ident="D3_DATAWIZARD_EXPORT_FORMAT_CSV"}]
|
||||
</button>
|
||||
<button class="dropdown-item" onclick="startExport('[{$id}]', 'Pretty')">
|
||||
[{oxmultilang ident="D3_DATAWIZARD_EXPORT_FORMAT_PRETTY"}]
|
||||
</button>
|
||||
[{/block}]
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
[{/foreach}]
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
[{/foreach}]
|
||||
</div>
|
||||
[{else}]
|
||||
<div class="alert alert-primary" role="alert">
|
||||
[{oxmultilang ident="D3_DATAWIZARD_ERR_NOEXPORT_INSTALLED"}]
|
||||
</div>
|
||||
[{/if}]
|
||||
</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 file="d3_cfg_mod_inc.tpl"}]
|
|
@ -0,0 +1,2 @@
|
|||
reports
|
||||
.phpunit.result.cache
|
|
@ -0,0 +1,15 @@
|
|||
# D3 Datawizard Tests
|
||||
|
||||
## Requirements
|
||||
|
||||
Please install the packages listed in the composer.json in "require-dev". Unfortunately Composer does not provide an automatic installation.
|
||||
missing ext-sockets
|
||||
|
||||
### Configuration
|
||||
|
||||
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
|
||||
|
||||
commands are described in composer.json scripts section
|
|
@ -0,0 +1,41 @@
|
|||
<?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
|
||||
*/
|
||||
|
||||
// Include datawizard test config
|
||||
|
||||
namespace D3\DataWizard\tests;
|
||||
|
||||
use D3\ModCfg\Tests\additional_abstract;
|
||||
use Exception;
|
||||
use OxidEsales\Eshop\Core\Exception\StandardException;
|
||||
|
||||
include(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'd3datawizard_config.php');
|
||||
|
||||
class additional extends additional_abstract
|
||||
{
|
||||
/**
|
||||
* additional constructor.
|
||||
* @throws StandardException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if (D3DATAWIZARD_REQUIRE_MODCFG) {
|
||||
$this->reactivateModCfg();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
d3GetOxidDIC()->get(additional::class);
|
||||
} catch (Exception) {
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<?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
|
||||
*/
|
||||
|
||||
const D3DATAWIZARD_REQUIRE_MODCFG = true;
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace D3\DataWizard\tests\tools;
|
||||
|
||||
use D3\DataWizard\Application\Model\ActionBase;
|
||||
|
||||
class d3TestAction extends ActionBase
|
||||
{
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'TestTitle';
|
||||
}
|
||||
|
||||
public function getQuery(): array
|
||||
{
|
||||
return ["UPDATE 1"];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace D3\DataWizard\tests\tools;
|
||||
|
||||
use D3\DataWizard\Application\Model\ExportBase;
|
||||
|
||||
class d3TestExport extends ExportBase
|
||||
{
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'TestTitle';
|
||||
}
|
||||
|
||||
public function getQuery(): array
|
||||
{
|
||||
return ["SELECT 1"];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,199 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* https://www.d3data.de
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
|
||||
* @link https://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\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 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 d3AdminController
|
||||
{
|
||||
/** @var d3ActionWizard */
|
||||
protected $_oController;
|
||||
|
||||
protected $testClassName = d3ActionWizard::class;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->_oController = oxNew($this->testClassName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Controller\Admin\d3ActionWizard::getGroups()
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetGroups()
|
||||
{
|
||||
$expected = ['expected' => 'array'];
|
||||
/** @var Configuration|MockObject $configurationMock */
|
||||
$configurationMock = $this->getMockBuilder(Configuration::class)
|
||||
->onlyMethods(['getActionGroups'])
|
||||
->getMock();
|
||||
$configurationMock->expects($this->atLeastOnce())->method('getActionGroups')->willReturn($expected);
|
||||
|
||||
$this->setValue($this->_oController, 'configuration', $configurationMock);
|
||||
|
||||
$this->assertSame(
|
||||
$expected,
|
||||
$this->callMethod(
|
||||
$this->_oController,
|
||||
'getGroups'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Controller\Admin\d3ActionWizard::getGroupTasks()
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
* @dataProvider canGetGroupTasksDataProvider
|
||||
*/
|
||||
public function canGetGroupTasks($argument)
|
||||
{
|
||||
$expected = ['expected' => 'array'];
|
||||
/** @var Configuration|MockObject $configurationMock */
|
||||
$configurationMock = $this->getMockBuilder(Configuration::class)
|
||||
->onlyMethods(['getActionsByGroup'])
|
||||
->getMock();
|
||||
$configurationMock->expects($this->atLeastOnce())->method('getActionsByGroup')->with($argument)->willReturn($expected);
|
||||
|
||||
$this->setValue($this->_oController, 'configuration', $configurationMock);
|
||||
|
||||
$this->assertSame(
|
||||
$expected,
|
||||
$this->callMethod(
|
||||
$this->_oController,
|
||||
'getGroupTasks',
|
||||
[$argument]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function canGetGroupTasksDataProvider(): array
|
||||
{
|
||||
return [
|
||||
['test1'],
|
||||
['test2'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Controller\Admin\d3ActionWizard::execute()
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
* @dataProvider executePassDataProvider
|
||||
*/
|
||||
public function executePass($blDebug)
|
||||
{
|
||||
/** @var Request|MockObject $requestMock */
|
||||
$requestMock = $this->getMockBuilder(get_class(Registry::getRequest()))
|
||||
->onlyMethods(['getRequestEscapedParameter'])
|
||||
->getMock();
|
||||
$requestMock->expects($this->any())->method('getRequestEscapedParameter')->willReturnCallback([$this, 'executePassRequestCallback']);
|
||||
Registry::set(Request::class, $requestMock);
|
||||
|
||||
/** @var ModuleSettingService $settingsServiceMock */
|
||||
$settingsServiceMock = $this->getMockBuilder(ModuleSettingService::class)
|
||||
->disableOriginalConstructor()
|
||||
->onlyMethods(['getBoolean'])
|
||||
->getMock();
|
||||
$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(['getSettingsService'])
|
||||
->getMock();
|
||||
$controllerMock->method('getSettingsService')->willReturn($settingsServiceMock);
|
||||
$this->_oController = $controllerMock;
|
||||
|
||||
/** @var d3TestAction|MockObject $actionMock */
|
||||
$actionMock = $this->getMockBuilder(d3TestAction::class)
|
||||
->onlyMethods([
|
||||
'getQuery',
|
||||
'run',
|
||||
])
|
||||
->getMock();
|
||||
$actionMock->expects($this->atLeastOnce())->method('getQuery')->willReturn(['SELECT 1', ['1']]);
|
||||
$actionMock->expects($this->exactly((int) !$blDebug))->method('run');
|
||||
|
||||
/** @var Configuration|MockObject $configurationMock */
|
||||
$configurationMock = $this->getMockBuilder(Configuration::class)
|
||||
->onlyMethods(['getActionById'])
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$configurationMock->expects($this->atLeastOnce())->method('getActionById')->with('testTaskId')->willReturn($actionMock);
|
||||
$this->setValue($this->_oController, 'configuration', $configurationMock);
|
||||
|
||||
if ($blDebug) {
|
||||
$this->expectException(DebugException::class);
|
||||
}
|
||||
|
||||
$this->callMethod(
|
||||
$this->_oController,
|
||||
'execute'
|
||||
);
|
||||
}
|
||||
|
||||
public function executePassRequestCallback($varName)
|
||||
{
|
||||
return match ( $varName ) {
|
||||
'taskid' => 'testTaskId',
|
||||
'format' => RendererBridge::FORMAT_CSV,
|
||||
default => oxNew( Request::class )->getRequestEscapedParameter( $varName ),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function executePassDataProvider(): array
|
||||
{
|
||||
return [
|
||||
'no debug' => [false],
|
||||
'debug' => [true],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[][]
|
||||
*/
|
||||
public function runTaskFailedDataProvider(): array
|
||||
{
|
||||
return [
|
||||
[DataWizardException::class],
|
||||
[DBALException::class],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,267 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* https://www.d3data.de
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
|
||||
* @link https://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\tests\unit\Application\Controller\Admin;
|
||||
|
||||
use D3\DataWizard\Application\Controller\Admin\d3ActionWizard;
|
||||
use D3\DataWizard\Application\Controller\Admin\d3ExportWizard;
|
||||
use D3\DataWizard\Application\Model\Configuration;
|
||||
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\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 d3AdminController extends d3ModCfgUnitTestCase
|
||||
{
|
||||
/** @var d3ActionWizard|d3ExportWizard */
|
||||
protected $_oController;
|
||||
|
||||
protected $testClassName;
|
||||
|
||||
public function tearDown(): void
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
unset($this->_oController);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Controller\Admin\d3ActionWizard::__construct
|
||||
* @covers \D3\DataWizard\Application\Controller\Admin\d3ExportWizard::__construct
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function testConstructor()
|
||||
{
|
||||
$this->setValue($this->_oController, 'configuration', oxNew(Configuration::class));
|
||||
|
||||
$this->callMethod(
|
||||
$this->_oController,
|
||||
'__construct'
|
||||
);
|
||||
|
||||
$this->assertInstanceOf(
|
||||
Configuration::class,
|
||||
$this->getValue(
|
||||
$this->_oController,
|
||||
'configuration'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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()
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function runTaskPass()
|
||||
{
|
||||
/** @var d3ActionWizard|d3ExportWizard|MockObject $controllerMock */
|
||||
$controllerMock = $this->getMockBuilder($this->testClassName)
|
||||
->onlyMethods(['execute'])
|
||||
->getMock();
|
||||
$controllerMock->expects($this->once())->method('execute');
|
||||
|
||||
$this->_oController = $controllerMock;
|
||||
|
||||
$this->callMethod(
|
||||
$this->_oController,
|
||||
'runTask'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Controller\Admin\d3ActionWizard::runTask()
|
||||
* @covers \D3\DataWizard\Application\Controller\Admin\d3ExportWizard::runTask()
|
||||
* @test
|
||||
* @param $exceptionClass
|
||||
* @throws ReflectionException
|
||||
* @dataProvider runTaskFailedDataProvider
|
||||
*/
|
||||
public function runTaskFailed($exceptionClass)
|
||||
{
|
||||
/** @var DataWizardException|DBALException|DatabaseErrorException|MockObject $exceptionMock */
|
||||
$exceptionMock = $this->getMockBuilder($exceptionClass)
|
||||
->setConstructorArgs(['exc_msg', 20, new Exception()])
|
||||
->getMock();
|
||||
|
||||
/** @var d3ActionWizard|d3ExportWizard|MockObject $controllerMock */
|
||||
$controllerMock = $this->getMockBuilder($this->testClassName)
|
||||
->onlyMethods(['execute'])
|
||||
->getMock();
|
||||
$controllerMock->expects($this->once())->method('execute')->willThrowException($exceptionMock);
|
||||
|
||||
/** @var LoggerInterface|MockObject $loggerMock */
|
||||
$loggerMock = $this->getMockBuilder(get_class(Registry::getLogger()))
|
||||
->onlyMethods(['error'])
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$loggerMock->expects($this->atLeastOnce())->method('error')->with('exc_msg')->willReturn(true);
|
||||
Registry::set('logger', $loggerMock);
|
||||
|
||||
/** @var UtilsView|MockObject $utilsViewMock */
|
||||
$utilsViewMock = $this->getMockBuilder(get_class(Registry::getUtilsView()))
|
||||
->onlyMethods(['addErrorToDisplay'])
|
||||
->getMock();
|
||||
$utilsViewMock->expects($this->atLeastOnce())->method('addErrorToDisplay')->with($exceptionMock)->willReturn(true);
|
||||
Registry::set(UtilsView::class, $utilsViewMock);
|
||||
|
||||
$this->_oController = $controllerMock;
|
||||
|
||||
$this->callMethod(
|
||||
$this->_oController,
|
||||
'runTask'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Controller\Admin\d3ActionWizard::execute()
|
||||
* @covers \D3\DataWizard\Application\Controller\Admin\d3ExportWizard::execute()
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
* @dataProvider executePassDataProvider
|
||||
*/
|
||||
public function executePass($blDebug)
|
||||
{
|
||||
/** @var Request|MockObject $requestMock */
|
||||
$requestMock = $this->getMockBuilder(get_class(Registry::getRequest()))
|
||||
->onlyMethods(['getRequestEscapedParameter'])
|
||||
->getMock();
|
||||
$requestMock->expects($this->atLeastOnce())->method('getRequestEscapedParameter')->with('taskid')->willReturn('testTaskId');
|
||||
Registry::set(Request::class, $requestMock);
|
||||
|
||||
/** @var d3TestAction|MockObject $actionMock */
|
||||
$actionMock = $this->getMockBuilder(d3TestAction::class)
|
||||
->onlyMethods([
|
||||
'getQuery',
|
||||
'run',
|
||||
])
|
||||
->getMock();
|
||||
$actionMock->expects($this->atLeastOnce())->method('getQuery')->willReturn(['SELECT 1', ['1']]);
|
||||
$actionMock->expects($this->exactly((int) !$blDebug))->method('run')->willReturn(true);
|
||||
|
||||
/** @var Configuration|MockObject $configurationMock */
|
||||
$configurationMock = $this->getMockBuilder(Configuration::class)
|
||||
->onlyMethods(['getActionById'])
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$configurationMock->expects($this->atLeastOnce())->method('getActionById')->with('testTaskId')->willReturn($actionMock);
|
||||
$this->setValue($this->_oController, 'configuration', $configurationMock);
|
||||
|
||||
/** @var Config|MockObject $configMock */
|
||||
$configMock = $this->getMockBuilder(Config::class)
|
||||
->onlyMethods(['getConfigParam'])
|
||||
->getMock();
|
||||
$configMock->expects($this->atLeastOnce())->method('getConfigParam')->willReturn($blDebug);
|
||||
Registry::set(Config::class, $configMock);
|
||||
|
||||
if ($blDebug) {
|
||||
$this->expectException(DebugException::class);
|
||||
}
|
||||
|
||||
$this->callMethod(
|
||||
$this->_oController,
|
||||
'execute'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function executePassDataProvider(): array
|
||||
{
|
||||
return [
|
||||
'no debug' => [false],
|
||||
'debug' => [true],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Controller\Admin\d3ActionWizard::getUserMessages()
|
||||
* @covers \D3\DataWizard\Application\Controller\Admin\d3ExportWizard::getUserMessages()
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetUserMessages()
|
||||
{
|
||||
$this->assertNull(
|
||||
$this->callMethod(
|
||||
$this->_oController,
|
||||
'getUserMessages'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Controller\Admin\d3ActionWizard::getHelpURL()
|
||||
* @covers \D3\DataWizard\Application\Controller\Admin\d3ExportWizard::getHelpURL()
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetHelpUrl()
|
||||
{
|
||||
$this->assertNull(
|
||||
$this->callMethod(
|
||||
$this->_oController,
|
||||
'getHelpURL'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @return void
|
||||
* @throws ReflectionException
|
||||
* @covers \D3\DataWizard\Application\Controller\Admin\d3ActionWizard::getSettingsService()
|
||||
* @covers \D3\DataWizard\Application\Controller\Admin\d3ExportWizard::getSettingsService()
|
||||
*/
|
||||
public function canGetSettingsService(): void
|
||||
{
|
||||
$this->assertInstanceOf(
|
||||
ModuleSettingService::class,
|
||||
$this->callMethod(
|
||||
$this->_oController,
|
||||
'getSettingsService'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,206 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* https://www.d3data.de
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
|
||||
* @link https://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\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 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 d3AdminController
|
||||
{
|
||||
/** @var d3ExportWizard */
|
||||
protected $_oController;
|
||||
|
||||
protected $testClassName = d3ExportWizard::class;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->_oController = oxNew($this->testClassName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Controller\Admin\d3ExportWizard::getGroups()
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetGroups()
|
||||
{
|
||||
$expected = ['expected' => 'array'];
|
||||
/** @var Configuration|MockObject $configurationMock */
|
||||
$configurationMock = $this->getMockBuilder(Configuration::class)
|
||||
->onlyMethods(['getExportGroups'])
|
||||
->getMock();
|
||||
$configurationMock->expects($this->atLeastOnce())->method('getExportGroups')->willReturn($expected);
|
||||
|
||||
$this->setValue($this->_oController, 'configuration', $configurationMock);
|
||||
|
||||
$this->assertSame(
|
||||
$expected,
|
||||
$this->callMethod(
|
||||
$this->_oController,
|
||||
'getGroups'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Controller\Admin\d3ExportWizard::getGroupTasks()
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
* @dataProvider canGetGroupTasksDataProvider
|
||||
*/
|
||||
public function canGetGroupTasks($argument)
|
||||
{
|
||||
$expected = ['expected' => 'array'];
|
||||
/** @var Configuration|MockObject $configurationMock */
|
||||
$configurationMock = $this->getMockBuilder(Configuration::class)
|
||||
->onlyMethods(['getExportsByGroup'])
|
||||
->getMock();
|
||||
$configurationMock->expects($this->atLeastOnce())->method('getExportsByGroup')->with($argument)->willReturn($expected);
|
||||
|
||||
$this->setValue($this->_oController, 'configuration', $configurationMock);
|
||||
|
||||
$this->assertSame(
|
||||
$expected,
|
||||
$this->callMethod(
|
||||
$this->_oController,
|
||||
'getGroupTasks',
|
||||
[$argument]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function canGetGroupTasksDataProvider(): array
|
||||
{
|
||||
return [
|
||||
['test1'],
|
||||
['test2'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Controller\Admin\d3ExportWizard::execute()
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
* @dataProvider executePassDataProvider
|
||||
*/
|
||||
public function executePass($blDebug)
|
||||
{
|
||||
/** @var Request|MockObject $requestMock */
|
||||
$requestMock = $this->getMockBuilder(get_class(Registry::getRequest()))
|
||||
->onlyMethods(['getRequestEscapedParameter'])
|
||||
->getMock();
|
||||
$requestMock->expects($this->any())->method('getRequestEscapedParameter')->willReturnCallback([$this, 'executePassRequestCallback']);
|
||||
//OnConsecutiveCalls('testTaskId', 'CSV');
|
||||
Registry::set(Request::class, $requestMock);
|
||||
|
||||
/** @var ModuleSettingService $settingsServiceMock */
|
||||
$settingsServiceMock = $this->getMockBuilder(ModuleSettingService::class)
|
||||
->disableOriginalConstructor()
|
||||
->onlyMethods(['getBoolean'])
|
||||
->getMock();
|
||||
$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(['getSettingsService'])
|
||||
->getMock();
|
||||
$controllerMock->method('getSettingsService')->willReturn($settingsServiceMock);
|
||||
$this->_oController = $controllerMock;
|
||||
|
||||
/** @var d3TestAction|MockObject $exportMock */
|
||||
$exportMock = $this->getMockBuilder(d3TestExport::class)
|
||||
->onlyMethods([
|
||||
'getQuery',
|
||||
'run',
|
||||
])
|
||||
->getMock();
|
||||
$exportMock->expects($this->atLeastOnce())->method('getQuery')->willReturn(['SELECT 1', ['1']]);
|
||||
$exportMock->expects($this->exactly((int) !$blDebug))->method('run')->willReturn('');
|
||||
|
||||
/** @var Configuration|MockObject $configurationMock */
|
||||
$configurationMock = $this->getMockBuilder(Configuration::class)
|
||||
->onlyMethods(['getExportById'])
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$configurationMock->expects($this->atLeastOnce())->method('getExportById')->with('testTaskId')->willReturn($exportMock);
|
||||
$this->setValue($this->_oController, 'configuration', $configurationMock);
|
||||
|
||||
if ($blDebug) {
|
||||
$this->expectException(DebugException::class);
|
||||
}
|
||||
|
||||
$this->callMethod(
|
||||
$this->_oController,
|
||||
'execute'
|
||||
);
|
||||
}
|
||||
|
||||
public function executePassRequestCallback($varName)
|
||||
{
|
||||
switch ($varName) {
|
||||
case 'taskid':
|
||||
return 'testTaskId';
|
||||
case 'format':
|
||||
return RendererBridge::FORMAT_CSV;
|
||||
default:
|
||||
return oxNew(Request::class)->getRequestEscapedParameter($varName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function executePassDataProvider(): array
|
||||
{
|
||||
return [
|
||||
'no debug' => [false],
|
||||
'debug' => [true],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[][]
|
||||
*/
|
||||
public function runTaskFailedDataProvider(): array
|
||||
{
|
||||
return [
|
||||
[DataWizardException::class],
|
||||
[DBALException::class],
|
||||
[DatabaseErrorException::class],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,318 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* https://www.d3data.de
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
|
||||
* @link https://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\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;
|
||||
use OxidEsales\Eshop\Core\Database\Adapter\Doctrine\Database;
|
||||
use OxidEsales\Eshop\Core\Exception\StandardException;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use ReflectionException;
|
||||
|
||||
class ActionBaseTest extends d3ModCfgUnitTestCase
|
||||
{
|
||||
/** @var d3TestAction */
|
||||
protected $_oModel;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->_oModel = oxNew(d3TestAction::class);
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
unset($this->_oModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ActionBase::getDescription
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetDescription()
|
||||
{
|
||||
$this->assertIsString(
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getDescription'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ActionBase::getButtonText
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetButtonText()
|
||||
{
|
||||
$this->assertIsString(
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getButtonText'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ActionBase::hasFormElements
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
* @dataProvider canGetHasFormElementsDataProvider
|
||||
*/
|
||||
public function canGetHasFormElements($formElements, $expected)
|
||||
{
|
||||
$this->setValue($this->_oModel, 'formElements', $formElements);
|
||||
|
||||
$this->assertSame(
|
||||
$expected,
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'hasFormElements'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function canGetHasFormElementsDataProvider(): array
|
||||
{
|
||||
return [
|
||||
'hasFormElements' => [['abc', 'def'], true],
|
||||
'hasNoFormElements' => [[], false],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ActionBase::getFormElements
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
* @dataProvider canGetHasFormElementsDataProvider
|
||||
*/
|
||||
public function canGetFormElements($formElements)
|
||||
{
|
||||
$this->setValue($this->_oModel, 'formElements', $formElements);
|
||||
|
||||
$this->assertSame(
|
||||
$formElements,
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getFormElements'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ActionBase::registerFormElement
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
* @dataProvider canRegisterFormElementDataProvider
|
||||
*/
|
||||
public function canRegisterFormElement($inputClass)
|
||||
{
|
||||
$oldCount = count($this->getValue($this->_oModel, 'formElements'));
|
||||
|
||||
/** @var Radio|MockObject $inputMock */
|
||||
$inputMock = $this->getMockBuilder($inputClass)
|
||||
->onlyMethods([
|
||||
'setTemplate',
|
||||
'setAttribute',
|
||||
])
|
||||
->getMock();
|
||||
$inputMock->expects($this->atLeastOnce())->method('setTemplate');
|
||||
$inputMock->expects($this->atLeastOnce())->method('setAttribute');
|
||||
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'registerFormElement',
|
||||
[$inputMock]
|
||||
);
|
||||
|
||||
$newCount = count($this->getValue($this->_oModel, 'formElements'));
|
||||
|
||||
$this->assertGreaterThan($oldCount, $newCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \string[][]
|
||||
*/
|
||||
public function canRegisterFormElementDataProvider(): array
|
||||
{
|
||||
return [
|
||||
'Radio' => [Radio::class],
|
||||
'Checkbox' => [Radio::class],
|
||||
'Hidden' => [Hidden::class],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ActionBase::run
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canRunWithoutFormElements()
|
||||
{
|
||||
$modelMock = $this->getMockBuilder(d3TestAction::class)
|
||||
->onlyMethods([
|
||||
'hasFormElements',
|
||||
'executeAction',
|
||||
'getQuery',
|
||||
])
|
||||
->getMock();
|
||||
$modelMock->expects($this->atLeastOnce())->method('hasFormElements')->willReturn(false);
|
||||
$modelMock->expects($this->atLeastOnce())->method('executeAction');
|
||||
$modelMock->expects($this->atLeastOnce())->method('getQuery')->willReturn([]);
|
||||
$this->_oModel = $modelMock;
|
||||
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'run'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ActionBase::run
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
* @dataProvider canRunWithFormElementsDataProvider
|
||||
*/
|
||||
public function canRunWithFormElements($elements, $blThrowException)
|
||||
{
|
||||
$expectedException = oxNew(StandardException::class);
|
||||
|
||||
$modelMock = $this->getMockBuilder(d3TestAction::class)
|
||||
->onlyMethods([
|
||||
'hasFormElements',
|
||||
'executeAction',
|
||||
'getQuery',
|
||||
'getFormElements',
|
||||
])
|
||||
->getMock();
|
||||
$modelMock->expects($this->atLeastOnce())->method('hasFormElements')->willReturn(true);
|
||||
$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;
|
||||
|
||||
if ($blThrowException) {
|
||||
$this->expectException(get_class($expectedException));
|
||||
}
|
||||
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'run'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
*/
|
||||
public function canRunWithFormElementsDataProvider(): array
|
||||
{
|
||||
/** @var Radio|MockObject $validMock */
|
||||
$validMock = $this->getMockBuilder(Radio::class)
|
||||
->onlyMethods(['isValid'])
|
||||
->getMock();
|
||||
$validMock->expects($this->atLeastOnce())->method('isValid')->willReturn(true);
|
||||
|
||||
$invalidField = new Number(null, [
|
||||
'required' => true,
|
||||
'min' => 1,
|
||||
'max' => 10,
|
||||
'step' => 5,
|
||||
]);
|
||||
$invalidField
|
||||
->setValue(20)
|
||||
->setErrorMessages(['errorMsgs']);
|
||||
|
||||
return [
|
||||
'validElements' => [[$validMock, $validMock], false],
|
||||
'invalidElements' => [[$validMock, $invalidField], true],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ActionBase::executeAction
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
* @dataProvider canExecuteActionDataProvider
|
||||
*/
|
||||
public function canExecuteAction($query, $throwsException)
|
||||
{
|
||||
/** @var Database|MockObject $connectionMock */
|
||||
$connectionMock = $this->getMockBuilder(Connection::class)
|
||||
->disableOriginalConstructor()
|
||||
->onlyMethods(['executeStatement'])
|
||||
->getMock();
|
||||
$connectionMock->expects($this->exactly((int) !$throwsException))->method('executeStatement')->willReturn(1);
|
||||
|
||||
/** @var d3TestAction|MockObject $modelMock */
|
||||
$modelMock = $this->getMockBuilder(d3TestAction::class)
|
||||
->onlyMethods(['getConnection'])
|
||||
->getMock();
|
||||
$modelMock->expects($this->exactly((int) !$throwsException))->method('getConnection')->willReturn($connectionMock);
|
||||
|
||||
$this->_oModel = $modelMock;
|
||||
|
||||
try {
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'executeAction',
|
||||
[[$query, ['parameters']]]
|
||||
);
|
||||
} catch (TaskException $e) {
|
||||
if ($throwsException) {
|
||||
$this->assertStringContainsString('keine SELECTs exportieren', $e->getMessage());
|
||||
} else {
|
||||
$this->assertStringContainsString('1 Eintrag verändert', $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
*/
|
||||
public function canExecuteActionDataProvider(): array
|
||||
{
|
||||
return [
|
||||
'Select throws exception' => ['SELECT 1', true],
|
||||
'Update dont throws exception' => ['UPDATE 1', false],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ActionBase::getConnection
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetConnection()
|
||||
{
|
||||
$this->assertInstanceOf(
|
||||
Connection::class,
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getConnection'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,455 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* https://www.d3data.de
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
|
||||
* @link https://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\tests\unit\Application\Model;
|
||||
|
||||
use D3\DataWizard\Application\Model\Configuration;
|
||||
use D3\DataWizard\Application\Model\Exceptions\DataWizardException;
|
||||
use D3\DataWizard\tests\tools\d3TestAction;
|
||||
use D3\DataWizard\tests\tools\d3TestExport;
|
||||
use D3\ModCfg\Tests\unit\d3ModCfgUnitTestCase;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use ReflectionException;
|
||||
|
||||
class ConfigurationTest extends d3ModCfgUnitTestCase
|
||||
{
|
||||
/** @var Configuration */
|
||||
protected $_oModel;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->_oModel = oxNew(Configuration::class);
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
unset($this->_oModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\Configuration::__construct
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canConstruct()
|
||||
{
|
||||
/** @var Configuration|MockObject $modelMock */
|
||||
$modelMock = $this->getMockBuilder(Configuration::class)
|
||||
->disableOriginalConstructor()
|
||||
->onlyMethods(['configure'])
|
||||
->getMock();
|
||||
$modelMock->expects($this->once())->method('configure');
|
||||
$this->_oModel = $modelMock;
|
||||
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'__construct'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\Configuration::configure()
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canConfigure()
|
||||
{
|
||||
$this->assertEmpty(
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'configure'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\Configuration::registerAction
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canRegisterAction()
|
||||
{
|
||||
$action = oxNew(d3TestAction::class);
|
||||
|
||||
$oldCount = count($this->getValue(
|
||||
$this->_oModel,
|
||||
'actions'
|
||||
));
|
||||
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'registerAction',
|
||||
['testGroup', $action]
|
||||
);
|
||||
|
||||
$actions = $this->getValue(
|
||||
$this->_oModel,
|
||||
'actions'
|
||||
);
|
||||
|
||||
$newCount = count($actions);
|
||||
|
||||
$flattedActions = $this->array_flatten($actions);
|
||||
|
||||
$this->assertGreaterThan($oldCount, $newCount);
|
||||
$this->assertContains($action, $flattedActions);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\Configuration::registerExport
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canRegisterExport()
|
||||
{
|
||||
$export = oxNew(d3TestExport::class);
|
||||
|
||||
$oldCount = count($this->getValue(
|
||||
$this->_oModel,
|
||||
'exports'
|
||||
));
|
||||
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'registerExport',
|
||||
['testGroup', $export]
|
||||
);
|
||||
|
||||
$exports = $this->getValue(
|
||||
$this->_oModel,
|
||||
'exports'
|
||||
);
|
||||
|
||||
$newCount = count($exports);
|
||||
|
||||
$flattedExports = $this->array_flatten($exports);
|
||||
|
||||
$this->assertGreaterThan($oldCount, $newCount);
|
||||
$this->assertContains($export, $flattedExports);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $array
|
||||
* @return array|false
|
||||
*/
|
||||
public function array_flatten($array)
|
||||
{
|
||||
if (!is_array($array)) {
|
||||
return false;
|
||||
}
|
||||
$result = [];
|
||||
foreach ($array as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
$result = array_merge($result, $this->array_flatten($value));
|
||||
} else {
|
||||
$result[$key] = $value;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\Configuration::getGroupedActions()
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetGroupedActions()
|
||||
{
|
||||
$actionList = ['abc', 'def'];
|
||||
|
||||
$this->setValue(
|
||||
$this->_oModel,
|
||||
'actions',
|
||||
$actionList
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
$actionList,
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getGroupedActions'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\Configuration::getGroupedExports()
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetGroupedExports()
|
||||
{
|
||||
$exportList = ['abc', 'def'];
|
||||
|
||||
$this->setValue(
|
||||
$this->_oModel,
|
||||
'exports',
|
||||
$exportList
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
$exportList,
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getGroupedExports'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\Configuration::getActionGroups()
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetActionGroups()
|
||||
{
|
||||
$actionList = ['abc' => '123', 'def' => '456'];
|
||||
|
||||
$this->setValue(
|
||||
$this->_oModel,
|
||||
'actions',
|
||||
$actionList
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
['abc', 'def'],
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getActionGroups'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\Configuration::getExportGroups()
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetExportGroups()
|
||||
{
|
||||
$exportList = ['abc' => '123', 'def' => '456'];
|
||||
|
||||
$this->setValue(
|
||||
$this->_oModel,
|
||||
'exports',
|
||||
$exportList
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
['abc', 'def'],
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getExportGroups'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\Configuration::getActionsByGroup()
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetActionsByGroup()
|
||||
{
|
||||
$actionList = ['abc' => ['123'], 'def' => ['456']];
|
||||
|
||||
$this->setValue(
|
||||
$this->_oModel,
|
||||
'actions',
|
||||
$actionList
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
['456'],
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getActionsByGroup',
|
||||
['def']
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\Configuration::getExportsByGroup()
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetExportsByGroup()
|
||||
{
|
||||
$exportList = ['abc' => ['123'], 'def' => ['456']];
|
||||
|
||||
$this->setValue(
|
||||
$this->_oModel,
|
||||
'exports',
|
||||
$exportList
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
['456'],
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getExportsByGroup',
|
||||
['def']
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\Configuration::getAllActions()
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetAllActions()
|
||||
{
|
||||
/** @var Configuration|MockObject $modelMock */
|
||||
$modelMock = $this->getMockBuilder(Configuration::class)
|
||||
->onlyMethods([
|
||||
'getActionGroups',
|
||||
'getActionsByGroup',
|
||||
])
|
||||
->getMock();
|
||||
$modelMock->expects($this->once())->method('getActionGroups')->willReturn(['123', '456']);
|
||||
$modelMock->expects($this->exactly(2))->method('getActionsByGroup')->willReturnOnConsecutiveCalls(
|
||||
['123', '456'],
|
||||
['789', '012']
|
||||
);
|
||||
|
||||
$this->_oModel = $modelMock;
|
||||
|
||||
$this->assertSame(
|
||||
['123','456', '789', '012'],
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getAllActions'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\Configuration::getAllExports()
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetAllExports()
|
||||
{
|
||||
/** @var Configuration|MockObject $modelMock */
|
||||
$modelMock = $this->getMockBuilder(Configuration::class)
|
||||
->onlyMethods([
|
||||
'getExportGroups',
|
||||
'getExportsByGroup',
|
||||
])
|
||||
->getMock();
|
||||
$modelMock->expects($this->once())->method('getExportGroups')->willReturn(['123', '456']);
|
||||
$modelMock->expects($this->exactly(2))->method('getExportsByGroup')->willReturnOnConsecutiveCalls(
|
||||
['123', '456'],
|
||||
['789', '012']
|
||||
);
|
||||
|
||||
$this->_oModel = $modelMock;
|
||||
|
||||
$this->assertSame(
|
||||
['123', '456', '789', '012'],
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getAllExports'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\Configuration::getActionById()
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
* @dataProvider canGetActionByIdDataProvider
|
||||
*/
|
||||
public function canGetActionById($id, $throwException)
|
||||
{
|
||||
$expected = oxNew(d3TestAction::class);
|
||||
|
||||
/** @var Configuration|MockObject $modelMock */
|
||||
$modelMock = $this->getMockBuilder(Configuration::class)
|
||||
->onlyMethods(['getAllActions'])
|
||||
->getMock();
|
||||
$modelMock->expects($this->once())->method('getAllActions')->willReturn(['123' => oxNew(d3TestAction::class), '456' => $expected]);
|
||||
$this->_oModel = $modelMock;
|
||||
|
||||
if ($throwException) {
|
||||
$this->expectException(DataWizardException::class);
|
||||
}
|
||||
|
||||
$return = $this->callMethod(
|
||||
$this->_oModel,
|
||||
'getActionById',
|
||||
[$id]
|
||||
);
|
||||
|
||||
if (!$throwException) {
|
||||
$this->assertSame(
|
||||
$expected,
|
||||
$return
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\Configuration::getExportById()
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
* @dataProvider canGetActionByIdDataProvider
|
||||
*/
|
||||
public function canGetExportById($id, $throwException)
|
||||
{
|
||||
$expected = oxNew(d3TestExport::class);
|
||||
|
||||
/** @var Configuration|MockObject $modelMock */
|
||||
$modelMock = $this->getMockBuilder(Configuration::class)
|
||||
->onlyMethods(['getAllExports'])
|
||||
->getMock();
|
||||
$modelMock->expects($this->once())->method('getAllExports')->willReturn(['123' => oxNew(d3TestExport::class), '456' => $expected]);
|
||||
$this->_oModel = $modelMock;
|
||||
|
||||
if ($throwException) {
|
||||
$this->expectException(DataWizardException::class);
|
||||
}
|
||||
|
||||
$return = $this->callMethod(
|
||||
$this->_oModel,
|
||||
'getExportById',
|
||||
[$id]
|
||||
);
|
||||
|
||||
if (!$throwException) {
|
||||
$this->assertSame(
|
||||
$expected,
|
||||
$return
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
*/
|
||||
public function canGetActionByIdDataProvider(): array
|
||||
{
|
||||
return [
|
||||
'unset id' => ['987', true],
|
||||
'set id' => ['456', false],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* https://www.d3data.de
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
|
||||
* @link https://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\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;
|
||||
|
||||
class DebugExceptionTest extends d3ModCfgUnitTestCase
|
||||
{
|
||||
/** @var DebugException */
|
||||
protected $_oModel;
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\Exceptions\DebugException::__construct
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canConstruct()
|
||||
{
|
||||
$code = '500';
|
||||
|
||||
$exception = oxNew(Exception::class);
|
||||
|
||||
/** @var DebugException|MockObject $modelMock */
|
||||
$modelMock = $this->getMockBuilder(DebugException::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->_oModel = $modelMock;
|
||||
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'__construct',
|
||||
['testMessage', $code, $exception]
|
||||
);
|
||||
|
||||
$this->assertStringContainsString(
|
||||
'Debug: testMessage',
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getMessage'
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
$code,
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getCode'
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
$exception,
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getPrevious'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* https://www.d3data.de
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
|
||||
* @link https://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\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;
|
||||
|
||||
class ExportFileExceptionTest extends d3ModCfgUnitTestCase
|
||||
{
|
||||
/** @var ExportFileException */
|
||||
protected $_oModel;
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\Exceptions\ExportFileException::__construct
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canConstruct()
|
||||
{
|
||||
$code = '500';
|
||||
|
||||
$exception = oxNew(Exception::class);
|
||||
|
||||
/** @var ExportFileException|MockObject $modelMock */
|
||||
$modelMock = $this->getMockBuilder(ExportFileException::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->_oModel = $modelMock;
|
||||
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'__construct',
|
||||
['testMessage', $code, $exception]
|
||||
);
|
||||
|
||||
$this->assertStringContainsString(
|
||||
'kann nicht angelegt werden',
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getMessage'
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
$code,
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getCode'
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
$exception,
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getPrevious'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* https://www.d3data.de
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
|
||||
* @link https://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\tests\unit\Application\Model\Exceptions;
|
||||
|
||||
use D3\DataWizard\Application\Model\Exceptions\InputUnvalidException;
|
||||
use D3\DataWizard\Application\Model\ExportBase;
|
||||
use D3\DataWizard\tests\tools\d3TestExport;
|
||||
use D3\ModCfg\Tests\unit\d3ModCfgUnitTestCase;
|
||||
use Exception;
|
||||
use FormManager\Inputs\Number;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use ReflectionException;
|
||||
|
||||
class InputUnvalidExceptionTest extends d3ModCfgUnitTestCase
|
||||
{
|
||||
/** @var InputUnvalidException */
|
||||
protected $_oModel;
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\Exceptions\InputUnvalidException::__construct
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canConstruct()
|
||||
{
|
||||
$code = '500';
|
||||
|
||||
$exception = oxNew(Exception::class);
|
||||
|
||||
$invalidField = new Number(null, [
|
||||
'required' => true,
|
||||
'min' => 1,
|
||||
'max' => 10,
|
||||
'step' => 5,
|
||||
]);
|
||||
$invalidField
|
||||
->setValue(20)
|
||||
->setErrorMessages(['errorMsgs']);
|
||||
|
||||
/** @var ExportBase|MockObject $taskMock */
|
||||
$taskMock = $this->getMockBuilder(d3TestExport::class)
|
||||
->onlyMethods(['getTitle'])
|
||||
->getMock();
|
||||
$taskMock->expects($this->atLeastOnce())->method('getTitle')->willReturn('testTitle');
|
||||
|
||||
/** @var InputUnvalidException|MockObject $modelMock */
|
||||
$modelMock = $this->getMockBuilder(InputUnvalidException::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->_oModel = $modelMock;
|
||||
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'__construct',
|
||||
[$taskMock, $invalidField, $code, $exception]
|
||||
);
|
||||
|
||||
$this->assertMatchesRegularExpression(
|
||||
'/^testTitle\s-\s*->\s.*\sless\s/m',
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getMessage'
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
$code,
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getCode'
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
$exception,
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getPrevious'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* https://www.d3data.de
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
|
||||
* @link https://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\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;
|
||||
|
||||
class NoSuitableRendererExceptionTest extends d3ModCfgUnitTestCase
|
||||
{
|
||||
/** @var NoSuitableRendererException */
|
||||
protected $_oModel;
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\Exceptions\NoSuitableRendererException::__construct
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canConstruct()
|
||||
{
|
||||
$code = '500';
|
||||
|
||||
$exception = oxNew(Exception::class);
|
||||
|
||||
/** @var NoSuitableRendererException|MockObject $modelMock */
|
||||
$modelMock = $this->getMockBuilder(NoSuitableRendererException::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->_oModel = $modelMock;
|
||||
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'__construct',
|
||||
['testMessage', $code, $exception]
|
||||
);
|
||||
|
||||
$this->assertStringContainsString(
|
||||
'kein Renderer f',
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getMessage'
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
$code,
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getCode'
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
$exception,
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getPrevious'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* https://www.d3data.de
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
|
||||
* @link https://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\tests\unit\Application\Model\Exceptions;
|
||||
|
||||
use D3\DataWizard\Application\Model\Exceptions\TaskException;
|
||||
use D3\DataWizard\Application\Model\ExportBase;
|
||||
use D3\DataWizard\tests\tools\d3TestExport;
|
||||
use D3\ModCfg\Tests\unit\d3ModCfgUnitTestCase;
|
||||
use Exception;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use ReflectionException;
|
||||
|
||||
class TaskExceptionTest extends d3ModCfgUnitTestCase
|
||||
{
|
||||
/** @var TaskException */
|
||||
protected $_oModel;
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\Exceptions\TaskException::__construct
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canConstruct()
|
||||
{
|
||||
$code = '500';
|
||||
|
||||
$exception = oxNew(Exception::class);
|
||||
|
||||
/** @var ExportBase|MockObject $taskMock */
|
||||
$taskMock = $this->getMockBuilder(d3TestExport::class)
|
||||
->onlyMethods(['getTitle'])
|
||||
->getMock();
|
||||
$taskMock->expects($this->atLeastOnce())->method('getTitle')->willReturn('testTitle');
|
||||
|
||||
/** @var TaskException|MockObject $modelMock */
|
||||
$modelMock = $this->getMockBuilder(TaskException::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->_oModel = $modelMock;
|
||||
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'__construct',
|
||||
[$taskMock, 'testMessage', $code, $exception]
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
'testTitle - testMessage',
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getMessage'
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
$code,
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getCode'
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
$exception,
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getPrevious'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,644 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* https://www.d3data.de
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
|
||||
* @link https://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\tests\unit\Application\Model;
|
||||
|
||||
use D3\DataWizard\Application\Model\Exceptions\ExportFileException;
|
||||
use D3\DataWizard\Application\Model\Exceptions\TaskException;
|
||||
use D3\DataWizard\Application\Model\ExportRenderer\Csv;
|
||||
use D3\DataWizard\Application\Model\ExportRenderer\RendererBridge;
|
||||
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;
|
||||
|
||||
class ExportBaseTest extends d3ModCfgUnitTestCase
|
||||
{
|
||||
/** @var d3TestExport */
|
||||
protected $_oModel;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->_oModel = oxNew(d3TestExport::class);
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
unset($this->_oModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ExportBase::getDescription
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetDescription()
|
||||
{
|
||||
$this->assertIsString(
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getDescription'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ExportBase::getButtonText
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetButtonText()
|
||||
{
|
||||
$this->assertIsString(
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getButtonText'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ExportBase::hasFormElements
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
* @dataProvider canGetHasFormElementsDataProvider
|
||||
*/
|
||||
public function canGetHasFormElements($formElements, $expected)
|
||||
{
|
||||
$this->setValue($this->_oModel, 'formElements', $formElements);
|
||||
|
||||
$this->assertSame(
|
||||
$expected,
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'hasFormElements'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function canGetHasFormElementsDataProvider(): array
|
||||
{
|
||||
return [
|
||||
'hasFormElements' => [['abc', 'def'], true],
|
||||
'hasNoFormElements' => [[], false],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ExportBase::getFormElements
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
* @dataProvider canGetHasFormElementsDataProvider
|
||||
*/
|
||||
public function canGetFormElements($formElements)
|
||||
{
|
||||
$this->setValue($this->_oModel, 'formElements', $formElements);
|
||||
|
||||
$this->assertSame(
|
||||
$formElements,
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getFormElements'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ExportBase::registerFormElement
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
* @dataProvider canRegisterFormElementDataProvider
|
||||
*/
|
||||
public function canRegisterFormElement($inputClass)
|
||||
{
|
||||
$oldCount = count($this->getValue($this->_oModel, 'formElements'));
|
||||
|
||||
/** @var Radio|MockObject $inputMock */
|
||||
$inputMock = $this->getMockBuilder($inputClass)
|
||||
->onlyMethods([
|
||||
'setTemplate',
|
||||
'setAttribute',
|
||||
])
|
||||
->getMock();
|
||||
$inputMock->expects($this->atLeastOnce())->method('setTemplate');
|
||||
$inputMock->expects($this->atLeastOnce())->method('setAttribute');
|
||||
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'registerFormElement',
|
||||
[$inputMock]
|
||||
);
|
||||
|
||||
$newCount = count($this->getValue($this->_oModel, 'formElements'));
|
||||
|
||||
$this->assertGreaterThan($oldCount, $newCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \string[][]
|
||||
*/
|
||||
public function canRegisterFormElementDataProvider(): array
|
||||
{
|
||||
return [
|
||||
'Radio' => [Radio::class],
|
||||
'Checkbox' => [Radio::class],
|
||||
'Hidden' => [Hidden::class],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ExportBase::run
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canRunWithoutFormElements()
|
||||
{
|
||||
$format = 'myFormat';
|
||||
$path = 'myPath';
|
||||
|
||||
/** @var d3TestExport|MockObject $modelMock */
|
||||
$modelMock = $this->getMockBuilder(d3TestExport::class)
|
||||
->onlyMethods([
|
||||
'hasFormElements',
|
||||
'executeExport',
|
||||
])
|
||||
->getMock();
|
||||
$modelMock->expects($this->atLeastOnce())->method('hasFormElements')->willReturn(false);
|
||||
$modelMock->expects($this->atLeastOnce())->method('executeExport')->with($format, $path)->willReturn('some content');
|
||||
$this->_oModel = $modelMock;
|
||||
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'run',
|
||||
[$format, $path]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ExportBase::run
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
* @dataProvider canRunWithFormElementsDataProvider
|
||||
*/
|
||||
public function canRunWithFormElements($elements, $blThrowException)
|
||||
{
|
||||
$format = 'myFormat';
|
||||
$path = 'myPath';
|
||||
|
||||
$expectedException = oxNew(StandardException::class);
|
||||
|
||||
$modelMock = $this->getMockBuilder(d3TestExport::class)
|
||||
->onlyMethods([
|
||||
'hasFormElements',
|
||||
'executeExport',
|
||||
'getFormElements',
|
||||
])
|
||||
->getMock();
|
||||
$modelMock->expects($this->atLeastOnce())->method('hasFormElements')->willReturn(true);
|
||||
$modelMock->expects($this->exactly((int) !$blThrowException))->method('executeExport')->with($format, $path)->willReturn('some content');
|
||||
$modelMock->expects($this->atLeastOnce())->method('getFormElements')->willReturn($elements);
|
||||
$this->_oModel = $modelMock;
|
||||
|
||||
if ($blThrowException) {
|
||||
$this->expectException(get_class($expectedException));
|
||||
}
|
||||
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'run',
|
||||
[$format, $path]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
*/
|
||||
public function canRunWithFormElementsDataProvider(): array
|
||||
{
|
||||
/** @var Radio|MockObject $validMock */
|
||||
$validMock = $this->getMockBuilder(Radio::class)
|
||||
->onlyMethods(['isValid'])
|
||||
->getMock();
|
||||
$validMock->expects($this->atLeastOnce())->method('isValid')->willReturn(true);
|
||||
|
||||
$invalidField = new Number(null, [
|
||||
'required' => true,
|
||||
'min' => 1,
|
||||
'max' => 10,
|
||||
'step' => 5,
|
||||
]);
|
||||
$invalidField
|
||||
->setValue(20)
|
||||
->setErrorMessages(['errorMsgs']);
|
||||
|
||||
return [
|
||||
'validElements' => [[$validMock, $validMock], false],
|
||||
'invalidElements' => [[$validMock, $invalidField], true],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ExportBase::executeExport
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
* @dataProvider canExecuteExportDataProvider
|
||||
*/
|
||||
public function canExecuteExport($path, $throwsException)
|
||||
{
|
||||
/** @var d3filesystem|MockObject $fsMock */
|
||||
$fsMock = $this->getMockBuilder(d3filesystem::class)
|
||||
->onlyMethods([
|
||||
'startDirectDownload',
|
||||
'filterFilename',
|
||||
'trailingslashit',
|
||||
'createFile',
|
||||
])
|
||||
->getMock();
|
||||
$fsMock->expects($this->exactly((int) !isset($path)))->method('startDirectDownload')->willReturn(true);
|
||||
$fsMock->method('filterFilename')->willReturnArgument(0);
|
||||
$fsMock->expects($this->exactly((int) isset($path)))->method('trailingslashit')->willReturnArgument(0);
|
||||
$fsMock->expects($this->exactly((int) isset($path)))->method('createFile')->willReturn((bool) !$throwsException);
|
||||
|
||||
/** @var d3TestExport|MockObject $modelMock */
|
||||
$modelMock = $this->getMockBuilder(d3TestExport::class)
|
||||
->onlyMethods([
|
||||
'getContent',
|
||||
'getFileSystem',
|
||||
'getExportFileName',
|
||||
])
|
||||
->getMock();
|
||||
$modelMock->expects($this->atLeastOnce())->method('getContent')->willReturn('some content');
|
||||
$modelMock->expects($this->atLeastOnce())->method('getFileSystem')->willReturn($fsMock);
|
||||
$modelMock->expects($this->atLeastOnce())->method('getExportFileName')->willReturn('exportFileName');
|
||||
|
||||
$this->_oModel = $modelMock;
|
||||
|
||||
if ($path && $throwsException) {
|
||||
$this->expectException(ExportFileException::class);
|
||||
}
|
||||
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'executeExport',
|
||||
['CSV', $path]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
*/
|
||||
public function canExecuteExportDataProvider(): array
|
||||
{
|
||||
return [
|
||||
'unable to create path for saving file' => ['myPath', true],
|
||||
'can create path for saving file' => ['myPath', false],
|
||||
'no path for download' => [null, false],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ExportBase::getConnection
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetConnection()
|
||||
{
|
||||
$this->assertInstanceOf(
|
||||
Connection::class,
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getConnection'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ExportBase::getFileSystem
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetFileSystem()
|
||||
{
|
||||
$this->assertInstanceOf(
|
||||
d3filesystem::class,
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getFileSystem'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ExportBase::getRenderer
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetRenderer()
|
||||
{
|
||||
/** @var RendererInterface|MockObject $rendererMock */
|
||||
$rendererMock = $this->getMockBuilder(Csv::class)
|
||||
->getMock();
|
||||
|
||||
/** @var RendererBridge|MockObject $rendererBridgeMock */
|
||||
$rendererBridgeMock = $this->getMockBuilder(RendererBridge::class)
|
||||
->onlyMethods(['getRenderer'])
|
||||
->getMock();
|
||||
$rendererBridgeMock->expects($this->atLeastOnce())->method('getRenderer')->willReturn($rendererMock);
|
||||
|
||||
/** @var d3TestExport|MockObject $modelMock */
|
||||
$modelMock = $this->getMockBuilder(d3TestExport::class)
|
||||
->onlyMethods([
|
||||
'getRendererBridge',
|
||||
])
|
||||
->getMock();
|
||||
$modelMock->expects($this->atLeastOnce())->method('getRendererBridge')->willReturn($rendererBridgeMock);
|
||||
|
||||
$this->_oModel = $modelMock;
|
||||
|
||||
$this->assertSame(
|
||||
$rendererMock,
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getRenderer',
|
||||
[RendererBridge::FORMAT_CSV]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ExportBase::getRendererBridge
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetRendererBridge()
|
||||
{
|
||||
$this->assertInstanceOf(
|
||||
RendererBridge::class,
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getRendererBridge'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ExportBase::getFileExtension
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetFileExtension()
|
||||
{
|
||||
$format = RendererBridge::FORMAT_CSV;
|
||||
$expected = 'myFileExtension';
|
||||
|
||||
/** @var RendererInterface|MockObject $rendererMock */
|
||||
$rendererMock = $this->getMockBuilder(Csv::class)
|
||||
->onlyMethods(['getFileExtension'])
|
||||
->getMock();
|
||||
$rendererMock->expects($this->atLeastOnce())->method('getFileExtension')->willReturn($expected);
|
||||
|
||||
/** @var d3TestExport|MockObject $modelMock */
|
||||
$modelMock = $this->getMockBuilder(d3TestExport::class)
|
||||
->onlyMethods([
|
||||
'getRenderer',
|
||||
])
|
||||
->getMock();
|
||||
$modelMock->expects($this->atLeastOnce())->method('getRenderer')->with($format)->willReturn($rendererMock);
|
||||
|
||||
$this->_oModel = $modelMock;
|
||||
|
||||
$this->assertSame(
|
||||
$expected,
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getFileExtension',
|
||||
[$format]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ExportBase::renderContent
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canRenderContent()
|
||||
{
|
||||
$rows = ['row1', 'row2'];
|
||||
$fieldnames = ['fieldname1', 'fieldname2'];
|
||||
$format = RendererBridge::FORMAT_CSV;
|
||||
$expected = 'myContent';
|
||||
|
||||
/** @var RendererInterface|MockObject $rendererMock */
|
||||
$rendererMock = $this->getMockBuilder(Csv::class)
|
||||
->onlyMethods(['getContent'])
|
||||
->getMock();
|
||||
$rendererMock->expects($this->atLeastOnce())->method('getContent')->with($rows, $fieldnames)->willReturn($expected);
|
||||
|
||||
/** @var d3TestExport|MockObject $modelMock */
|
||||
$modelMock = $this->getMockBuilder(d3TestExport::class)
|
||||
->onlyMethods([
|
||||
'getRenderer',
|
||||
])
|
||||
->getMock();
|
||||
$modelMock->expects($this->atLeastOnce())->method('getRenderer')->with($format)->willReturn($rendererMock);
|
||||
|
||||
$this->_oModel = $modelMock;
|
||||
|
||||
$this->assertSame(
|
||||
$expected,
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'renderContent',
|
||||
[$rows, $fieldnames, $format]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ExportBase::getExportFilenameBase
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetExportFilenameBase()
|
||||
{
|
||||
/** @var d3TestExport|MockObject $modelMock */
|
||||
$modelMock = $this->getMockBuilder(d3TestExport::class)
|
||||
->onlyMethods([
|
||||
'getTitle',
|
||||
])
|
||||
->getMock();
|
||||
$modelMock->expects($this->atLeastOnce())->method('getTitle')->willReturn('someTitle');
|
||||
|
||||
$this->_oModel = $modelMock;
|
||||
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getExportFilenameBase'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ExportBase::getExportFileName
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetExportFileName()
|
||||
{
|
||||
$format = RendererBridge::FORMAT_CSV;
|
||||
|
||||
/** @var d3TestExport|MockObject $modelMock */
|
||||
$modelMock = $this->getMockBuilder(d3TestExport::class)
|
||||
->onlyMethods([
|
||||
'getExportFilenameBase',
|
||||
'getFileExtension',
|
||||
])
|
||||
->getMock();
|
||||
$modelMock->expects($this->atLeastOnce())->method('getExportFilenameBase')->willReturn('base');
|
||||
$modelMock->expects($this->atLeastOnce())->method('getFileExtension')->with($format)->willReturn('extension');
|
||||
|
||||
$this->_oModel = $modelMock;
|
||||
|
||||
$this->assertMatchesRegularExpression(
|
||||
'/^base_(\d{4})-(\d{2})-(\d{2})_(\d{2})-(\d{2})-(\d{2})\.extension$/m',
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getExportFileName',
|
||||
[$format]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ExportBase::getExportData
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
* @dataProvider canGetExportDataDataProvider
|
||||
*/
|
||||
public function canGetExportData($query, $throwsException, $dbResult)
|
||||
{
|
||||
/** @var Result|MockObject $resultMock */
|
||||
$resultMock = $this->getMockBuilder(Result::class)
|
||||
->onlyMethods(get_class_methods(Result::class))
|
||||
->getMock();
|
||||
$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([
|
||||
'getConnection',
|
||||
])
|
||||
->getMock();
|
||||
$modelMock->expects($this->exactly((int) !$throwsException))->method('getConnection')->willReturn($connectionMock);
|
||||
|
||||
$this->_oModel = $modelMock;
|
||||
|
||||
try {
|
||||
$result = $this->callMethod(
|
||||
$this->_oModel,
|
||||
'getExportData',
|
||||
[[$query, ['param1', 'param2']]]
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
[
|
||||
[
|
||||
[
|
||||
'field1' => 'content1',
|
||||
'field2' => 'content2',
|
||||
],
|
||||
],
|
||||
[
|
||||
'field1',
|
||||
'field2',
|
||||
],
|
||||
],
|
||||
$result
|
||||
);
|
||||
} catch (TaskException $e) {
|
||||
if ($throwsException) {
|
||||
$this->assertStringContainsString('Export kann nicht ausgefĂĽhrt werden', $e->getMessage());
|
||||
} elseif (!count($dbResult)) {
|
||||
$this->assertStringContainsString('kein Inhalt', $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
*/
|
||||
public function canGetExportDataDataProvider(): array
|
||||
{
|
||||
return [
|
||||
'not SELECT throws exception' => [' UPDATE 1', true, []],
|
||||
'empty SELECT' => [' SELECT 1', false, []],
|
||||
'fulfilled SELECT' => [' SELECT 1', false, [['field1' => 'content1', 'field2' => 'content2']]],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ExportBase::getContent
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetContent()
|
||||
{
|
||||
/** @var d3TestExport|MockObject $modelMock */
|
||||
$modelMock = $this->getMockBuilder(d3TestExport::class)
|
||||
->onlyMethods([
|
||||
'getQuery',
|
||||
'getExportData',
|
||||
'renderContent',
|
||||
])
|
||||
->getMock();
|
||||
$modelMock->expects($this->atLeastOnce())->method('getQuery')->willReturn(['SELECT 1', ['arg1', 'arg2']]);
|
||||
$modelMock->expects($this->atLeastOnce())->method('getExportData')->willReturn([[1, 2], ['field1', 'field2']]);
|
||||
$modelMock->expects($this->atLeastOnce())->method('renderContent')->willReturn('some content');
|
||||
|
||||
$this->_oModel = $modelMock;
|
||||
|
||||
$this->assertSame(
|
||||
'some content',
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getContent',
|
||||
['CSV']
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,203 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* https://www.d3data.de
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
|
||||
* @link https://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\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;
|
||||
use OxidEsales\Eshop\Core\Registry;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use ReflectionException;
|
||||
|
||||
class CsvTest extends ExportRendererTest
|
||||
{
|
||||
/** @var Csv */
|
||||
protected $_oModel;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$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
|
||||
* @throws ReflectionException
|
||||
* @dataProvider canGetContentDataProvider
|
||||
*/
|
||||
public function canGetContent($blThrowException)
|
||||
{
|
||||
$expected = 'expectedReturn';
|
||||
$fieldList = ['field1', 'field2'];
|
||||
$valueList = ['value1', 'value2'];
|
||||
|
||||
/** @var Writer|MockObject $csvMock */
|
||||
$csvMockBuilder = $this->getMockBuilder(Writer::class);
|
||||
$csvMockBuilder->disableOriginalConstructor();
|
||||
$onlyMethods = ['__toString', 'insertOne', 'insertAll'];
|
||||
$csvMockBuilder->onlyMethods($onlyMethods);
|
||||
$csvMock = $csvMockBuilder->getMock();
|
||||
|
||||
$csvMock->method('insertOne')->willReturn(1);
|
||||
$csvMock->method('insertAll')->willReturn(1);
|
||||
|
||||
if ($blThrowException) {
|
||||
$csvMock->expects($this->atLeastOnce())->method('__toString')->willThrowException(oxNew(Exception::class));
|
||||
$this->expectException(RenderException::class);
|
||||
} else {
|
||||
$csvMock->expects($this->atLeastOnce())->method('__toString')->willReturn($expected);
|
||||
}
|
||||
|
||||
/** @var Csv|MockObject $modelMock */
|
||||
$modelMock = $this->getMockBuilder(Csv::class)
|
||||
->onlyMethods(['getCsv'])
|
||||
->getMock();
|
||||
$modelMock->expects($this->atLeastOnce())->method('getCsv')->willReturn($csvMock);
|
||||
$this->_oModel = $modelMock;
|
||||
|
||||
$this->assertSame(
|
||||
$expected,
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getContent',
|
||||
[$valueList, $fieldList]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function canGetContentDataProvider(): array
|
||||
{
|
||||
return [
|
||||
'exception' => [true],
|
||||
'no exception' => [false],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ExportRenderer\Csv::getCsv
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetCsv()
|
||||
{
|
||||
$this->assertInstanceOf(
|
||||
Writer::class,
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getCsv'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ExportRenderer\Csv::getCsv
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetCsvNoSettings()
|
||||
{
|
||||
/** @var Config|MockObject $configMock */
|
||||
$configMock = $this->getMockBuilder(Config::class)
|
||||
->onlyMethods(['getConfigParam'])
|
||||
->getMock();
|
||||
$configMock->expects($this->atLeastOnce())->method('getConfigParam')->willReturnCallback(
|
||||
function ($argName) {
|
||||
return match ( $argName ) {
|
||||
'sGiCsvFieldEncloser', 'sCSVSign' => null,
|
||||
default => Registry::getConfig()->getConfigParam( $argName ),
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
$modelMock = $this->getMockBuilder(Csv::class)
|
||||
->onlyMethods(['d3GetConfig'])
|
||||
->getMock();
|
||||
$modelMock->method('d3GetConfig')->willReturn($configMock);
|
||||
$this->_oModel = $modelMock;
|
||||
|
||||
$csv = $this->callMethod(
|
||||
$this->_oModel,
|
||||
'getCsv'
|
||||
);
|
||||
|
||||
$this->assertInstanceOf(
|
||||
Writer::class,
|
||||
$csv
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
'"',
|
||||
$csv->getEnclosure()
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
';',
|
||||
$csv->getDelimiter()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ExportRenderer\Csv::d3GetConfig
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetConfig()
|
||||
{
|
||||
$this->assertInstanceOf(
|
||||
Config::class,
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'd3GetConfig'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
<?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
|
||||
*/
|
||||
|
||||
namespace D3\DataWizard\tests\unit\Application\Model\ExportRenderer;
|
||||
|
||||
use D3\DataWizard\Application\Model\ExportRenderer\RendererInterface;
|
||||
use D3\ModCfg\Tests\unit\d3ModCfgUnitTestCase;
|
||||
use ReflectionException;
|
||||
|
||||
abstract class ExportRendererTest extends d3ModCfgUnitTestCase
|
||||
{
|
||||
/** @var RendererInterface */
|
||||
protected $_oModel;
|
||||
|
||||
public function tearDown(): void
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
unset($this->_oModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ExportRenderer\Csv::getFileExtension
|
||||
* @covers \D3\DataWizard\Application\Model\ExportRenderer\Json::getFileExtension
|
||||
* @covers \D3\DataWizard\Application\Model\ExportRenderer\Pretty::getFileExtension
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetFileExtension()
|
||||
{
|
||||
$this->assertMatchesRegularExpression(
|
||||
"/^[a-z0-9._-]*$/i",
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getFileExtension'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ExportRenderer\Csv::getTitleTranslationId
|
||||
* @covers \D3\DataWizard\Application\Model\ExportRenderer\Json::getTitleTranslationId
|
||||
* @covers \D3\DataWizard\Application\Model\ExportRenderer\Pretty::getTitleTranslationId
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetTitleTranslationId()
|
||||
{
|
||||
$this->assertIsString(
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getTitleTranslationId'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* https://www.d3data.de
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
|
||||
* @link https://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\tests\unit\Application\Model\ExportRenderer;
|
||||
|
||||
use D3\DataWizard\Application\Model\Exceptions\RenderException;
|
||||
use D3\DataWizard\Application\Model\ExportRenderer\Json;
|
||||
use ReflectionException;
|
||||
|
||||
class JsonTest extends ExportRendererTest
|
||||
{
|
||||
/** @var Json */
|
||||
protected $_oModel;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->_oModel = oxNew(Json::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ExportRenderer\Json::getContent
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
* @dataProvider canGetContentDataProvider
|
||||
*/
|
||||
public function canGetContent($valueList, $expectException)
|
||||
{
|
||||
$fieldList = ['field1', 'field2'];
|
||||
|
||||
if ($expectException) {
|
||||
$this->expectException(RenderException::class);
|
||||
}
|
||||
|
||||
$this->assertJson(
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getContent',
|
||||
[$valueList, $fieldList]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[][]
|
||||
*/
|
||||
public function canGetContentDataProvider(): array
|
||||
{
|
||||
return [
|
||||
'valid' => [['value1', "value2"], false],
|
||||
'invalid' => [["text" => "\xB1\x31"], true], // malformed UTF8 chars
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* https://www.d3data.de
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
|
||||
* @link https://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\tests\unit\Application\Model\ExportRenderer;
|
||||
|
||||
use D3\DataWizard\Application\Model\ExportRenderer\Pretty;
|
||||
use MathieuViossat\Util\ArrayToTextTable;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use ReflectionException;
|
||||
|
||||
class PrettyTest extends ExportRendererTest
|
||||
{
|
||||
/** @var Pretty */
|
||||
protected $_oModel;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->_oModel = oxNew(Pretty::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ExportRenderer\Pretty::getContent
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetContent()
|
||||
{
|
||||
$expected = 'expectedReturn';
|
||||
$fieldList = ['field1', 'field2'];
|
||||
$valueList = ['value1', 'value2'];
|
||||
|
||||
/** @var ArrayToTextTable|MockObject $csvMock */
|
||||
$arrayToTextTableMock = $this->getMockBuilder(ArrayToTextTable::class)
|
||||
->disableOriginalConstructor()
|
||||
->onlyMethods(['getTable'])
|
||||
->getMock();
|
||||
$arrayToTextTableMock->expects($this->atLeastOnce())->method('getTable')->willReturn($expected);
|
||||
|
||||
/** @var Pretty|MockObject $modelMock */
|
||||
$modelMock = $this->getMockBuilder(Pretty::class)
|
||||
->onlyMethods(['getArrayToTextTableInstance'])
|
||||
->getMock();
|
||||
$modelMock->expects($this->atLeastOnce())->method('getArrayToTextTableInstance')->willReturn($arrayToTextTableMock);
|
||||
$this->_oModel = $modelMock;
|
||||
|
||||
$this->assertSame(
|
||||
$expected,
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getContent',
|
||||
[$valueList, $fieldList]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ExportRenderer\Pretty::getArrayToTextTableInstance
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetArrayToTextTableInstance()
|
||||
{
|
||||
$this->assertInstanceOf(
|
||||
ArrayToTextTable::class,
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getArrayToTextTableInstance',
|
||||
[['field1', 'field2']]
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* https://www.d3data.de
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
|
||||
* @link https://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace D3\DataWizard\tests\unit\Application\Model\ExportRenderer;
|
||||
|
||||
use D3\DataWizard\Application\Model\Exceptions\NoSuitableRendererException;
|
||||
use D3\DataWizard\Application\Model\ExportRenderer\Csv;
|
||||
use D3\DataWizard\Application\Model\ExportRenderer\Json;
|
||||
use D3\DataWizard\Application\Model\ExportRenderer\Pretty;
|
||||
use D3\DataWizard\Application\Model\ExportRenderer\RendererBridge;
|
||||
use D3\DataWizard\Application\Model\ExportRenderer\RendererInterface;
|
||||
use D3\ModCfg\Tests\unit\d3ModCfgUnitTestCase;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use ReflectionException;
|
||||
|
||||
class RendererBridgeTest extends d3ModCfgUnitTestCase
|
||||
{
|
||||
/** @var RendererBridge */
|
||||
protected $_oModel;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->_oModel = oxNew(RendererBridge::class);
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
unset($this->_oModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ExportRenderer\RendererBridge::getRendererList
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetRendererList()
|
||||
{
|
||||
$list = $this->callMethod(
|
||||
$this->_oModel,
|
||||
'getRendererList'
|
||||
);
|
||||
|
||||
$this->assertIsArray($list);
|
||||
$this->assertTrue((bool) count($list));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ExportRenderer\RendererBridge::getTranslatedRendererIdList
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canGetTranslatedRendererIdList()
|
||||
{
|
||||
$utlist = $this->callMethod(
|
||||
$this->_oModel,
|
||||
'getRendererList'
|
||||
);
|
||||
|
||||
$list = $this->callMethod(
|
||||
$this->_oModel,
|
||||
'getTranslatedRendererIdList'
|
||||
);
|
||||
|
||||
$this->assertIsArray($list);
|
||||
$this->assertTrue((bool) count($list));
|
||||
$this->assertSame(count($utlist), count($list));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ExportRenderer\RendererBridge::translateRendererId
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function canTranslateRendererId()
|
||||
{
|
||||
$expected = "expectedTranslation";
|
||||
|
||||
/** @var RendererInterface|MockObject $renderMock */
|
||||
$renderMock = $this->getMockBuilder(Pretty::class)
|
||||
->onlyMethods(['getTitleTranslationId'])
|
||||
->getMock();
|
||||
$renderMock->expects($this->atLeastOnce())->method('getTitleTranslationId')->willReturn($expected);
|
||||
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'translateRendererId',
|
||||
[$renderMock]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \D3\DataWizard\Application\Model\ExportRenderer\RendererBridge::getRenderer
|
||||
* @test
|
||||
* @param $format
|
||||
* @param $blThrowException
|
||||
* @throws ReflectionException
|
||||
* @dataProvider canGetRendererDataProvider
|
||||
*/
|
||||
public function canGetRenderer($format, $blThrowException)
|
||||
{
|
||||
/** @var RendererBridge|MockObject $modelMock */
|
||||
$modelMock = $this->getMockBuilder(RendererBridge::class)
|
||||
->onlyMethods(['getRendererList'])
|
||||
->getMock();
|
||||
$modelMock->expects($this->atLeastOnce())->method('getRendererList')->willReturn(
|
||||
[
|
||||
'CSV' => $this->getMockBuilder(Csv::class)->getMock(),
|
||||
'Pretty' => $this->getMockBuilder(Pretty::class)->getMock(),
|
||||
'JSON' => $this->getMockBuilder(Json::class)->getMock(),
|
||||
]
|
||||
);
|
||||
|
||||
$this->_oModel = $modelMock;
|
||||
|
||||
if ($blThrowException) {
|
||||
$this->expectException(NoSuitableRendererException::class);
|
||||
}
|
||||
|
||||
$this->callMethod(
|
||||
$this->_oModel,
|
||||
'getRenderer',
|
||||
[$format]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function canGetRendererDataProvider(): array
|
||||
{
|
||||
return [
|
||||
'existing renderer'=> [RendererBridge::FORMAT_JSON, false],
|
||||
'unknown renderer'=> ['unknownRenderer', true],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +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="@d3datawizard/admin/inc/d3Wizards.tpl" submit="@d3datawizard/admin/inc/d3ActionSubmit.tpl"}]
|
|
@ -0,0 +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="@d3datawizard/admin/inc/d3Wizards.tpl" submit="@d3datawizard/admin/inc/d3ExportSubmit.tpl"}]
|
|
@ -0,0 +1,146 @@
|
|||
[{include file="headitem.tpl" title="GENERAL_ADMIN_TITLE"|oxmultilangassign}]
|
||||
|
||||
[{oxstyle include="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"}]
|
||||
[{oxscript include="https://code.jquery.com/jquery-3.2.1.slim.min.js"}]
|
||||
[{oxscript include="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"}]
|
||||
[{oxscript include="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"}]
|
||||
[{oxstyle include="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/solid.min.css"}]
|
||||
|
||||
[{if $readonly}]
|
||||
[{assign var="readonly" value="readonly disabled"}]
|
||||
[{else}]
|
||||
[{assign var="readonly" value=""}]
|
||||
[{/if}]
|
||||
|
||||
<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 name="d3script"}][{strip}]
|
||||
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';
|
||||
form = document.getElementById('form_' + id);
|
||||
form.format.value = format;
|
||||
form.submit();
|
||||
}
|
||||
[{/strip}][{/capture}]
|
||||
[{oxscript add=$smarty.capture.d3script}]
|
||||
|
||||
[{assign var="groups" value=$oView->getGroups()}]
|
||||
[{if $groups|@count}]
|
||||
<div id="accordion">
|
||||
[{foreach from=$oView->getGroups() item="group"}]
|
||||
<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}]">
|
||||
[{oxmultilang 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">
|
||||
[{foreach from=$oView->getGroupTasks($group) key="id" item="item"}]
|
||||
<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">
|
||||
|
||||
<form name="myedit" id="form_[{$id}]" action="[{$oViewConf->getSelfLink()}]" method="post">
|
||||
[{$oViewConf->getHiddenSid()}]
|
||||
<input type="hidden" name="cl" value="[{$oViewConf->getActiveClassName()}]">
|
||||
<input type="hidden" name="fnc" value="runTask">
|
||||
<input type="hidden" name="taskid" value="[{$id}]">
|
||||
<input type="hidden" name="format" value="CSV">
|
||||
|
||||
|
||||
[{if $item->getDescription()}]
|
||||
[{assign var="description" value=$item->getDescription()}]
|
||||
[{assign var="sectionlength" value="100"}]
|
||||
|
||||
[{if $description|count_characters:true <= $sectionlength}]
|
||||
<p class="card-text">[{$description}]</p>
|
||||
[{else}]
|
||||
[{assign var="shorttext" value=$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_[{$id}]">
|
||||
...[{$description|replace:$shorttext:''}]
|
||||
</p>
|
||||
[{/if}]
|
||||
[{/if}]
|
||||
|
||||
[{if $item->hasFormElements()}]
|
||||
[{foreach from=$item->getFormElements() item="formElement"}]
|
||||
[{$formElement}]
|
||||
[{/foreach}]
|
||||
[{/if}]
|
||||
|
||||
[{block name="exportSubmit"}]
|
||||
[{include file=$submit}]
|
||||
[{/block}]
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
[{/foreach}]
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
[{/foreach}]
|
||||
</div>
|
||||
[{else}]
|
||||
<div class="alert alert-primary" role="alert">
|
||||
[{oxmultilang ident=$d3dw_noitemmessageid}]
|
||||
</div>
|
||||
[{/if}]
|
||||
|
||||
<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 file="@d3modcfg_lib/admin/inc/inc.tpl"}]
|
|
@ -0,0 +1,8 @@
|
|||
[{block name="submitElements"}]
|
||||
<div class="btn-group" [{$readonly}]>
|
||||
<button type="button" class="btn btn-primary" onclick="if (confirm('[{oxmultilang ident="D3_DATAWIZARD_ACTION_SUBMIT_CONFIRM"}]') === true) {startTask('[{$id}]')}" [{$readonly}]>
|
||||
<i class="fas fa-fw fa-magic"></i>
|
||||
[{oxmultilang ident=$item->getButtonText()}]
|
||||
</button>
|
||||
</div>
|
||||
[{/block}]
|
|
@ -0,0 +1,24 @@
|
|||
[{block name="submitElements"}]
|
||||
<div class="btn-group" [{$readonly}]>
|
||||
<button type="button" class="btn btn-primary" onclick="startTask('[{$id}]', 'CSV')" [{$readonly}]>
|
||||
<i class="fas fa-fw fa-magic"></i>
|
||||
[{oxmultilang 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" [{$readonly}]>
|
||||
<span class="sr-only">
|
||||
<i class="fas fa-fw fa-magic"></i>
|
||||
[{oxmultilang ident=$item->getButtonText()}]
|
||||
</span>
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
[{block name="dataWizardFormat"}]
|
||||
[{assign var="rendererBridge" value=$item->getRendererBridge()}]
|
||||
[{foreach from=$rendererBridge->getTranslatedRendererIdList() key="key" item="translationId"}]
|
||||
<button class="dropdown-item" onclick="startTask('[{$id}]', '[{$key}]')" [{$readonly}]>
|
||||
[{oxmultilang ident=$translationId}]
|
||||
</button>
|
||||
[{/foreach}]
|
||||
[{/block}]
|
||||
</div>
|
||||
</div>
|
||||
[{/block}]
|
|
@ -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"} %}
|
|
@ -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"} %}
|
|
@ -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" %}
|
|
@ -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 %}
|
|
@ -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 %}
|
Loading…
Reference in New Issue