Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Price.php
Go to the documentation of this file.
1 <?php
7 
18 use Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\IndexTableStructureFactory;
20 
26 {
30  private $baseFinalPrice;
31 
35  private $indexTableStructureFactory;
36 
40  private $tableMaintainer;
41 
45  private $metadataPool;
46 
50  private $resource;
51 
55  private $connectionName;
56 
60  private $connection;
61 
65  private $eavConfig;
66 
70  private $basePriceModifier;
71 
82  public function __construct(
83  BaseFinalPrice $baseFinalPrice,
84  IndexTableStructureFactory $indexTableStructureFactory,
85  TableMaintainer $tableMaintainer,
86  MetadataPool $metadataPool,
87  Config $eavConfig,
88  ResourceConnection $resource,
89  BasePriceModifier $basePriceModifier,
90  $connectionName = 'indexer'
91  ) {
92  $this->baseFinalPrice = $baseFinalPrice;
93  $this->indexTableStructureFactory = $indexTableStructureFactory;
94  $this->tableMaintainer = $tableMaintainer;
95  $this->connectionName = $connectionName;
96  $this->metadataPool = $metadataPool;
97  $this->resource = $resource;
98  $this->eavConfig = $eavConfig;
99  $this->basePriceModifier = $basePriceModifier;
100  }
101 
108  public function executeByDimensions(array $dimensions, \Traversable $entityIds)
109  {
110  $temporaryPriceTable = $this->indexTableStructureFactory->create([
111  'tableName' => $this->tableMaintainer->getMainTmpTable($dimensions),
112  'entityField' => 'entity_id',
113  'customerGroupField' => 'customer_group_id',
114  'websiteField' => 'website_id',
115  'taxClassField' => 'tax_class_id',
116  'originalPriceField' => 'price',
117  'finalPriceField' => 'final_price',
118  'minPriceField' => 'min_price',
119  'maxPriceField' => 'max_price',
120  'tierPriceField' => 'tier_price',
121  ]);
122  $this->fillFinalPrice($dimensions, $entityIds, $temporaryPriceTable);
123  $this->basePriceModifier->modifyPrice($temporaryPriceTable, iterator_to_array($entityIds));
124  $this->applyDownloadableLink($temporaryPriceTable, $dimensions);
125  }
126 
135  private function applyDownloadableLink(
136  IndexTableStructure $temporaryPriceTable,
137  array $dimensions
138  ) {
139  $temporaryDownloadableTableName = 'catalog_product_index_price_downlod_temp';
140  $this->getConnection()->createTemporaryTableLike(
141  $temporaryDownloadableTableName,
142  $this->getTable('catalog_product_index_price_downlod_tmp'),
143  true
144  );
145  $this->fillTemporaryTable($temporaryDownloadableTableName, $dimensions);
146  $this->updateTemporaryDownloadableTable($temporaryPriceTable->getTableName(), $temporaryDownloadableTableName);
147  $this->getConnection()->delete($temporaryDownloadableTableName);
148  return $this;
149  }
150 
158  protected function getAttribute($attributeCode)
159  {
160  return $this->eavConfig->getAttribute(Product::ENTITY, $attributeCode);
161  }
162 
171  private function fillTemporaryTable(string $temporaryDownloadableTableName, array $dimensions)
172  {
173  $dlType = $this->getAttribute('links_purchased_separately');
174  $ifPrice = $this->getConnection()->getIfNullSql('dlpw.price_id', 'dlpd.price');
175  $metadata = $this->metadataPool->getMetadata(ProductInterface::class);
176  $linkField = $metadata->getLinkField();
177 
178  $select = $this->getConnection()->select()->from(
179  ['i' => $this->tableMaintainer->getMainTmpTable($dimensions)],
180  ['entity_id', 'customer_group_id', 'website_id']
181  )->join(
182  ['dl' => $dlType->getBackend()->getTable()],
183  "dl.{$linkField} = i.entity_id AND dl.attribute_id = {$dlType->getAttributeId()}" . " AND dl.store_id = 0",
184  []
185  )->join(
186  ['dll' => $this->getTable('downloadable_link')],
187  'dll.product_id = i.entity_id',
188  []
189  )->join(
190  ['dlpd' => $this->getTable('downloadable_link_price')],
191  'dll.link_id = dlpd.link_id AND dlpd.website_id = 0',
192  []
193  )->joinLeft(
194  ['dlpw' => $this->getTable('downloadable_link_price')],
195  'dlpd.link_id = dlpw.link_id AND dlpw.website_id = i.website_id',
196  []
197  )->where(
198  'dl.value = ?',
199  1
200  )->group(
201  ['i.entity_id', 'i.customer_group_id', 'i.website_id']
202  )->columns(
203  [
204  'min_price' => new \Zend_Db_Expr('MIN(' . $ifPrice . ')'),
205  'max_price' => new \Zend_Db_Expr('SUM(' . $ifPrice . ')'),
206  ]
207  );
208  $query = $select->insertFromSelect($temporaryDownloadableTableName);
209  $this->getConnection()->query($query);
210  }
211 
219  private function updateTemporaryDownloadableTable(
220  string $temporaryPriceTableName,
221  string $temporaryDownloadableTableName
222  ) {
223  $ifTierPrice = $this->getConnection()->getCheckSql(
224  'i.tier_price IS NOT NULL',
225  '(i.tier_price + id.min_price)',
226  'NULL'
227  );
228 
229  $selectForCrossUpdate = $this->getConnection()->select()->join(
230  ['id' => $temporaryDownloadableTableName],
231  'i.entity_id = id.entity_id AND i.customer_group_id = id.customer_group_id' .
232  ' AND i.website_id = id.website_id',
233  []
234  );
235  // adds price of custom option, that was applied in DefaultPrice::_applyCustomOption
236  $selectForCrossUpdate->columns(
237  [
238  'min_price' => new \Zend_Db_Expr('i.min_price + id.min_price'),
239  'max_price' => new \Zend_Db_Expr('i.max_price + id.max_price'),
240  'tier_price' => new \Zend_Db_Expr($ifTierPrice),
241  ]
242  );
243  $query = $selectForCrossUpdate->crossUpdateFromSelect(['i' => $temporaryPriceTableName]);
244  $this->getConnection()->query($query);
245  }
246 
256  private function fillFinalPrice(
257  array $dimensions,
258  \Traversable $entityIds,
259  IndexTableStructure $temporaryPriceTable
260  ) {
261  $select = $this->baseFinalPrice->getQuery($dimensions, Type::TYPE_DOWNLOADABLE, iterator_to_array($entityIds));
262  $query = $select->insertFromSelect($temporaryPriceTable->getTableName(), [], false);
263  $this->tableMaintainer->getConnection()->query($query);
264  }
265 
272  private function getConnection(): \Magento\Framework\DB\Adapter\AdapterInterface
273  {
274  if ($this->connection === null) {
275  $this->connection = $this->resource->getConnection($this->connectionName);
276  }
277 
278  return $this->connection;
279  }
280 
287  private function getTable($tableName)
288  {
289  return $this->resource->getTableName($tableName, $this->connectionName);
290  }
291 }
$tableName
Definition: trigger.php:13
$resource
Definition: bulk.php:12
$attributeCode
Definition: extend.phtml:12
__construct(BaseFinalPrice $baseFinalPrice, IndexTableStructureFactory $indexTableStructureFactory, TableMaintainer $tableMaintainer, MetadataPool $metadataPool, Config $eavConfig, ResourceConnection $resource, BasePriceModifier $basePriceModifier, $connectionName='indexer')
Definition: Price.php:82
executeByDimensions(array $dimensions, \Traversable $entityIds)
Definition: Price.php:108