Image.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Catalog\Helper;
  7. use Magento\Framework\App\Helper\AbstractHelper;
  8. /**
  9. * Catalog image helper
  10. *
  11. * @api
  12. * @SuppressWarnings(PHPMD.TooManyFields)
  13. * @since 100.0.2
  14. */
  15. class Image extends AbstractHelper
  16. {
  17. /**
  18. * Media config node
  19. */
  20. const MEDIA_TYPE_CONFIG_NODE = 'images';
  21. /**
  22. * Current model
  23. *
  24. * @var \Magento\Catalog\Model\Product\Image
  25. */
  26. protected $_model;
  27. /**
  28. * Scheduled for resize image
  29. *
  30. * @var bool
  31. */
  32. protected $_scheduleResize = true;
  33. /**
  34. * Scheduled for rotate image
  35. *
  36. * @var bool
  37. */
  38. protected $_scheduleRotate = false;
  39. /**
  40. * Angle
  41. *
  42. * @var int
  43. */
  44. protected $_angle;
  45. /**
  46. * Watermark file name
  47. *
  48. * @var string
  49. */
  50. protected $_watermark;
  51. /**
  52. * Watermark Position
  53. *
  54. * @var string
  55. */
  56. protected $_watermarkPosition;
  57. /**
  58. * Watermark Size
  59. *
  60. * @var string
  61. */
  62. protected $_watermarkSize;
  63. /**
  64. * Watermark Image opacity
  65. *
  66. * @var int
  67. */
  68. protected $_watermarkImageOpacity;
  69. /**
  70. * Current Product
  71. *
  72. * @var \Magento\Catalog\Model\Product
  73. */
  74. protected $_product;
  75. /**
  76. * Image File
  77. *
  78. * @var string
  79. */
  80. protected $_imageFile;
  81. /**
  82. * Image Placeholder
  83. *
  84. * @var string
  85. */
  86. protected $_placeholder;
  87. /**
  88. * @var \Magento\Framework\View\Asset\Repository
  89. */
  90. protected $_assetRepo;
  91. /**
  92. * Product image factory
  93. *
  94. * @var \Magento\Catalog\Model\Product\ImageFactory
  95. */
  96. protected $_productImageFactory;
  97. /**
  98. * @var \Magento\Framework\View\ConfigInterface
  99. */
  100. protected $viewConfig;
  101. /**
  102. * @var \Magento\Framework\Config\View
  103. */
  104. protected $configView;
  105. /**
  106. * Image configuration attributes
  107. *
  108. * @var array
  109. */
  110. protected $attributes = [];
  111. /**
  112. * @var \Magento\Catalog\Model\View\Asset\PlaceholderFactory
  113. */
  114. private $viewAssetPlaceholderFactory;
  115. /**
  116. * @param \Magento\Framework\App\Helper\Context $context
  117. * @param \Magento\Catalog\Model\Product\ImageFactory $productImageFactory
  118. * @param \Magento\Framework\View\Asset\Repository $assetRepo
  119. * @param \Magento\Framework\View\ConfigInterface $viewConfig
  120. * @param \Magento\Catalog\Model\View\Asset\PlaceholderFactory $placeholderFactory
  121. */
  122. public function __construct(
  123. \Magento\Framework\App\Helper\Context $context,
  124. \Magento\Catalog\Model\Product\ImageFactory $productImageFactory,
  125. \Magento\Framework\View\Asset\Repository $assetRepo,
  126. \Magento\Framework\View\ConfigInterface $viewConfig,
  127. \Magento\Catalog\Model\View\Asset\PlaceholderFactory $placeholderFactory = null
  128. ) {
  129. $this->_productImageFactory = $productImageFactory;
  130. parent::__construct($context);
  131. $this->_assetRepo = $assetRepo;
  132. $this->viewConfig = $viewConfig;
  133. $this->viewAssetPlaceholderFactory = $placeholderFactory
  134. ?: \Magento\Framework\App\ObjectManager::getInstance()
  135. ->get(\Magento\Catalog\Model\View\Asset\PlaceholderFactory::class);
  136. }
  137. /**
  138. * Reset all previous data
  139. *
  140. * @return $this
  141. */
  142. protected function _reset()
  143. {
  144. $this->_model = null;
  145. $this->_scheduleRotate = false;
  146. $this->_angle = null;
  147. $this->_watermark = null;
  148. $this->_watermarkPosition = null;
  149. $this->_watermarkSize = null;
  150. $this->_watermarkImageOpacity = null;
  151. $this->_product = null;
  152. $this->_imageFile = null;
  153. $this->attributes = [];
  154. return $this;
  155. }
  156. /**
  157. * Initialize Helper to work with Image
  158. *
  159. * @param \Magento\Catalog\Model\Product $product
  160. * @param string $imageId
  161. * @param array $attributes
  162. * @return $this
  163. */
  164. public function init($product, $imageId, $attributes = [])
  165. {
  166. $this->_reset();
  167. $this->attributes = array_merge(
  168. $this->getConfigView()->getMediaAttributes('Magento_Catalog', self::MEDIA_TYPE_CONFIG_NODE, $imageId),
  169. $attributes
  170. );
  171. $this->setProduct($product);
  172. $this->setImageProperties();
  173. $this->setWatermarkProperties();
  174. return $this;
  175. }
  176. /**
  177. * Set image properties
  178. *
  179. * @return $this
  180. */
  181. protected function setImageProperties()
  182. {
  183. $this->_getModel()->setDestinationSubdir($this->getType());
  184. $this->_getModel()->setWidth($this->getWidth());
  185. $this->_getModel()->setHeight($this->getHeight());
  186. // Set 'keep frame' flag
  187. $frame = $this->getFrame();
  188. if (!empty($frame)) {
  189. $this->_getModel()->setKeepFrame($frame);
  190. }
  191. // Set 'constrain only' flag
  192. $constrain = $this->getAttribute('constrain');
  193. if (!empty($constrain)) {
  194. $this->_getModel()->setConstrainOnly($constrain);
  195. }
  196. // Set 'keep aspect ratio' flag
  197. $aspectRatio = $this->getAttribute('aspect_ratio');
  198. if (!empty($aspectRatio)) {
  199. $this->_getModel()->setKeepAspectRatio($aspectRatio);
  200. }
  201. // Set 'transparency' flag
  202. $transparency = $this->getAttribute('transparency');
  203. if (!empty($transparency)) {
  204. $this->_getModel()->setKeepTransparency($transparency);
  205. }
  206. // Set background color
  207. $background = $this->getAttribute('background');
  208. if (!empty($background)) {
  209. $this->_getModel()->setBackgroundColor($background);
  210. }
  211. return $this;
  212. }
  213. /**
  214. * Set watermark properties
  215. *
  216. * @return $this
  217. */
  218. protected function setWatermarkProperties()
  219. {
  220. $this->setWatermark(
  221. $this->scopeConfig->getValue(
  222. "design/watermark/{$this->getType()}_image",
  223. \Magento\Store\Model\ScopeInterface::SCOPE_STORE
  224. )
  225. );
  226. $this->setWatermarkImageOpacity(
  227. $this->scopeConfig->getValue(
  228. "design/watermark/{$this->getType()}_imageOpacity",
  229. \Magento\Store\Model\ScopeInterface::SCOPE_STORE
  230. )
  231. );
  232. $this->setWatermarkPosition(
  233. $this->scopeConfig->getValue(
  234. "design/watermark/{$this->getType()}_position",
  235. \Magento\Store\Model\ScopeInterface::SCOPE_STORE
  236. )
  237. );
  238. $this->setWatermarkSize(
  239. $this->scopeConfig->getValue(
  240. "design/watermark/{$this->getType()}_size",
  241. \Magento\Store\Model\ScopeInterface::SCOPE_STORE
  242. )
  243. );
  244. return $this;
  245. }
  246. /**
  247. * Schedule resize of the image
  248. * $width *or* $height can be null - in this case, lacking dimension will be calculated.
  249. *
  250. * @see \Magento\Catalog\Model\Product\Image
  251. * @param int $width
  252. * @param int $height
  253. * @return $this
  254. */
  255. public function resize($width, $height = null)
  256. {
  257. $this->_getModel()->setWidth($width)->setHeight($height);
  258. $this->_scheduleResize = true;
  259. return $this;
  260. }
  261. /**
  262. * Set image quality, values in percentage from 0 to 100
  263. *
  264. * @param int $quality
  265. * @return $this
  266. * @deprecated 103.0.1
  267. */
  268. public function setQuality($quality)
  269. {
  270. $this->_getModel()->setQuality($quality);
  271. return $this;
  272. }
  273. /**
  274. * Guarantee, that image picture width/height will not be distorted.
  275. * Applicable before calling resize()
  276. * It is true by default.
  277. *
  278. * @see \Magento\Catalog\Model\Product\Image
  279. * @param bool $flag
  280. * @return $this
  281. */
  282. public function keepAspectRatio($flag)
  283. {
  284. $this->_getModel()->setKeepAspectRatio($flag);
  285. return $this;
  286. }
  287. /**
  288. * Guarantee, that image will have dimensions, set in $width/$height
  289. * Applicable before calling resize()
  290. * Not applicable, if keepAspectRatio(false)
  291. *
  292. * $position - TODO, not used for now - picture position inside the frame.
  293. *
  294. * @see \Magento\Catalog\Model\Product\Image
  295. * @param bool $flag
  296. * @return $this
  297. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  298. */
  299. public function keepFrame($flag)
  300. {
  301. $this->_getModel()->setKeepFrame($flag);
  302. return $this;
  303. }
  304. /**
  305. * Guarantee, that image will not lose transparency if any.
  306. * Applicable before calling resize()
  307. * It is true by default.
  308. *
  309. * $alphaOpacity - TODO, not used for now
  310. *
  311. * @see \Magento\Catalog\Model\Product\Image
  312. * @param bool $flag
  313. * @return $this
  314. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  315. */
  316. public function keepTransparency($flag)
  317. {
  318. $this->_getModel()->setKeepTransparency($flag);
  319. return $this;
  320. }
  321. /**
  322. * Guarantee, that image picture will not be bigger, than it was.
  323. * Applicable before calling resize()
  324. * It is false by default
  325. *
  326. * @param bool $flag
  327. * @return $this
  328. */
  329. public function constrainOnly($flag)
  330. {
  331. $this->_getModel()->setConstrainOnly($flag);
  332. return $this;
  333. }
  334. /**
  335. * Set color to fill image frame with.
  336. * Applicable before calling resize()
  337. * The keepTransparency(true) overrides this (if image has transparent color)
  338. * It is white by default.
  339. *
  340. * @see \Magento\Catalog\Model\Product\Image
  341. * @param array $colorRGB
  342. * @return $this
  343. */
  344. public function backgroundColor($colorRGB)
  345. {
  346. // assume that 3 params were given instead of array
  347. if (!is_array($colorRGB)) {
  348. $colorRGB = func_get_args();
  349. }
  350. $this->_getModel()->setBackgroundColor($colorRGB);
  351. return $this;
  352. }
  353. /**
  354. * Rotate image into specified angle
  355. *
  356. * @param int $angle
  357. * @return $this
  358. */
  359. public function rotate($angle)
  360. {
  361. $this->setAngle($angle);
  362. $this->_getModel()->setAngle($angle);
  363. $this->_scheduleRotate = true;
  364. return $this;
  365. }
  366. /**
  367. * Add watermark to image
  368. *
  369. * Size param in format 100x200
  370. *
  371. * @param string $fileName
  372. * @param string $position
  373. * @param string $size
  374. * @param int $imageOpacity
  375. * @return $this
  376. */
  377. public function watermark($fileName, $position, $size = null, $imageOpacity = null)
  378. {
  379. $this->setWatermark(
  380. $fileName
  381. )->setWatermarkPosition(
  382. $position
  383. )->setWatermarkSize(
  384. $size
  385. )->setWatermarkImageOpacity(
  386. $imageOpacity
  387. );
  388. return $this;
  389. }
  390. /**
  391. * Set placeholder
  392. *
  393. * @param string $fileName
  394. * @return void
  395. */
  396. public function placeholder($fileName)
  397. {
  398. $this->_placeholder = $fileName;
  399. }
  400. /**
  401. * Get Placeholder
  402. *
  403. * @param null|string $placeholder
  404. * @return string
  405. *
  406. * @deprecated 102.0.0 Returns only default placeholder.
  407. * Does not take into account custom placeholders set in Configuration.
  408. */
  409. public function getPlaceholder($placeholder = null)
  410. {
  411. if ($placeholder) {
  412. $placeholderFullPath = 'Magento_Catalog::images/product/placeholder/' . $placeholder . '.jpg';
  413. } else {
  414. $placeholderFullPath = $this->_placeholder
  415. ?: 'Magento_Catalog::images/product/placeholder/' . $this->_getModel()->getDestinationSubdir() . '.jpg';
  416. }
  417. return $placeholderFullPath;
  418. }
  419. /**
  420. * Apply scheduled actions
  421. *
  422. * @return $this
  423. * @throws \Exception
  424. */
  425. protected function applyScheduledActions()
  426. {
  427. $this->initBaseFile();
  428. if ($this->isScheduledActionsAllowed()) {
  429. $model = $this->_getModel();
  430. if ($this->_scheduleRotate) {
  431. $model->rotate($this->getAngle());
  432. }
  433. if ($this->_scheduleResize) {
  434. $model->resize();
  435. }
  436. if ($this->getWatermark()) {
  437. $model->setWatermark($this->getWatermark());
  438. }
  439. $model->saveFile();
  440. }
  441. return $this;
  442. }
  443. /**
  444. * Initialize base image file
  445. *
  446. * @return $this
  447. */
  448. protected function initBaseFile()
  449. {
  450. $model = $this->_getModel();
  451. $baseFile = $model->getBaseFile();
  452. if (!$baseFile) {
  453. if ($this->getImageFile()) {
  454. $model->setBaseFile($this->getImageFile());
  455. } else {
  456. $model->setBaseFile($this->getProduct()->getData($model->getDestinationSubdir()));
  457. }
  458. }
  459. return $this;
  460. }
  461. /**
  462. * Check if scheduled actions is allowed
  463. *
  464. * @return bool
  465. */
  466. protected function isScheduledActionsAllowed()
  467. {
  468. $model = $this->_getModel();
  469. if ($model->isBaseFilePlaceholder() || $model->isCached()) {
  470. return false;
  471. }
  472. return true;
  473. }
  474. /**
  475. * Retrieve image URL
  476. *
  477. * @return string
  478. */
  479. public function getUrl()
  480. {
  481. try {
  482. $this->applyScheduledActions();
  483. return $this->_getModel()->getUrl();
  484. } catch (\Exception $e) {
  485. return $this->getDefaultPlaceholderUrl();
  486. }
  487. }
  488. /**
  489. * Save changes
  490. *
  491. * @return $this
  492. */
  493. public function save()
  494. {
  495. $this->applyScheduledActions();
  496. return $this;
  497. }
  498. /**
  499. * Return resized product image information
  500. *
  501. * @return array
  502. */
  503. public function getResizedImageInfo()
  504. {
  505. $this->applyScheduledActions();
  506. return $this->_getModel()->getResizedImageInfo();
  507. }
  508. /**
  509. * Getter for placeholder url
  510. *
  511. * @param null|string $placeholder
  512. * @return string
  513. */
  514. public function getDefaultPlaceholderUrl($placeholder = null)
  515. {
  516. try {
  517. $imageAsset = $this->viewAssetPlaceholderFactory->create(
  518. [
  519. 'type' => $placeholder ?: $this->_getModel()->getDestinationSubdir(),
  520. ]
  521. );
  522. $url = $imageAsset->getUrl();
  523. } catch (\Exception $e) {
  524. $this->_logger->critical($e);
  525. $url = $this->_urlBuilder->getUrl('', ['_direct' => 'core/index/notFound']);
  526. }
  527. return $url;
  528. }
  529. /**
  530. * Get current Image model
  531. *
  532. * @return \Magento\Catalog\Model\Product\Image
  533. */
  534. protected function _getModel()
  535. {
  536. if (!$this->_model) {
  537. $this->_model = $this->_productImageFactory->create();
  538. }
  539. return $this->_model;
  540. }
  541. /**
  542. * Set Rotation Angle
  543. *
  544. * @param int $angle
  545. * @return $this
  546. */
  547. protected function setAngle($angle)
  548. {
  549. $this->_angle = $angle;
  550. return $this;
  551. }
  552. /**
  553. * Get Rotation Angle
  554. *
  555. * @return int
  556. */
  557. protected function getAngle()
  558. {
  559. return $this->_angle;
  560. }
  561. /**
  562. * Set watermark file name
  563. *
  564. * @param string $watermark
  565. * @return $this
  566. */
  567. protected function setWatermark($watermark)
  568. {
  569. $this->_watermark = $watermark;
  570. $this->_getModel()->setWatermarkFile($watermark);
  571. return $this;
  572. }
  573. /**
  574. * Get watermark file name
  575. *
  576. * @return string
  577. */
  578. protected function getWatermark()
  579. {
  580. return $this->_watermark;
  581. }
  582. /**
  583. * Set watermark position
  584. *
  585. * @param string $position
  586. * @return $this
  587. */
  588. protected function setWatermarkPosition($position)
  589. {
  590. $this->_watermarkPosition = $position;
  591. $this->_getModel()->setWatermarkPosition($position);
  592. return $this;
  593. }
  594. /**
  595. * Get watermark position
  596. *
  597. * @return string
  598. */
  599. protected function getWatermarkPosition()
  600. {
  601. return $this->_watermarkPosition;
  602. }
  603. /**
  604. * Set watermark size
  605. *
  606. * Param size in format 100x200
  607. *
  608. * @param string $size
  609. * @return $this
  610. */
  611. public function setWatermarkSize($size)
  612. {
  613. $this->_watermarkSize = $size;
  614. $this->_getModel()->setWatermarkSize($this->parseSize($size));
  615. return $this;
  616. }
  617. /**
  618. * Get watermark size
  619. *
  620. * @return string
  621. */
  622. protected function getWatermarkSize()
  623. {
  624. return $this->_watermarkSize;
  625. }
  626. /**
  627. * Set watermark image opacity
  628. *
  629. * @param int $imageOpacity
  630. * @return $this
  631. */
  632. public function setWatermarkImageOpacity($imageOpacity)
  633. {
  634. $this->_watermarkImageOpacity = $imageOpacity;
  635. $this->_getModel()->setWatermarkImageOpacity($imageOpacity);
  636. return $this;
  637. }
  638. /**
  639. * Get watermark image opacity
  640. *
  641. * @return int
  642. */
  643. protected function getWatermarkImageOpacity()
  644. {
  645. if ($this->_watermarkImageOpacity) {
  646. return $this->_watermarkImageOpacity;
  647. }
  648. return $this->_getModel()->getWatermarkImageOpacity();
  649. }
  650. /**
  651. * Set current Product
  652. *
  653. * @param \Magento\Catalog\Model\Product $product
  654. * @return $this
  655. */
  656. protected function setProduct($product)
  657. {
  658. $this->_product = $product;
  659. return $this;
  660. }
  661. /**
  662. * Get current Product
  663. *
  664. * @return \Magento\Catalog\Model\Product
  665. */
  666. protected function getProduct()
  667. {
  668. return $this->_product;
  669. }
  670. /**
  671. * Set Image file
  672. *
  673. * @param string $file
  674. * @return $this
  675. */
  676. public function setImageFile($file)
  677. {
  678. $this->_imageFile = $file;
  679. return $this;
  680. }
  681. /**
  682. * Get Image file
  683. *
  684. * @return string
  685. */
  686. protected function getImageFile()
  687. {
  688. return $this->_imageFile;
  689. }
  690. /**
  691. * Retrieve size from string
  692. *
  693. * @param string $string
  694. * @return array|bool
  695. */
  696. protected function parseSize($string)
  697. {
  698. $size = explode('x', strtolower($string));
  699. if (sizeof($size) == 2) {
  700. return ['width' => $size[0] > 0 ? $size[0] : null, 'height' => $size[1] > 0 ? $size[1] : null];
  701. }
  702. return false;
  703. }
  704. /**
  705. * Retrieve original image width
  706. *
  707. * @return int|null
  708. */
  709. public function getOriginalWidth()
  710. {
  711. return $this->_getModel()->getImageProcessor()->getOriginalWidth();
  712. }
  713. /**
  714. * Retrieve original image height
  715. *
  716. * @return int|null
  717. */
  718. public function getOriginalHeight()
  719. {
  720. return $this->_getModel()->getImageProcessor()->getOriginalHeight();
  721. }
  722. /**
  723. * Retrieve Original image size as array
  724. * 0 - width, 1 - height
  725. *
  726. * @return int[]
  727. */
  728. public function getOriginalSizeArray()
  729. {
  730. return [$this->getOriginalWidth(), $this->getOriginalHeight()];
  731. }
  732. /**
  733. * Retrieve config view
  734. *
  735. * @return \Magento\Framework\Config\View
  736. */
  737. protected function getConfigView()
  738. {
  739. if (!$this->configView) {
  740. $this->configView = $this->viewConfig->getViewConfig();
  741. }
  742. return $this->configView;
  743. }
  744. /**
  745. * Retrieve image type
  746. *
  747. * @return string
  748. */
  749. public function getType()
  750. {
  751. return $this->getAttribute('type');
  752. }
  753. /**
  754. * Retrieve image width
  755. *
  756. * @return string
  757. */
  758. public function getWidth()
  759. {
  760. return $this->getAttribute('width');
  761. }
  762. /**
  763. * Retrieve image height
  764. *
  765. * @return string
  766. */
  767. public function getHeight()
  768. {
  769. return $this->getAttribute('height') ?: $this->getAttribute('width');
  770. }
  771. /**
  772. * Retrieve image frame flag
  773. *
  774. * @return false|string
  775. */
  776. public function getFrame()
  777. {
  778. $frame = $this->getAttribute('frame');
  779. if ($frame === null) {
  780. $frame = $this->getConfigView()->getVarValue('Magento_Catalog', 'product_image_white_borders');
  781. }
  782. return (bool)$frame;
  783. }
  784. /**
  785. * Retrieve image attribute
  786. *
  787. * @param string $name
  788. * @return string
  789. */
  790. protected function getAttribute($name)
  791. {
  792. return $this->attributes[$name] ?? null;
  793. }
  794. /**
  795. * Return image label
  796. *
  797. * @return string
  798. */
  799. public function getLabel()
  800. {
  801. $label = $this->_product->getData($this->getType() . '_' . 'label');
  802. if (empty($label)) {
  803. $label = $this->_product->getName();
  804. }
  805. return $label;
  806. }
  807. }