Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Product.php
Go to the documentation of this file.
1 <?php
6 namespace Magento\Catalog\Helper;
7 
13 
18 class Product extends \Magento\Framework\Url\Helper\Data
19 {
20  const XML_PATH_PRODUCT_URL_USE_CATEGORY = 'catalog/seo/product_use_categories';
21 
22  const XML_PATH_USE_PRODUCT_CANONICAL_TAG = 'catalog/seo/product_canonical_tag';
23 
24  const XML_PATH_AUTO_GENERATE_MASK = 'catalog/fields_masks';
25 
31  protected $_skipSaleableCheck = false;
32 
36  protected $_statuses;
37 
41  protected $_priceBlock;
42 
46  protected $_assetRepo;
47 
53  protected $_coreRegistry;
54 
58  protected $_attributeConfig;
59 
65  protected $_catalogSession;
66 
73 
80 
84  protected $productRepository;
85 
90 
94  protected $_storeManager;
95 
109  public function __construct(
110  \Magento\Framework\App\Helper\Context $context,
111  \Magento\Store\Model\StoreManagerInterface $storeManager,
112  \Magento\Catalog\Model\Session $catalogSession,
113  \Magento\Framework\View\Asset\Repository $assetRepo,
114  \Magento\Framework\Registry $coreRegistry,
115  \Magento\Catalog\Model\Attribute\Config $attributeConfig,
116  $reindexPriceIndexerData,
117  $reindexProductCategoryIndexerData,
120  ) {
121  $this->_catalogSession = $catalogSession;
122  $this->_attributeConfig = $attributeConfig;
123  $this->_coreRegistry = $coreRegistry;
124  $this->_assetRepo = $assetRepo;
125  $this->_reindexPriceIndexerData = $reindexPriceIndexerData;
126  $this->productRepository = $productRepository;
127  $this->categoryRepository = $categoryRepository;
128  $this->_reindexProductCategoryIndexerData = $reindexProductCategoryIndexerData;
129  $this->_storeManager = $storeManager;
130  parent::__construct($context);
131  }
132 
140  {
141  if ($data instanceof ModelProduct) {
142  foreach ($this->_reindexPriceIndexerData['byDataResult'] as $param) {
143  if ($data->getData($param)) {
144  return true;
145  }
146  }
147  foreach ($this->_reindexPriceIndexerData['byDataChange'] as $param) {
148  if ($data->dataHasChangedFor($param)) {
149  return true;
150  }
151  }
152  } elseif (is_array($data)) {
153  foreach ($this->_reindexPriceIndexerData['byDataChange'] as $param) {
154  if (isset($data[$param])) {
155  return true;
156  }
157  }
158  }
159  return false;
160  }
161 
169  {
170  foreach ($this->_reindexProductCategoryIndexerData['byDataChange'] as $param) {
171  if ($data->dataHasChangedFor($param)) {
172  return true;
173  }
174  }
175  return false;
176  }
177 
184  public function getProductUrl($product)
185  {
186  if ($product instanceof ModelProduct) {
187  return $product->getProductUrl();
188  } elseif (is_numeric($product)) {
189  return $this->productRepository->getById($product)->getProductUrl();
190  }
191  return false;
192  }
193 
200  public function getPrice($product)
201  {
202  return $product->getPrice();
203  }
204 
211  public function getFinalPrice($product)
212  {
213  return $product->getFinalPrice();
214  }
215 
222  public function getImageUrl($product)
223  {
224  $url = false;
225  $attribute = $product->getResource()->getAttribute('image');
226  if (!$product->getImage()) {
227  $url = $this->_assetRepo->getUrl('Magento_Catalog::images/product/placeholder/image.jpg');
228  } elseif ($attribute) {
229  $url = $attribute->getFrontend()->getUrl($product);
230  }
231  return $url;
232  }
233 
240  public function getSmallImageUrl($product)
241  {
242  $url = false;
243  $attribute = $product->getResource()->getAttribute('small_image');
244  if (!$product->getSmallImage()) {
245  $url = $this->_assetRepo->getUrl('Magento_Catalog::images/product/placeholder/small_image.jpg');
246  } elseif ($attribute) {
247  $url = $attribute->getFrontend()->getUrl($product);
248  }
249  return $url;
250  }
251 
258  public function getThumbnailUrl($product)
259  {
260  $url = false;
261  $attribute = $product->getResource()->getAttribute('thumbnail');
262  if (!$product->getThumbnail()) {
263  $url = $this->_assetRepo->getUrl('Magento_Catalog::images/product/placeholder/thumbnail.jpg');
264  } elseif ($attribute) {
265  $url = $attribute->getFrontend()->getUrl($product);
266  }
267  return $url;
268  }
269 
274  public function getEmailToFriendUrl($product)
275  {
276  $categoryId = null;
277  $category = $this->_coreRegistry->registry('current_category');
278  if ($category) {
279  $categoryId = $category->getId();
280  }
281  return $this->_getUrl('sendfriend/product/send', ['id' => $product->getId(), 'cat_id' => $categoryId]);
282  }
283 
287  public function getStatuses()
288  {
289  if (null === $this->_statuses) {
290  $this->_statuses = [];
291  }
292 
293  return $this->_statuses;
294  }
295 
304  public function canShow($product, $where = 'catalog')
305  {
306  if (is_int($product)) {
307  try {
308  $product = $this->productRepository->getById($product);
309  } catch (NoSuchEntityException $e) {
310  return false;
311  }
312  } else {
313  if (!$product->getId()) {
314  return false;
315  }
316  }
317  return $product->isVisibleInCatalog() && $product->isVisibleInSiteVisibility();
318  }
319 
326  public function canUseCanonicalTag($store = null)
327  {
328  return $this->scopeConfig->getValue(
329  self::XML_PATH_USE_PRODUCT_CANONICAL_TAG,
331  $store
332  );
333  }
334 
343  public function getAttributeInputTypes($inputType = null)
344  {
348  $inputTypes = [
349  'multiselect' => ['backend_model' => \Magento\Eav\Model\Entity\Attribute\Backend\ArrayBackend::class],
350  'boolean' => ['source_model' => \Magento\Eav\Model\Entity\Attribute\Source\Boolean::class],
351  ];
352 
353  if ($inputType === null) {
354  return $inputTypes;
355  } else {
356  if (isset($inputTypes[$inputType])) {
357  return $inputTypes[$inputType];
358  }
359  }
360  return [];
361  }
362 
369  public function getAttributeBackendModelByInputType($inputType)
370  {
371  $inputTypes = $this->getAttributeInputTypes();
372  if (!empty($inputTypes[$inputType]['backend_model'])) {
373  return $inputTypes[$inputType]['backend_model'];
374  }
375  return null;
376  }
377 
384  public function getAttributeSourceModelByInputType($inputType)
385  {
386  $inputTypes = $this->getAttributeInputTypes();
387  if (!empty($inputTypes[$inputType]['source_model'])) {
388  return $inputTypes[$inputType]['source_model'];
389  }
390  return null;
391  }
392 
407  public function initProduct($productId, $controller, $params = null)
408  {
409  // Prepare data for routine
410  if (!$params) {
411  $params = new \Magento\Framework\DataObject();
412  }
413 
414  // Init and load product
415  $this->_eventManager->dispatch(
416  'catalog_controller_product_init_before',
417  ['controller_action' => $controller, 'params' => $params]
418  );
419 
420  if (!$productId) {
421  return false;
422  }
423 
424  try {
425  $product = $this->productRepository->getById($productId, false, $this->_storeManager->getStore()->getId());
426  } catch (NoSuchEntityException $e) {
427  return false;
428  }
429 
430  if (!$this->canShow($product)) {
431  return false;
432  }
433  if (!in_array($this->_storeManager->getStore()->getWebsiteId(), $product->getWebsiteIds())) {
434  return false;
435  }
436 
437  // Load product current category
438  $categoryId = $params->getCategoryId();
439  if (!$categoryId && $categoryId !== false) {
440  $lastId = $this->_catalogSession->getLastVisitedCategoryId();
441  if ($product->canBeShowInCategory($lastId)) {
442  $categoryId = $lastId;
443  }
444  } elseif (!$product->canBeShowInCategory($categoryId)) {
445  $categoryId = null;
446  }
447 
448  if ($categoryId) {
449  try {
450  $category = $this->categoryRepository->get($categoryId);
451  } catch (NoSuchEntityException $e) {
452  $category = null;
453  }
454  if ($category) {
455  $product->setCategory($category);
456  $this->_coreRegistry->register('current_category', $category);
457  }
458  }
459 
460  // Register current data and dispatch final events
461  $this->_coreRegistry->register('current_product', $product);
462  $this->_coreRegistry->register('product', $product);
463 
464  try {
465  $this->_eventManager->dispatch(
466  'catalog_controller_product_init_after',
467  ['product' => $product, 'controller_action' => $controller]
468  );
469  } catch (\Magento\Framework\Exception\LocalizedException $e) {
470  $this->_logger->critical($e);
471  return false;
472  }
473 
474  return $product;
475  }
476 
486  {
487  $optionValues = $product->processBuyRequest($buyRequest);
488  $optionValues->setQty($buyRequest->getQty());
489  $product->setPreconfiguredValues($optionValues);
490 
491  return $this;
492  }
493 
509  {
510  if (is_array($buyRequest)) {
511  $buyRequest = new \Magento\Framework\DataObject($buyRequest);
512  }
513  if (is_array($params)) {
514  $params = new \Magento\Framework\DataObject($params);
515  }
516 
517  // Ensure that currentConfig goes as \Magento\Framework\DataObject - for easier work with it later
518  $currentConfig = $params->getCurrentConfig();
519  if ($currentConfig) {
520  if (is_array($currentConfig)) {
521  $params->setCurrentConfig(new \Magento\Framework\DataObject($currentConfig));
522  } elseif (!$currentConfig instanceof \Magento\Framework\DataObject) {
523  $params->unsCurrentConfig();
524  }
525  }
526 
527  /*
528  * Notice that '_processing_params' must always be object to protect processing forged requests
529  * where '_processing_params' comes in $buyRequest as array from user input
530  */
531  $processingParams = $buyRequest->getData('_processing_params');
532  if (!$processingParams || !$processingParams instanceof \Magento\Framework\DataObject) {
533  $processingParams = new \Magento\Framework\DataObject();
534  $buyRequest->setData('_processing_params', $processingParams);
535  }
536  $processingParams->addData($params->getData());
537 
538  return $buyRequest;
539  }
540 
549  public function setSkipSaleableCheck($skipSaleableCheck = false)
550  {
551  $this->_skipSaleableCheck = $skipSaleableCheck;
552  return $this;
553  }
554 
561  public function getSkipSaleableCheck()
562  {
564  }
565 
572  {
573  return $this->scopeConfig->getValue(Product::XML_PATH_AUTO_GENERATE_MASK, 'default');
574  }
575 
582  {
583  return $this->_attributeConfig->getAttributeNames('used_in_autogeneration');
584  }
585 }
elseif(isset( $params[ 'redirect_parent']))
Definition: iframe.phtml:17
getAttributeBackendModelByInputType($inputType)
Definition: Product.php:369
$storeManager
__construct(\Magento\Framework\App\Helper\Context $context, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Catalog\Model\Session $catalogSession, \Magento\Framework\View\Asset\Repository $assetRepo, \Magento\Framework\Registry $coreRegistry, \Magento\Catalog\Model\Attribute\Config $attributeConfig, $reindexPriceIndexerData, $reindexProductCategoryIndexerData, ProductRepositoryInterface $productRepository, CategoryRepositoryInterface $categoryRepository)
Definition: Product.php:109
addParamsToBuyRequest($buyRequest, $params)
Definition: Product.php:508
prepareProductOptions($product, $buyRequest)
Definition: Product.php:485
isDataForProductCategoryIndexerWasChanged(\Magento\Catalog\Model\Product $data)
Definition: Product.php:168
getAttributeInputTypes($inputType=null)
Definition: Product.php:343
foreach($product->getExtensionAttributes() ->getBundleProductOptions() as $option) $buyRequest
initProduct($productId, $controller, $params=null)
Definition: Product.php:407
setSkipSaleableCheck($skipSaleableCheck=false)
Definition: Product.php:549
canShow($product, $where='catalog')
Definition: Product.php:304
canUseCanonicalTag($store=null)
Definition: Product.php:326
$controller
Definition: info.phtml:14
$params[\Magento\Store\Model\StoreManager::PARAM_RUN_CODE]
Definition: website.php:18
getAttributeSourceModelByInputType($inputType)
Definition: Product.php:384