Skip to content

Commit

Permalink
Merge pull request #18 from aligent/feature/BEG-151_fix_for_issue_rel…
Browse files Browse the repository at this point in the history
…ated_to_row_id_and_entity_id_both_being_added_to__cl_tables

BEG-151: Add custom StagedProductAttributeSubscription for catalog_product_link table #17
  • Loading branch information
mausham-shrestha-aligent authored Mar 18, 2024
2 parents 8ba6a98 + 996b58b commit 7733c92
Show file tree
Hide file tree
Showing 5 changed files with 241 additions and 4 deletions.
221 changes: 221 additions & 0 deletions Model/Mview/View/Attribute/CatalogProductLinkSubscription.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
<?php
/*
* Copyright (c) Aligent Consulting. All rights reserved.
*/
namespace Aligent\PrerenderIo\Model\Mview\View\Attribute;

use Magento\Catalog\Api\Data\CategoryInterface;
use Magento\Framework\DB\Ddl\Trigger;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\DB\Ddl\TriggerFactory;
use Magento\Framework\EntityManager\EntityMetadata;
use Magento\Framework\EntityManager\MetadataPool;
use Magento\Framework\Mview\View\ChangelogInterface;
use Magento\Framework\Mview\View\CollectionInterface;
use Magento\Framework\Mview\ViewInterface;
use Magento\Framework\Mview\Config;
use Magento\Framework\Mview\View\Changelog;

/**
* Subscription model class for "catalog_product_link" table
*/
class CatalogProductLinkSubscription extends \Magento\Framework\Mview\View\Subscription
{
private const CATALOG_PRODUCT_LINK_PRODUCT_ID = 'product_id';

/**
* @var EntityMetadata
*/
protected $entityMetadata;

/**
* Save state of Subscription for build statement for retrieving entity id value
*
* @var array
*/
private $statementState = [];

/**
* List of columns that can be updated in a subscribed table
* without creating a new change log entry
*
* @var array
*/
private $ignoredUpdateColumns;

/**
* @param ResourceConnection $resource
* @param TriggerFactory $triggerFactory
* @param CollectionInterface $viewCollection
* @param ViewInterface $view
* @param string $tableName
* @param string $columnName
* @param MetadataPool $metadataPool
* @param string|null $entityInterface
* @param array $ignoredUpdateColumns
* @param array $ignoredUpdateColumnsBySubscription
* @param Config|null $mviewConfig
* @throws \Exception
*/
public function __construct(
ResourceConnection $resource,
TriggerFactory $triggerFactory,
CollectionInterface $viewCollection,
ViewInterface $view,
$tableName,
$columnName,
MetadataPool $metadataPool,
$entityInterface = null,
$ignoredUpdateColumns = [],
$ignoredUpdateColumnsBySubscription = [],
Config $mviewConfig = null
) {
parent::__construct(
$resource,
$triggerFactory,
$viewCollection,
$view,
$tableName,
$columnName,
$ignoredUpdateColumns,
$ignoredUpdateColumnsBySubscription,
$mviewConfig
);
$this->ignoredUpdateColumns = $ignoredUpdateColumns;
$this->entityMetadata = $metadataPool->getMetadata($entityInterface);
}

/**
* Build trigger statement for INSERT, UPDATE, DELETE events
*
* @param string $event
* @param ViewInterface $view
* @return string
*/
protected function buildStatement(string $event, ViewInterface $view): string
{
$triggerBody = '';

switch ($event) {
case Trigger::EVENT_INSERT:
case Trigger::EVENT_UPDATE:
$eventType = 'NEW';
break;
case Trigger::EVENT_DELETE:
$eventType = 'OLD';
break;
default:
return $triggerBody;
}
$entityIdHash = $this->entityMetadata->getIdentifierField()
. $this->entityMetadata->getEntityTable()
. $this->entityMetadata->getLinkField()
. $event;
if (!isset($this->statementState[$entityIdHash])) {
$triggerBody = $this->buildEntityIdStatementByEventType($eventType);
$this->statementState[$entityIdHash] = true;
}

$trigger = $this->buildStatementByEventType($view, $event);
if ($event == Trigger::EVENT_UPDATE) {
$trigger = $this->addConditionsToTrigger($trigger);
}
$triggerBody .= $trigger;

return $triggerBody;
}

/**
* Adds quoted conditions to the trigger
*
* @param string $trigger
* @return string
*/
private function addConditionsToTrigger(string $trigger): string
{
$tableName = $this->resource->getTableName($this->getTableName());
if ($this->connection->isTableExists($tableName)
&& $describe = $this->connection->describeTable($tableName)
) {
$columnNames = array_column($describe, 'COLUMN_NAME');
$columnNames = array_diff($columnNames, $this->ignoredUpdateColumns);
if ($columnNames) {
$columns = [];
foreach ($columnNames as $columnName) {
$columns[] = sprintf(
'NOT(NEW.%1$s <=> OLD.%1$s)',
$this->connection->quoteIdentifier($columnName)
);
}
$trigger = sprintf(
"IF (%s) THEN %s END IF;",
implode(' OR ', $columns),
$trigger
);
}
}

return $trigger;
}

/**
* Build trigger body
*
* @param string $eventType
* @return string
*/
private function buildEntityIdStatementByEventType(string $eventType): string
{
return vsprintf(
'SET @entity_id = (SELECT %1$s FROM %2$s WHERE %3$s = %4$s.%5$s);',
[
$this->connection->quoteIdentifier(
$this->entityMetadata->getIdentifierField()
),
$this->connection->quoteIdentifier(
$this->resource->getTableName($this->entityMetadata->getEntityTable())
),
$this->connection->quoteIdentifier(
$this->entityMetadata->getLinkField()
),
$eventType,
self::CATALOG_PRODUCT_LINK_PRODUCT_ID
]
) . PHP_EOL;
}

/**
* Override column name as we need to use entity_id instead of link field
*
* @param string $prefix
* @param ViewInterface $view
* @return string
*/
public function getEntityColumn(string $prefix, ViewInterface $view): string
{
return '@entity_id';
}

/**
* Build sql statement for trigger
*
* @param ViewInterface $view
* @param string $event
* @return string
* @throws \Exception
*/
private function buildStatementByEventType(ViewInterface $view, string $event): string
{
$columns = $this->prepareColumns($view, $event);
return vsprintf(
'INSERT IGNORE INTO %s (%s) values(%s);',
[
$this->connection->quoteIdentifier(
$this->resource->getTableName($view->getChangelog()->getName())
),
implode(', ', $columns['column_names']),
implode(', ', $columns['column_values'])
]
);
}
}
6 changes: 5 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
"description": "Prerender.io integration for Magento 2, providing recaching for product URLs",
"require": {
"php": ">=7.4",
"magento/framework": "*"
"magento/framework": "*",
"magento/module-store": "*",
"magento/module-catalog": "*",
"magento/module-configurable-product": "*",
"magento/module-url-rewrite": "*"
},
"require-dev": {
"magento/magento-coding-standard": ">=23"
Expand Down
5 changes: 5 additions & 0 deletions etc/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,9 @@
</argument>
</arguments>
</type>
<type name="Aligent\Prerender\Model\Mview\View\Attribute\CatalogProductLinkSubscription">
<arguments>
<argument name="entityInterface" xsi:type="string">Magento\Catalog\Api\Data\ProductInterface</argument>
</arguments>
</type>
</config>
9 changes: 8 additions & 1 deletion etc/module.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,12 @@

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Aligent_PrerenderIo"/>
<module name="Aligent_PrerenderIo">
<sequence>
<module name="Magento_Store"/>
<module name="Magento_Catalog"/>
<module name="Magento_ConfigurableProduct"/>
<module name="Magento_UrlRewrite"/>
</sequence>
</module>
</config>
4 changes: 2 additions & 2 deletions etc/mview.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<table name="catalog_product_entity_text" entity_column="entity_id" />
<table name="catalog_product_entity_tier_price" entity_column="entity_id" />
<table name="catalog_product_entity_varchar" entity_column="entity_id" />
<table name="catalog_product_link" entity_column="product_id" />
<table name="catalog_product_link" entity_column="product_id" subscription_model="Aligent\PrerenderIo\Model\Mview\View\Attribute\CatalogProductLinkSubscription"/>
<table name="catalogrule_product_price" entity_column="product_id" />
<table name="cataloginventory_stock_item" entity_column="product_id" />
</subscriptions>
Expand All @@ -41,7 +41,7 @@
<table name="catalog_product_entity_text" entity_column="entity_id" />
<table name="catalog_product_entity_tier_price" entity_column="entity_id" />
<table name="catalog_product_entity_varchar" entity_column="entity_id" />
<table name="catalog_product_link" entity_column="product_id" />
<table name="catalog_product_link" entity_column="product_id" subscription_model="Aligent\PrerenderIo\Model\Mview\View\Attribute\CatalogProductLinkSubscription"/>
<table name="catalogrule_product_price" entity_column="product_id" />
<table name="cataloginventory_stock_item" entity_column="product_id" />
<table name="catalog_category_product" entity_column="product_id" />
Expand Down

0 comments on commit 7733c92

Please sign in to comment.