diff --git a/src/Setup/Actions.php b/src/Setup/Actions.php new file mode 100644 index 0000000..a2c4a95 --- /dev/null +++ b/src/Setup/Actions.php @@ -0,0 +1,135 @@ + + * @link https://www.oxidmodule.com + */ + +declare(strict_types=1); + +namespace D3\Linkmobility4OXID\Setup; + +use D3\Linkmobility4OXID\Application\Model\MessageTypes\AbstractMessage; +use Doctrine\DBAL\Driver\Exception as DoctrineDriverException; +use Doctrine\DBAL\Exception as DoctrineException; +use Doctrine\DBAL\Query\QueryBuilder; +use OxidEsales\Eshop\Core\DatabaseProvider; +use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException; +use OxidEsales\Eshop\Core\Exception\DatabaseErrorException; +use OxidEsales\Eshop\Core\Exception\DatabaseException; +use OxidEsales\Eshop\Core\Registry; +use OxidEsales\EshopCommunity\Internal\Container\ContainerFactory; +use OxidEsales\EshopCommunity\Internal\Framework\Database\QueryBuilderFactoryInterface; +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\NotFoundExceptionInterface; + +class Actions +{ + /** + * @return void + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + public function setupDatabase() + { + try { + if (!$this->hasRemarkTypeEnumValue()) { + $this->addRemarkTypeEnumValue(); + } + } catch (DatabaseException|DoctrineDriverException|DoctrineException $e) { + Registry::getLogger()->error($e->getMessage()); + Registry::getUtilsView()->addErrorToDisplay($e); + } + } + + /** + * @return bool + * @throws ContainerExceptionInterface + * @throws DoctrineDriverException + * @throws DoctrineException + * @throws NotFoundExceptionInterface + */ + protected function hasRemarkTypeEnumValue(): bool + { + $fieldType = $this->getRemarkTypeFieldType(); + + $patternEnumCheck = '/^\b(enum)\b/mi'; + if (!preg_match($patternEnumCheck, $fieldType)) { + throw oxNew(DatabaseException::class, 'remark type field has not the expected enum type'); + } + + $patternValueCheck = '/\b('.preg_quote(AbstractMessage::REMARK_IDENT).')\b/mi'; + + return (bool) preg_match($patternValueCheck, $fieldType); + } + + /** + * @return string + * @throws DoctrineDriverException + * @throws DoctrineException + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + protected function getRemarkTypeFieldType(): string + { + /** @var QueryBuilder $qb */ + $qb = ContainerFactory::getInstance()->getContainer()->get(QueryBuilderFactoryInterface::class)->create(); + $qb->select('column_type') + ->from('INFORMATION_SCHEMA.COLUMNS') + ->where( + $qb->expr()->and( + $qb->expr()->eq( + 'table_schema', + $qb->createNamedParameter(Registry::getConfig()->getConfigParam('dbName')) + ), + $qb->expr()->eq( + 'table_name', + $qb->createNamedParameter('oxremark') + ), + $qb->expr()->eq( + 'COLUMN_NAME', + $qb->createNamedParameter('oxtype') + ) + ) + ); + + return (string) $qb->execute()->fetchOne(); + } + + /** + * @return void + * @throws DoctrineDriverException + * @throws DoctrineException + * @throws DatabaseConnectionException + * @throws DatabaseErrorException + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + protected function addRemarkTypeEnumValue() + { + $valuePattern = '/(?<=enum\().*(?=\))/i'; + preg_match($valuePattern, $this->getRemarkTypeFieldType(), $matches); + + $items = array_unique( + array_merge( + str_getcsv($matches[0], ',', "'"), + [AbstractMessage::REMARK_IDENT] + ) + ); + + $db = DatabaseProvider::getDb(); + + $query = 'ALTER TABLE '.$db->quoteIdentifier('oxremark'). + ' CHANGE '.$db->quoteIdentifier('OXTYPE'). ' '.$db->quoteIdentifier('OXTYPE') . + ' enum('.implode(',', $db->quoteArray($items)).')'. + ' COLLATE '.$db->quote('utf8_general_ci').' NOT NULL DEFAULT '.$db->quote('r'); + + $db->execute($query); + } +} \ No newline at end of file diff --git a/src/Setup/Events.php b/src/Setup/Events.php new file mode 100644 index 0000000..fd29ee9 --- /dev/null +++ b/src/Setup/Events.php @@ -0,0 +1,47 @@ + + * @link https://www.oxidmodule.com + */ + +declare(strict_types=1); + +// @codeCoverageIgnoreStart + +namespace D3\Linkmobility4OXID\Setup; + +use D3\ModCfg\Application\Model\Exception\d3ShopCompatibilityAdapterException; +use D3\ModCfg\Application\Model\Install\d3install; +use Doctrine\DBAL\DBALException; +use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException; +use OxidEsales\Eshop\Core\Exception\DatabaseErrorException; +use OxidEsales\Eshop\Core\Exception\StandardException; +use OxidEsales\Eshop\Core\Exception\SystemComponentException; +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\NotFoundExceptionInterface; + +class Events +{ + /** + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + public static function onActivate() + { + /** @var Actions $actions */ + $actions = oxNew(Actions::class); + $actions->setupDatabase(); + } + + public static function onDeactivate() + { + } +} +// @codeCoverageIgnoreEnd diff --git a/src/metadata.php b/src/metadata.php index e431909..3e53c9d 100644 --- a/src/metadata.php +++ b/src/metadata.php @@ -17,6 +17,7 @@ use D3\Linkmobility4OXID\Application\Controller\Admin\AdminOrder; use D3\Linkmobility4OXID\Application\Controller\Admin\AdminUser; use D3\Linkmobility4OXID\Modules\Application\Model\OrderModel; use D3\Linkmobility4OXID\Modules\Core\EmailCore; +use D3\Linkmobility4OXID\Setup\Events; use OxidEsales\Eshop\Application\Model\Order; use OxidEsales\Eshop\Core\Email; @@ -54,7 +55,10 @@ $aModule = [ 'd3sms_sendednow.tpl' => 'd3/linkmobility/Application/views/tpl/SMS/sendednow.tpl', 'd3sms_ordercanceled.tpl' => 'd3/linkmobility/Application/views/tpl/SMS/ordercanceled.tpl', ], - 'events' => [], + 'events' => [ + 'onActivate' => Events::class.'::onActivate', + 'onDeactivate' => Events::class.'::onDeactivate', + ], 'blocks' => [ [ 'template' => 'order_remark.tpl',