Dob.php 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Customer\Block\Widget;
  7. use Magento\Customer\Api\CustomerMetadataInterface;
  8. use Magento\Framework\Api\ArrayObjectSearch;
  9. /**
  10. * Class Dob
  11. *
  12. * @SuppressWarnings(PHPMD.DepthOfInheritance)
  13. */
  14. class Dob extends AbstractWidget
  15. {
  16. /**
  17. * Constants for borders of date-type customer attributes
  18. */
  19. const MIN_DATE_RANGE_KEY = 'date_range_min';
  20. const MAX_DATE_RANGE_KEY = 'date_range_max';
  21. /**
  22. * Date inputs
  23. *
  24. * @var array
  25. */
  26. protected $_dateInputs = [];
  27. /**
  28. * @var \Magento\Framework\View\Element\Html\Date
  29. */
  30. protected $dateElement;
  31. /**
  32. * @var \Magento\Framework\Data\Form\FilterFactory
  33. */
  34. protected $filterFactory;
  35. /**
  36. * @param \Magento\Framework\View\Element\Template\Context $context
  37. * @param \Magento\Customer\Helper\Address $addressHelper
  38. * @param CustomerMetadataInterface $customerMetadata
  39. * @param \Magento\Framework\View\Element\Html\Date $dateElement
  40. * @param \Magento\Framework\Data\Form\FilterFactory $filterFactory
  41. * @param array $data
  42. */
  43. public function __construct(
  44. \Magento\Framework\View\Element\Template\Context $context,
  45. \Magento\Customer\Helper\Address $addressHelper,
  46. CustomerMetadataInterface $customerMetadata,
  47. \Magento\Framework\View\Element\Html\Date $dateElement,
  48. \Magento\Framework\Data\Form\FilterFactory $filterFactory,
  49. array $data = []
  50. ) {
  51. $this->dateElement = $dateElement;
  52. $this->filterFactory = $filterFactory;
  53. parent::__construct($context, $addressHelper, $customerMetadata, $data);
  54. }
  55. /**
  56. * @inheritdoc
  57. */
  58. public function _construct()
  59. {
  60. parent::_construct();
  61. $this->setTemplate('Magento_Customer::widget/dob.phtml');
  62. }
  63. /**
  64. * Check if dob attribute enabled in system
  65. *
  66. * @return bool
  67. */
  68. public function isEnabled()
  69. {
  70. $attributeMetadata = $this->_getAttribute('dob');
  71. return $attributeMetadata ? (bool)$attributeMetadata->isVisible() : false;
  72. }
  73. /**
  74. * Check if dob attribute marked as required
  75. *
  76. * @return bool
  77. */
  78. public function isRequired()
  79. {
  80. $attributeMetadata = $this->_getAttribute('dob');
  81. return $attributeMetadata ? (bool)$attributeMetadata->isRequired() : false;
  82. }
  83. /**
  84. * Set date
  85. *
  86. * @param string $date
  87. * @return $this
  88. */
  89. public function setDate($date)
  90. {
  91. $this->setTime($date ? strtotime($date) : false);
  92. $this->setValue($this->applyOutputFilter($date));
  93. return $this;
  94. }
  95. /**
  96. * Return Data Form Filter or false
  97. *
  98. * @return \Magento\Framework\Data\Form\Filter\FilterInterface|false
  99. */
  100. protected function getFormFilter()
  101. {
  102. $attributeMetadata = $this->_getAttribute('dob');
  103. $filterCode = $attributeMetadata->getInputFilter();
  104. if ($filterCode) {
  105. $data = [];
  106. if ($filterCode == 'date') {
  107. $data['format'] = $this->getDateFormat();
  108. }
  109. $filter = $this->filterFactory->create($filterCode, $data);
  110. return $filter;
  111. }
  112. return false;
  113. }
  114. /**
  115. * Apply output filter to value
  116. *
  117. * @param string $value
  118. * @return string
  119. */
  120. protected function applyOutputFilter($value)
  121. {
  122. $filter = $this->getFormFilter();
  123. if ($filter && $value) {
  124. $value = date('Y-m-d', $this->getTime());
  125. $value = $filter->outputFilter($value);
  126. }
  127. return $value;
  128. }
  129. /**
  130. * Get day
  131. *
  132. * @return string|bool
  133. */
  134. public function getDay()
  135. {
  136. return $this->getTime() ? date('d', $this->getTime()) : '';
  137. }
  138. /**
  139. * Get month
  140. *
  141. * @return string|bool
  142. */
  143. public function getMonth()
  144. {
  145. return $this->getTime() ? date('m', $this->getTime()) : '';
  146. }
  147. /**
  148. * Get year
  149. *
  150. * @return string|bool
  151. */
  152. public function getYear()
  153. {
  154. return $this->getTime() ? date('Y', $this->getTime()) : '';
  155. }
  156. /**
  157. * Return label
  158. *
  159. * @return \Magento\Framework\Phrase
  160. */
  161. public function getLabel()
  162. {
  163. return __('Date of Birth');
  164. }
  165. /**
  166. * Retrieve store attribute label
  167. *
  168. * @param string $attributeCode
  169. *
  170. * @return string
  171. */
  172. public function getStoreLabel($attributeCode)
  173. {
  174. $attribute = $this->_getAttribute($attributeCode);
  175. return $attribute ? __($attribute->getStoreLabel()) : '';
  176. }
  177. /**
  178. * Create correct date field
  179. *
  180. * @return string
  181. */
  182. public function getFieldHtml()
  183. {
  184. $this->dateElement->setData([
  185. 'extra_params' => $this->getHtmlExtraParams(),
  186. 'name' => $this->getHtmlId(),
  187. 'id' => $this->getHtmlId(),
  188. 'class' => $this->getHtmlClass(),
  189. 'value' => $this->getValue(),
  190. 'date_format' => $this->getDateFormat(),
  191. 'image' => $this->getViewFileUrl('Magento_Theme::calendar.png'),
  192. 'years_range' => '-120y:c+nn',
  193. 'max_date' => '-1d',
  194. 'change_month' => 'true',
  195. 'change_year' => 'true',
  196. 'show_on' => 'both',
  197. 'first_day' => $this->getFirstDay()
  198. ]);
  199. return $this->dateElement->getHtml();
  200. }
  201. /**
  202. * Return id
  203. *
  204. * @return string
  205. */
  206. public function getHtmlId()
  207. {
  208. return 'dob';
  209. }
  210. /**
  211. * Return data-validate rules
  212. *
  213. * @return string
  214. */
  215. public function getHtmlExtraParams()
  216. {
  217. $validators = [];
  218. if ($this->isRequired()) {
  219. $validators['required'] = true;
  220. }
  221. $validators['validate-date'] = [
  222. 'dateFormat' => $this->getDateFormat()
  223. ];
  224. return 'data-validate="' . $this->_escaper->escapeHtml(json_encode($validators)) . '"';
  225. }
  226. /**
  227. * Returns format which will be applied for DOB in javascript
  228. *
  229. * @return string
  230. */
  231. public function getDateFormat()
  232. {
  233. return $this->_localeDate->getDateFormatWithLongYear();
  234. }
  235. /**
  236. * Add date input html
  237. *
  238. * @param string $code
  239. * @param string $html
  240. * @return void
  241. */
  242. public function setDateInput($code, $html)
  243. {
  244. $this->_dateInputs[$code] = $html;
  245. }
  246. /**
  247. * Sort date inputs by dateformat order of current locale
  248. *
  249. * @param bool $stripNonInputChars
  250. *
  251. * @return string
  252. */
  253. public function getSortedDateInputs($stripNonInputChars = true)
  254. {
  255. $mapping = [];
  256. if ($stripNonInputChars) {
  257. $mapping['/[^medy]/i'] = '\\1';
  258. }
  259. $mapping['/m{1,5}/i'] = '%1$s';
  260. $mapping['/e{1,5}/i'] = '%2$s';
  261. $mapping['/d{1,5}/i'] = '%2$s';
  262. $mapping['/y{1,5}/i'] = '%3$s';
  263. $dateFormat = preg_replace(array_keys($mapping), array_values($mapping), $this->getDateFormat());
  264. return sprintf($dateFormat, $this->_dateInputs['m'], $this->_dateInputs['d'], $this->_dateInputs['y']);
  265. }
  266. /**
  267. * Return minimal date range value
  268. *
  269. * @return string|null
  270. */
  271. public function getMinDateRange()
  272. {
  273. $dob = $this->_getAttribute('dob');
  274. if ($dob !== null) {
  275. $rules = $this->_getAttribute('dob')->getValidationRules();
  276. $minDateValue = ArrayObjectSearch::getArrayElementByName(
  277. $rules,
  278. self::MIN_DATE_RANGE_KEY
  279. );
  280. if ($minDateValue !== null) {
  281. return date("Y/m/d", $minDateValue);
  282. }
  283. }
  284. return null;
  285. }
  286. /**
  287. * Return maximal date range value
  288. *
  289. * @return string|null
  290. */
  291. public function getMaxDateRange()
  292. {
  293. $dob = $this->_getAttribute('dob');
  294. if ($dob !== null) {
  295. $rules = $this->_getAttribute('dob')->getValidationRules();
  296. $maxDateValue = ArrayObjectSearch::getArrayElementByName(
  297. $rules,
  298. self::MAX_DATE_RANGE_KEY
  299. );
  300. if ($maxDateValue !== null) {
  301. return date("Y/m/d", $maxDateValue);
  302. }
  303. }
  304. return null;
  305. }
  306. /**
  307. * Return first day of the week
  308. *
  309. * @return int
  310. */
  311. public function getFirstDay()
  312. {
  313. return (int)$this->_scopeConfig->getValue(
  314. 'general/locale/firstday',
  315. \Magento\Store\Model\ScopeInterface::SCOPE_STORE
  316. );
  317. }
  318. }