/src/DluTwBootstrap/Form/View/Helper/FormMonthSelectTwb.php
https://bitbucket.org/dominicwatson/dlutwbootstrap-active · PHP · 321 lines · 167 code · 45 blank · 109 comment · 20 complexity · e7fd1464c0a0c13def9271924005ba7e MD5 · raw file
- <?php
- namespace DluTwBootstrap\Form\View\Helper;
- use DateTime;
- use IntlDateFormatter;
- use Locale;
- use Zend\Form\ElementInterface;
- use Zend\Form\Element\MonthSelect as MonthSelectElement;
- use Zend\Form\Exception;
- use Zend\Form\View\Helper\AbstractHelper;
- use DluTwBootstrap\Form\FormUtil;
- class FormMonthSelectTwb extends AbstractHelper
- {
- /**
- * FormSelect helper
- *
- * @var FormSelect
- */
- protected $selectHelper;
- /**
- * Date formatter to use
- *
- * @var int
- */
- protected $dateType;
- /**
- * Pattern to use for Date rendering
- *
- * @var string
- */
- protected $pattern;
- /**
- * Locale to use
- *
- * @var string
- */
- protected $locale;
- /**
- * General utils
- * @var GenUtil
- */
- protected $genUtil;
-
- /**
- * Form utils
- * @var \DluTwBootstrap\Form\FormUtil
- */
- protected $formUtil;
-
- /* **************************** METHODS ****************************** */
-
- /**
- * Constructor
- * @param \DluTwBootstrap\GenUtil $genUtil
- * @param \DluTwBootstrap\Form\FormUtil $formUtil
- */
- public function __construct(FormUtil $formUtil)
- {
- $this->formUtil = $formUtil;
- }
-
- /**
- * Render a month element that is composed of two selects
- *
- * @param \Zend\Form\ElementInterface $element
- * @throws \Zend\Form\Exception\InvalidArgumentException
- * @throws \Zend\Form\Exception\DomainException
- * @return string
- */
- public function render(ElementInterface $element, $formType = null, array $displayOptions = array())
- {
- if (!$element instanceof MonthSelectElement) {
- throw new Exception\InvalidArgumentException(sprintf(
- '%s requires that the element is of type Zend\Form\Element\MonthSelect',
- __METHOD__
- ));
- }
- $name = $element->getName();
- if ($name === null || $name === '') {
- throw new Exception\DomainException(sprintf(
- '%s requires that the element has an assigned name; none discovered',
- __METHOD__
- ));
- }
- // Allow passing of options to each of the rendered elements
- if (!array_key_exists('day', $displayOptions)) {
- $displayOptions['day'] = array();
- }
- if (!array_key_exists('month', $displayOptions)) {
- $displayOptions['month'] = array();
- }
- if (!array_key_exists('year', $displayOptions)) {
- $displayOptions['year'] = array();
- }
- $selectHelper = $this->getSelectElementHelper();
- $pattern = $this->parsePattern($element->shouldRenderDelimiters());
- // The pattern always contains "day" part and the first separator, so we have to remove it
- unset($pattern['day']);
- unset($pattern[0]);
- $monthsOptions = $this->getMonthsOptions($pattern['month']);
- $yearOptions = $this->getYearsOptions($element->getMinYear(), $element->getMaxYear());
- $monthElement = $element->getMonthElement()->setValueOptions($monthsOptions);
- $yearElement = $element->getYearElement()->setValueOptions($yearOptions);
- if ($element->shouldCreateEmptyOption()) {
- $monthElement->setEmptyOption('');
- $yearElement->setEmptyOption('');
- }
- $data = array();
- $data[$pattern['month']] = $selectHelper->render($monthElement, $formType, $displayOptions['month']);
- $data[$pattern['year']] = $selectHelper->render($yearElement, $formType, $displayOptions['year']);
- $markup = '';
- foreach ($pattern as $key => $value) {
- // Delimiter
- if (is_numeric($key)) {
- $markup .= $value;
- } else {
- $markup .= $data[$value];
- }
- }
- return $markup;
- }
- /**
- * Invoke helper as function
- *
- * Proxies to {@link render()}.
- *
- * @param \Zend\Form\ElementInterface $element
- * @param int $dateType
- * @param null|string $locale
- * @return FormDateSelect
- */
- public function __invoke(ElementInterface $element = null, $formType = null,
- array $displayOptions = array(),
- $dateType = IntlDateFormatter::LONG, $locale = null)
- {
- if (!$element) {
- return $this;
- }
- $this->setDateType($dateType);
- if ($locale !== null) {
- $this->setLocale($locale);
- }
- return $this->render($element, $formType, $displayOptions);
- }
- /**
- * Parse the pattern
- *
- * @param bool $renderDelimiters
- * @return array
- */
- protected function parsePattern($renderDelimiters = true)
- {
- $pattern = $this->getPattern();
- $pregResult = preg_split("/([ -,.\/]*(?:'[a-zA-Z]+')*[ -,.\/]+)/", $pattern, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
- $result = array();
- foreach ($pregResult as $value) {
- if (stripos($value, "'") === false && stripos($value, 'd') !== false) {
- $result['day'] = $value;
- } elseif (stripos($value, "'") === false && stripos($value, 'm') !== false) {
- $result['month'] = $value;
- } elseif (stripos($value, "'") === false && stripos($value, 'y') !== false) {
- $result['year'] = $value;
- } elseif ($renderDelimiters) {
- $result[] = str_replace("'", '', $value);
- }
- }
- return $result;
- }
- /**
- * Retrive pattern to use for Date rendering
- *
- * @return string
- */
- public function getPattern()
- {
- if (null === $this->pattern) {
- $intl = new IntlDateFormatter($this->getLocale(), $this->dateType, IntlDateFormatter::NONE);
- $this->pattern = $intl->getPattern();
- }
- return $this->pattern;
- }
- /**
- * Set date formatter
- *
- * @param int $dateType
- * @return FormDateSelect
- */
- public function setDateType($dateType)
- {
- // The FULL format uses values that are not used
- if ($dateType === IntlDateFormatter::FULL) {
- $dateType = IntlDateFormatter::LONG;
- }
- $this->dateType = $dateType;
- return $this;
- }
- /**
- * Get date formatter
- *
- * @return int
- */
- public function getDateType()
- {
- return $this->dateType;
- }
- /**
- * Set locale
- *
- * @param string $locale
- * @return FormDateSelect
- */
- public function setLocale($locale)
- {
- $this->locale = $locale;
- return $this;
- }
- /**
- * Get locale
- *
- * @return string
- */
- public function getLocale()
- {
- if (null === $this->locale) {
- $this->locale = Locale::getDefault();
- }
- return $this->locale;
- }
- /**
- * Create a key => value options for months
- *
- * @param string $pattern Pattern to use for months
- * @return array
- */
- protected function getMonthsOptions($pattern)
- {
- $keyFormatter = new IntlDateFormatter($this->getLocale(), null, null, null, null, 'MM');
- $valueFormatter = new IntlDateFormatter($this->getLocale(), null, null, null, null, $pattern);
- $date = new DateTime('1970-01-01');
- $result = array();
- for ($month = 1; $month <= 12; $month++) {
- $key = $keyFormatter->format($date->getTimestamp());
- $value = $valueFormatter->format($date->getTimestamp());
- $result[$key] = $value;
- $date->modify('+1 month');
- }
- return $result;
- }
- /**
- * Create a key => value options for years
- * NOTE: we don't use a pattern for years, as years written as two digits can lead to hard to
- * read date for users, so we only use four digits years
- *
- * @param int $minYear
- * @param int $maxYear
- * @return array
- */
- protected function getYearsOptions($minYear, $maxYear)
- {
- $result = array();
- for ($i = $maxYear; $i >= $minYear; --$i) {
- $result[$i] = $i;
- }
- return $result;
- }
- /**
- * Retrieve the FormSelectTwb helper
- *
- * @return FormRow
- */
- protected function getSelectElementHelper()
- {
- if ($this->selectHelper) {
- return $this->selectHelper;
- }
- if (method_exists($this->view, 'plugin')) {
- $this->selectHelper = $this->view->plugin('formselecttwb');
- }
- return $this->selectHelper;
- }
- }