Skip to content

Commit

Permalink
🚧 init commit
Browse files Browse the repository at this point in the history
  • Loading branch information
waelkhalifa committed Sep 30, 2022
0 parents commit bd7ac69
Show file tree
Hide file tree
Showing 22 changed files with 710 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.idea/
30 changes: 30 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "wael/custom-catalog",
"description": " Case Study",
"type": "magento2-module",
"version": "1.0.0",
"license": "MIT",
"authors": [
{
"name": "Wael Khalifa",
"email": "[email protected]",
"role": "developer"
}
],
"require": {
"magento/framework": "103.0.*",
"magento/framework-amqp": "100.4.*",
"magento/framework-message-queue": "100.4.*",
"php": ">=7.4"
},
"autoload": {
"files": [
"registration.php"
],
"psr-4": {
"Wael\\CustomCatalog\\": "src"
}
},
"minimum-stability": "dev",
"prefer-stable": true
}
10 changes: 10 additions & 0 deletions registration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php


use \Magento\Framework\Component\ComponentRegistrar;

ComponentRegistrar::register(
ComponentRegistrar::MODULE,
'Wael_CustomCatalog',
__DIR__
);
30 changes: 30 additions & 0 deletions src/Api/CustomCatalogInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php


namespace Wael\CustomCatalog\Api;

/**
* Interface CustomCatalogInterface
* @api
* @package Wael\CustomCatalog\Api
*/
interface CustomCatalogInterface
{
/**
* Get products by VPN
*
* @param string $vpn
* @return \Magento\Catalog\Api\Data\ProductSearchResultsInterface
* @api
*/
public function getByVPN($vpn);

/**
* Update product
*
* @param mixed $product
* @return void
* @api
*/
public function update($product);
}
24 changes: 24 additions & 0 deletions src/Block/Adminhtml/Product/Edit/Button/Back.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php


namespace Wael\CustomCatalog\Block\Adminhtml\Product\Edit\Button;

/**
* Class Back
* @package Wael\CustomCatalog\Block\Adminhtml\Product\Edit\Button
*/
class Back extends \Magento\Catalog\Block\Adminhtml\Product\Edit\Button\Generic
{
/**
* @return array
*/
public function getButtonData()
{
return [
'label' => __('Back'),
'on_click' => sprintf("location.href = '%s';", $this->getUrl('customcatalog/product/')),
'class' => 'back',
'sort_order' => 10
];
}
}
38 changes: 38 additions & 0 deletions src/Controller/Adminhtml/Product/Index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php


namespace Wael\CustomCatalog\Controller\Adminhtml\Product;

/**
* Class Index
* @package Wael\CustomCatalog\Controller\Adminhtml\Product
*/
class Index extends \Magento\Framework\App\Action\Action
{
/**
* @var \Magento\Framework\View\Result\PageFactory
*/
protected $resultPageFactory;

/**
* Constructor
*
* @param \Magento\Framework\App\Action\Context $context
* @param \Magento\Framework\View\Result\PageFactory $resultPageFactory
*/
public function __construct(
\Magento\Framework\App\Action\Context $context,
\Magento\Framework\View\Result\PageFactory $resultPageFactory
) {
parent::__construct($context);
$this->resultPageFactory = $resultPageFactory;
}

/**
* @return \Magento\Framework\View\Result\Page
*/
public function execute()
{
return $this->resultPageFactory->create();
}
}
83 changes: 83 additions & 0 deletions src/Model/CustomCatalog.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php


namespace Wael\CustomCatalog\Model;

/**
* Class CustomCatalog
* @package Wael\CustomCatalog\Model
*/
class CustomCatalog implements \Wael\CustomCatalog\Api\CustomCatalogInterface
{
const TOPIC = 'customcatalog.product.update';
/**
* @var \Magento\Framework\MessageQueue\PublisherInterface
*/
private $publisher;
/**
* @var \Magento\Catalog\Api\ProductRepositoryInterface
*/
private $productRepository;
/**
* @var \Magento\Framework\Api\SearchCriteriaBuilder
*/
private $searchCriteriaBuilder;
/**
* @var \Magento\Framework\Serialize\Serializer\Json
*/
private $jsonSerializer;

/**
* CustomCatalog constructor.
* @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
* @param \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder
* @param \Magento\Framework\MessageQueue\PublisherInterface $publisher
* @param \Magento\Framework\Serialize\Serializer\Json $jsonSerializer
*/
public function __construct(
\Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
\Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder,
\Magento\Framework\MessageQueue\PublisherInterface $publisher,
\Magento\Framework\Serialize\Serializer\Json $jsonSerializer
) {
$this->productRepository = $productRepository;
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
$this->publisher = $publisher;
$this->jsonSerializer = $jsonSerializer;
}

/**
* Returns products for given VPN
*
* @param string $vpn VPN.
* @return \Magento\Catalog\Api\Data\ProductSearchResultsInterface
* @api
*/
public function getByVPN($vpn)
{
$searchCriteria = $this->searchCriteriaBuilder->addFilter('vpn', $vpn, 'eq')->create();
$products = $this->productRepository->getList($searchCriteria);

return $products;
}

/**
* Update product
*
* @param mixed $product
* @return mixed
*/
public function update($product)
{
$result = [];
try {
$productData = $this->jsonSerializer->serialize($product);
$this->publisher->publish(self::TOPIC, $productData);
$result['success'] = 'Product Id: '.$product['entity_id'].' updated successfully';
} catch (\Exception $e) {
$result['error'] = $e->getMessage();
}

return $result;
}
}
151 changes: 151 additions & 0 deletions src/Model/CustomCatalogConsumer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
<?php


namespace Wael\CustomCatalog\Model;

use Magento\Framework\App\ResourceConnection;
use Magento\Framework\MessageQueue\MessageLockException;
use Magento\Framework\MessageQueue\ConnectionLostException;
use Magento\Framework\Exception\NotFoundException;
use Magento\Framework\MessageQueue\CallbackInvoker;
use Magento\Framework\MessageQueue\ConsumerConfigurationInterface;
use Magento\Framework\MessageQueue\EnvelopeInterface;
use Magento\Framework\MessageQueue\QueueInterface;
use Magento\Framework\MessageQueue\LockInterface;
use Magento\Framework\MessageQueue\MessageController;
use Magento\Framework\MessageQueue\ConsumerInterface;

/**
* Class CustomCatalogConsumer
* @package Wael\CustomCatalog\Model
*/
class CustomCatalogConsumer implements ConsumerInterface
{
/**
* @var \Magento\Framework\MessageQueue\CallbackInvoker
*/
private $invoker;
/**
* @var \Magento\Framework\App\ResourceConnection
*/
private $resource;
/**
* @var \Magento\Framework\MessageQueue\ConsumerConfigurationInterface
*/
private $configuration;
/**
* @var \Magento\Framework\MessageQueue\MessageController
*/
private $messageController;
/**
* @var \Magento\Catalog\Api\ProductRepositoryInterface
*/
private $productRepository;
/**
* @var \Magento\Framework\Serialize\Serializer\Json
*/
private $jsonSerializer;

/**
* CustomCatalogConsumer constructor.
* @param CallbackInvoker $invoker
* @param ResourceConnection $resource
* @param MessageController $messageController
* @param ConsumerConfigurationInterface $configuration
* @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
* @param \Magento\Framework\Serialize\Serializer\Json $jsonSerializer
*/
public function __construct(
CallbackInvoker $invoker,
ResourceConnection $resource,
MessageController $messageController,
ConsumerConfigurationInterface $configuration,
\Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
\Magento\Framework\Serialize\Serializer\Json $jsonSerializer
) {
$this->invoker = $invoker;
$this->resource = $resource;
$this->messageController = $messageController;
$this->configuration = $configuration;
$this->productRepository = $productRepository;
$this->jsonSerializer = $jsonSerializer;
}

/**
* @inheritdoc
*/
public function process($maxNumberOfMessages = null)
{
$queue = $this->configuration->getQueue();
if ( ! isset($maxNumberOfMessages)) {
$queue->subscribe($this->getTransactionCallback($queue));
} else {
$this->invoker->invoke($queue, $maxNumberOfMessages, $this->getTransactionCallback($queue));
}
}

/**
* Get transaction callback. This handles the case of both sync and async.
*
* @param QueueInterface $queue
* @return \Closure
*/
private function getTransactionCallback(QueueInterface $queue)
{
return function (EnvelopeInterface $message) use ($queue) {
/** @var LockInterface $lock */
$lock = null;
try {
$lock = $this->messageController->lock($message, $this->configuration->getConsumerName());
$product = $this->updateProduct($message);
if ($product === false) {
$queue->reject($message);
} else {
// For me to get to know if there is an error.
print_r('Product Id : '.$product->getId().' has updated successfully.'.PHP_EOL);
}
$queue->acknowledge($message);
} catch (MessageLockException $e) {
$queue->reject($message, false, $e->getMessage());
$queue->acknowledge($message);
} catch (ConnectionLostException $e) {
$queue->reject($message, false, $e->getMessage());
$queue->acknowledge($message);
if ($lock) {
$this->resource->getConnection()
->delete($this->resource->getTableName('queue_lock'), ['id = ?' => $lock->getId()]);
}
} catch (NotFoundException $e) {
$queue->reject($message, false, $e->getMessage());
$queue->acknowledge($message);
} catch (\Exception $e) {
$queue->reject($message, false, $e->getMessage());
$queue->acknowledge($message);
if ($lock) {
$this->resource->getConnection()
->delete($this->resource->getTableName('queue_lock'), ['id = ?' => $lock->getId()]);
}
}
};
}

/**
* @param $message
* @return \Magento\Catalog\Api\Data\ProductInterface
* @throws \Magento\Framework\Exception\CouldNotSaveException
* @throws \Magento\Framework\Exception\InputException
* @throws \Magento\Framework\Exception\NoSuchEntityException
* @throws \Magento\Framework\Exception\StateException
*/
public function updateProduct($message)
{
$messageBody = $this->jsonSerializer->unserialize($this->jsonSerializer
->unserialize($message->getBody()));
$product = $this->productRepository->getById($messageBody['entity_id']);
$product->setData('copy_write_info', $messageBody['copy_write_info']);
$product->setData('vpn', $messageBody['vpn']);
$product->setStoreId(0);

return $this->productRepository->save($product);
}
}
Loading

0 comments on commit bd7ac69

Please sign in to comment.