Form.php 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\CatalogSearch\Block\Advanced;
  7. use Magento\CatalogSearch\Model\Advanced;
  8. use Magento\Directory\Model\CurrencyFactory;
  9. use Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
  10. use Magento\Framework\Data\Collection\AbstractDb as DbCollection;
  11. use Magento\Framework\View\Element\AbstractBlock;
  12. use Magento\Framework\View\Element\BlockInterface;
  13. use Magento\Framework\View\Element\Template;
  14. use Magento\Framework\View\Element\Template\Context;
  15. /**
  16. * Advanced search form
  17. *
  18. * @api
  19. * @since 100.0.2
  20. */
  21. class Form extends Template
  22. {
  23. /**
  24. * Currency factory
  25. *
  26. * @var CurrencyFactory
  27. */
  28. protected $_currencyFactory;
  29. /**
  30. * Catalog search advanced
  31. *
  32. * @var Advanced
  33. */
  34. protected $_catalogSearchAdvanced;
  35. /**
  36. * @param Context $context
  37. * @param Advanced $catalogSearchAdvanced
  38. * @param CurrencyFactory $currencyFactory
  39. * @param array $data
  40. */
  41. public function __construct(
  42. Context $context,
  43. Advanced $catalogSearchAdvanced,
  44. CurrencyFactory $currencyFactory,
  45. array $data = []
  46. ) {
  47. $this->_catalogSearchAdvanced = $catalogSearchAdvanced;
  48. $this->_currencyFactory = $currencyFactory;
  49. parent::__construct($context, $data);
  50. }
  51. /**
  52. * @inheritdoc
  53. */
  54. public function _prepareLayout()
  55. {
  56. // add Home breadcrumb
  57. if ($breadcrumbs = $this->getLayout()->getBlock('breadcrumbs')) {
  58. $breadcrumbs->addCrumb(
  59. 'home',
  60. [
  61. 'label' => __('Home'),
  62. 'title' => __('Go to Home Page'),
  63. 'link' => $this->_storeManager->getStore()->getBaseUrl()
  64. ]
  65. )->addCrumb(
  66. 'search',
  67. ['label' => __('Catalog Advanced Search')]
  68. );
  69. }
  70. return parent::_prepareLayout();
  71. }
  72. /**
  73. * Retrieve collection of product searchable attributes
  74. *
  75. * @return DbCollection
  76. */
  77. public function getSearchableAttributes()
  78. {
  79. $attributes = $this->_catalogSearchAdvanced->getAttributes();
  80. return $attributes;
  81. }
  82. /**
  83. * Retrieve attribute label
  84. *
  85. * @param AbstractAttribute $attribute
  86. * @return string
  87. */
  88. public function getAttributeLabel($attribute)
  89. {
  90. return $attribute->getStoreLabel();
  91. }
  92. /**
  93. * Retrieve attribute input validation class
  94. *
  95. * @param AbstractAttribute $attribute
  96. * @return string
  97. */
  98. public function getAttributeValidationClass($attribute)
  99. {
  100. return $attribute->getFrontendClass();
  101. }
  102. /**
  103. * Retrieve search string for given field from request
  104. *
  105. * @param AbstractAttribute $attribute
  106. * @param string|null $part
  107. * @return mixed|string
  108. */
  109. public function getAttributeValue($attribute, $part = null)
  110. {
  111. $value = $this->getRequest()->getQuery($attribute->getAttributeCode());
  112. if ($part && $value) {
  113. if (isset($value[$part])) {
  114. $value = $value[$part];
  115. } else {
  116. $value = '';
  117. }
  118. }
  119. return $value;
  120. }
  121. /**
  122. * Retrieve the list of available currencies
  123. *
  124. * @return array
  125. */
  126. public function getAvailableCurrencies()
  127. {
  128. $currencies = $this->getData('_currencies');
  129. if ($currencies === null) {
  130. $currencies = [];
  131. $codes = $this->_storeManager->getStore()->getAvailableCurrencyCodes(true);
  132. if (is_array($codes) && count($codes)) {
  133. $rates = $this->_currencyFactory->create()->getCurrencyRates(
  134. $this->_storeManager->getStore()->getBaseCurrency(),
  135. $codes
  136. );
  137. foreach ($codes as $code) {
  138. if (isset($rates[$code])) {
  139. $currencies[$code] = $code;
  140. }
  141. }
  142. }
  143. $this->setData('currencies', $currencies);
  144. }
  145. return $currencies;
  146. }
  147. /**
  148. * Count available currencies
  149. *
  150. * @return int
  151. */
  152. public function getCurrencyCount()
  153. {
  154. return count($this->getAvailableCurrencies());
  155. }
  156. /**
  157. * Retrieve currency code for attribute
  158. *
  159. * @param AbstractAttribute $attribute
  160. * @return string
  161. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  162. */
  163. public function getCurrency($attribute)
  164. {
  165. return $this->_storeManager->getStore()->getCurrentCurrencyCode();
  166. }
  167. /**
  168. * Retrieve attribute input type
  169. *
  170. * @param AbstractAttribute $attribute
  171. * @return string
  172. */
  173. public function getAttributeInputType($attribute)
  174. {
  175. $dataType = $attribute->getBackend()->getType();
  176. $inputType = $attribute->getFrontend()->getInputType();
  177. if ($inputType == 'select' || $inputType == 'multiselect') {
  178. return 'select';
  179. }
  180. if ($inputType == 'boolean') {
  181. return 'yesno';
  182. }
  183. if ($inputType == 'price') {
  184. return 'price';
  185. }
  186. if ($dataType == 'int' || $dataType == 'decimal') {
  187. return 'number';
  188. }
  189. if ($dataType == 'datetime') {
  190. return 'date';
  191. }
  192. return 'string';
  193. }
  194. /**
  195. * Build attribute select element html string
  196. *
  197. * @param AbstractAttribute $attribute
  198. * @return string
  199. */
  200. public function getAttributeSelectElement($attribute)
  201. {
  202. $extra = '';
  203. $options = $attribute->getSource()->getAllOptions(false);
  204. $name = $attribute->getAttributeCode();
  205. // 2 - avoid yes/no selects to be multiselects
  206. if (is_array($options) && count($options) > 2) {
  207. $extra = 'multiple="multiple" size="4"';
  208. $name .= '[]';
  209. } else {
  210. array_unshift($options, ['value' => '', 'label' => __('All')]);
  211. }
  212. return $this->_getSelectBlock()->setName(
  213. $name
  214. )->setId(
  215. $attribute->getAttributeCode()
  216. )->setTitle(
  217. $this->getAttributeLabel($attribute)
  218. )->setExtraParams(
  219. $extra
  220. )->setValue(
  221. $this->getAttributeValue($attribute)
  222. )->setOptions(
  223. $options
  224. )->setClass(
  225. 'multiselect'
  226. )->getHtml();
  227. }
  228. /**
  229. * Retrieve yes/no element html for provided attribute
  230. *
  231. * @param AbstractAttribute $attribute
  232. * @return string
  233. */
  234. public function getAttributeYesNoElement($attribute)
  235. {
  236. $options = [
  237. ['value' => '', 'label' => __('All')],
  238. ['value' => '1', 'label' => __('Yes')],
  239. ['value' => '0', 'label' => __('No')],
  240. ];
  241. $name = $attribute->getAttributeCode();
  242. return $this->_getSelectBlock()->setName(
  243. $name
  244. )->setId(
  245. $attribute->getAttributeCode()
  246. )->setTitle(
  247. $this->getAttributeLabel($attribute)
  248. )->setExtraParams(
  249. ""
  250. )->setValue(
  251. $this->getAttributeValue($attribute)
  252. )->setOptions(
  253. $options
  254. )->getHtml();
  255. }
  256. /**
  257. * Get select block.
  258. *
  259. * @return BlockInterface
  260. */
  261. protected function _getSelectBlock()
  262. {
  263. $block = $this->getData('_select_block');
  264. if ($block === null) {
  265. $block = $this->getLayout()->createBlock(\Magento\Framework\View\Element\Html\Select::class);
  266. $this->setData('_select_block', $block);
  267. }
  268. return $block;
  269. }
  270. /**
  271. * Get date block.
  272. *
  273. * @return BlockInterface|mixed
  274. */
  275. protected function _getDateBlock()
  276. {
  277. $block = $this->getData('_date_block');
  278. if ($block === null) {
  279. $block = $this->getLayout()->createBlock(\Magento\Framework\View\Element\Html\Date::class);
  280. $this->setData('_date_block', $block);
  281. }
  282. return $block;
  283. }
  284. /**
  285. * Retrieve search form action url
  286. *
  287. * @return string
  288. */
  289. public function getSearchPostUrl()
  290. {
  291. return $this->getUrl('*/*/result');
  292. }
  293. /**
  294. * Build date element html string for attribute
  295. *
  296. * @param AbstractAttribute $attribute
  297. * @param string $part
  298. * @return string
  299. */
  300. public function getDateInput($attribute, $part = 'from')
  301. {
  302. $name = $attribute->getAttributeCode() . '[' . $part . ']';
  303. $value = $this->getAttributeValue($attribute, $part);
  304. return $this->_getDateBlock()->setName(
  305. $name
  306. )->setId(
  307. $attribute->getAttributeCode() . ($part == 'from' ? '' : '_' . $part)
  308. )->setTitle(
  309. $this->getAttributeLabel($attribute)
  310. )->setValue(
  311. $value
  312. )->setImage(
  313. $this->getViewFileUrl('Magento_Theme::calendar.png')
  314. )->setDateFormat(
  315. $this->_localeDate->getDateFormat(\IntlDateFormatter::SHORT)
  316. )->setClass(
  317. 'input-text'
  318. )->getHtml();
  319. }
  320. }