Skip to content

Commit

Permalink
Merge branch 'b-7.2.x-add_dao_example-OXDEV-8778' into b-7.2.x-prepar…
Browse files Browse the repository at this point in the history
…e_for_v7.2-OXDEV-8316
  • Loading branch information
tkcreateit committed Nov 14, 2024
2 parents d168cb8 + 1c2023b commit 53352c3
Show file tree
Hide file tree
Showing 32 changed files with 1,287 additions and 1 deletion.
2 changes: 2 additions & 0 deletions metadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
'email' => '',
'extend' => [
\OxidEsales\Eshop\Application\Controller\StartController::class => \OxidEsales\ModuleTemplate\Extension\Controller\StartController::class,
\OxidEsales\Eshop\Application\Controller\ArticleDetailsController::class => \OxidEsales\ModuleTemplate\ProductVote\Controller\ArticleDetailsController::class,
\OxidEsales\Eshop\Application\Component\Widget\ArticleDetails::class => \OxidEsales\ModuleTemplate\ProductVote\Widget\ArticleDetails::class,
\OxidEsales\Eshop\Application\Model\Basket::class => \OxidEsales\ModuleTemplate\Extension\Model\Basket::class,
\OxidEsales\Eshop\Application\Model\User::class => \OxidEsales\ModuleTemplate\Extension\Model\User::class,
],
Expand Down
50 changes: 50 additions & 0 deletions migration/data/Version20241022140851.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

declare(strict_types=1);

namespace OxidEsales\ModuleTemplate\Migrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20241022140851 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}

public function up(Schema $schema): void
{
$this->connection->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');

//add module specific table. To be used with a shop model it needs OXID and TIMESTAMP columns.
if (!$schema->hasTable('oemt_product_vote')) {
$this->addSql("CREATE TABLE `oemt_product_vote` (
`OXID` char(32) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL
COMMENT 'Primary oxid',
`OXSHOPID` int(11) NOT NULL DEFAULT '0'
COMMENT 'Shop id (oxshops), value 0 in case no shop was specified',
`OXARTID` char(32) character set latin1 collate latin1_general_ci NOT NULL
COMMENT 'Product id (oxarticles)',
`OXUSERID` char(32) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL
COMMENT 'User id',
`OXVOTE` tinyint(1) NOT NULL
COMMENT 'Vote up (1) or down (0)',
`OXTIMESTAMP` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
COMMENT 'Timestamp',
PRIMARY KEY (`OXID`),
KEY `OXARTID` (`OXARTID`),
UNIQUE KEY `OXMAINIDX` (`OXSHOPID`, `OXUSERID`, `OXARTID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;");
}
}

public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
}
}
1 change: 1 addition & 0 deletions services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ parameters:
imports:
- { resource: src/Greeting/services.yaml }
- { resource: src/Logging/services.yaml }
- { resource: src/ProductVote/services.yaml }
- { resource: src/Settings/services.yaml }
- { resource: src/Tracker/services.yaml }

Expand Down
56 changes: 56 additions & 0 deletions src/ProductVote/Controller/ArticleDetailsController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/

declare(strict_types=1);

namespace OxidEsales\ModuleTemplate\ProductVote\Controller;

use OxidEsales\Eshop\Application\Model\User;
use OxidEsales\ModuleTemplate\ProductVote\Service\VoteServiceInterface;

/**
* @extendable-class
*
* This is a brand new (module own) controller which extends from the
* shop frontend controller class.
*
* @SuppressWarnings(PHPMD.CamelCasePropertyName)
*/
class ArticleDetailsController extends ArticleDetailsController_parent
{
public function voteUp(): void
{
$this->vote(true);
}

public function voteDown(): void
{
$this->vote(false);
}

public function resetVote(): void
{
$user = $this->getUser();
if (!($user instanceof User)) {
return;
}

$voteService = $this->getService(VoteServiceInterface::class);
$voteService->resetProductVote($this->getProduct(), $user);
}

private function vote(bool $isUp): void
{
$user = $this->getUser();
if (!($user instanceof User)) {
return;
}

$voteService = $this->getService(VoteServiceInterface::class);
$voteService->setProductVote($this->getProduct(), $user, $isUp);
}
}
88 changes: 88 additions & 0 deletions src/ProductVote/Dao/ProductVoteDao.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?php

/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/

declare(strict_types=1);

namespace OxidEsales\ModuleTemplate\ProductVote\Dao;

use Doctrine\DBAL\Result;
use OxidEsales\EshopCommunity\Internal\Framework\Database\QueryBuilderFactoryInterface;
use OxidEsales\ModuleTemplate\ProductVote\DataMapper\ProductVoteDataMapperInterface;
use OxidEsales\ModuleTemplate\ProductVote\DataType\ProductVoteInterface;

readonly class ProductVoteDao implements ProductVoteDaoInterface
{
public function __construct(
private QueryBuilderFactoryInterface $queryBuilderFactory,
private ProductVoteDataMapperInterface $dataMapper,
) {
}

public function getProductVote(string $productId, string $userId): ?ProductVoteInterface
{
$queryBuilder = $this->queryBuilderFactory->create();
$queryBuilder
->select([
'oxartid as ProductId',
'oxuserid as UserId',
'oxvote as Vote',
])
->from('oemt_product_vote')
->where('oxartid = :productId')
->andWhere('oxuserid = :userId')
->setParameters([
'productId' => $productId,
'userId' => $userId,
]);

/** @var Result $result */
$result = $queryBuilder->execute();
$row = $result->fetchAssociative();

if ($row === false) {
return null;
}

return $this->dataMapper->mapFromDbRow($row);
}

public function setProductVote(ProductVoteInterface $vote): void
{
$this->resetProductVote($vote->getProductId(), $vote->getUserId());

$queryBuilder = $this->queryBuilderFactory->create();
$queryBuilder
->insert('oemt_product_vote')
->values([
'oxid' => ':oxid',
'oxartid' => ':productId',
'oxuserid' => ':userId',
'oxvote' => ':vote',
])
->setParameters([
'oxid' => uniqid(),
'productId' => $vote->getProductId(),
'userId' => $vote->getUserId(),
'vote' => (int)$vote->isVoteUp(),
])
->execute();
}

public function resetProductVote(string $productId, string $userId): void
{
$queryBuilder = $this->queryBuilderFactory->create();
$queryBuilder
->delete('oemt_product_vote')
->where('oxartid = :productId')
->andWhere('oxuserid = :userId')
->setParameters([
'productId' => $productId,
'userId' => $userId,
])
->execute();
}
}
20 changes: 20 additions & 0 deletions src/ProductVote/Dao/ProductVoteDaoInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/

declare(strict_types=1);

namespace OxidEsales\ModuleTemplate\ProductVote\Dao;

use OxidEsales\ModuleTemplate\ProductVote\DataType\ProductVoteInterface;

interface ProductVoteDaoInterface
{
public function getProductVote(string $productId, string $userId): ?ProductVoteInterface;

public function setProductVote(ProductVoteInterface $vote): void;
public function resetProductVote(string $productId, string $userId): void;
}
51 changes: 51 additions & 0 deletions src/ProductVote/Dao/VoteResultDao.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/

declare(strict_types=1);

namespace OxidEsales\ModuleTemplate\ProductVote\Dao;

use Doctrine\DBAL\Result;
use OxidEsales\EshopCommunity\Internal\Framework\Database\QueryBuilderFactoryInterface;
use OxidEsales\ModuleTemplate\ProductVote\DataMapper\VoteResultDataMapperInterface;
use OxidEsales\ModuleTemplate\ProductVote\DataType\VoteResult;
use OxidEsales\ModuleTemplate\ProductVote\DataType\VoteResultInterface;

readonly class VoteResultDao implements VoteResultDaoInterface
{
public function __construct(
private QueryBuilderFactoryInterface $queryBuilderFactory,
private VoteResultDataMapperInterface $dataMapper,
) {
}

public function getProductVoteResult(string $productId): VoteResultInterface
{
$queryBuilder = $this->queryBuilderFactory->create();
$queryBuilder
->select([
'oxartid as ProductId',
'SUM(oxvote != 0) as VoteUp',
'SUM(oxvote = 0) as VoteDown',
])
->from('oemt_product_vote')
->where('oxartid = :productId')
->groupBy('oxartid')
->setParameters([
'productId' => $productId,
]);

/** @var Result $queryResult */
$queryResult = $queryBuilder->execute();
$row = $queryResult->fetchAssociative();

if (!$row) {
return new VoteResult($productId, 0, 0);
}
return $this->dataMapper->mapFromDbRow($row);
}
}
17 changes: 17 additions & 0 deletions src/ProductVote/Dao/VoteResultDaoInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/

declare(strict_types=1);

namespace OxidEsales\ModuleTemplate\ProductVote\Dao;

use OxidEsales\ModuleTemplate\ProductVote\DataType\VoteResultInterface;

interface VoteResultDaoInterface
{
public function getProductVoteResult(string $productId): VoteResultInterface;
}
26 changes: 26 additions & 0 deletions src/ProductVote/DataMapper/ProductVoteDataMapper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/

declare(strict_types=1);

namespace OxidEsales\ModuleTemplate\ProductVote\DataMapper;

use OxidEsales\ModuleTemplate\ProductVote\DataType\ProductVote;
use OxidEsales\ModuleTemplate\ProductVote\DataType\ProductVoteInterface;
use OxidEsales\ModuleTemplate\ProductVote\Exception\MapDataTypeException;

readonly class ProductVoteDataMapper implements ProductVoteDataMapperInterface
{
public function mapFromDbRow(array $data): ProductVoteInterface
{
if (!isset($data['ProductId']) || !isset($data['UserId']) || !isset($data['Vote'])) {
throw new MapDataTypeException();
}

return new ProductVote($data['ProductId'], $data['UserId'], (bool)$data['Vote']);
}
}
17 changes: 17 additions & 0 deletions src/ProductVote/DataMapper/ProductVoteDataMapperInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/

declare(strict_types=1);

namespace OxidEsales\ModuleTemplate\ProductVote\DataMapper;

use OxidEsales\ModuleTemplate\ProductVote\DataType\ProductVoteInterface;

interface ProductVoteDataMapperInterface
{
public function mapFromDbRow(array $data): ProductVoteInterface;
}
26 changes: 26 additions & 0 deletions src/ProductVote/DataMapper/VoteResultDataMapper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/

declare(strict_types=1);

namespace OxidEsales\ModuleTemplate\ProductVote\DataMapper;

use OxidEsales\ModuleTemplate\ProductVote\DataType\VoteResult;
use OxidEsales\ModuleTemplate\ProductVote\DataType\VoteResultInterface;
use OxidEsales\ModuleTemplate\ProductVote\Exception\MapDataTypeException;

readonly class VoteResultDataMapper implements VoteResultDataMapperInterface
{
public function mapFromDbRow(array $data): VoteResultInterface
{
if (!isset($data['ProductId']) || !isset($data['VoteUp']) || !isset($data['VoteDown'])) {
throw new MapDataTypeException();
}

return new VoteResult($data['ProductId'], (int)$data['VoteUp'], (int)$data['VoteDown']);
}
}
17 changes: 17 additions & 0 deletions src/ProductVote/DataMapper/VoteResultDataMapperInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/

declare(strict_types=1);

namespace OxidEsales\ModuleTemplate\ProductVote\DataMapper;

use OxidEsales\ModuleTemplate\ProductVote\DataType\VoteResultInterface;

interface VoteResultDataMapperInterface
{
public function mapFromDbRow(array $data): VoteResultInterface;
}
Loading

0 comments on commit 53352c3

Please sign in to comment.