<?php
/**
 * Zend Framework (http://framework.zend.com/)
 *
 * @link      http://github.com/zendframework/zf2 for the canonical source repository
 * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd New BSD License
 */

namespace Zend\Form\View\Helper;

use 
DateTime;
use 
IntlDateFormatter;
use 
Zend\Form\ElementInterface;
use 
Zend\Form\Element\DateSelect as DateSelectElement;
use 
Zend\Form\Exception;
use 
Zend\Form\View\Helper\FormMonthSelect as FormMonthSelectHelper;

class 
FormDateSelect extends FormMonthSelectHelper
{
    
/**
     * Render a date element that is composed of three selects
     *
     * @param  ElementInterface $element
     * @throws \Zend\Form\Exception\InvalidArgumentException
     * @throws \Zend\Form\Exception\DomainException
     * @return string
     */
    
public function render(ElementInterface $element)
    {
        if (!
$element instanceof DateSelectElement) {
            throw new 
Exception\InvalidArgumentException(sprintf(
                
'%s requires that the element is of type Zend\Form\Element\DateSelect',
                
__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__
            
));
        }

        
$selectHelper $this->getSelectElementHelper();
        
$pattern      $this->parsePattern($element->shouldRenderDelimiters());

        
$daysOptions   $this->getDaysOptions($pattern['day']);
        
$monthsOptions $this->getMonthsOptions($pattern['month']);
        
$yearOptions   $this->getYearsOptions($element->getMinYear(), $element->getMaxYear());

        
$dayElement   $element->getDayElement()->setValueOptions($daysOptions);
        
$monthElement $element->getMonthElement()->setValueOptions($monthsOptions);
        
$yearElement  $element->getYearElement()->setValueOptions($yearOptions);

        if (
$element->shouldCreateEmptyOption()) {
            
$dayElement->setEmptyOption('');
            
$yearElement->setEmptyOption('');
            
$monthElement->setEmptyOption('');
        }

        
$data = array();
        
$data[$pattern['day']]   = $selectHelper->render($dayElement);
        
$data[$pattern['month']] = $selectHelper->render($monthElement);
        
$data[$pattern['year']]  = $selectHelper->render($yearElement);

        
$markup '';
        foreach (
$pattern as $key => $value) {
            
// Delimiter
            
if (is_numeric($key)) {
                
$markup .= $value;
            } else {
                
$markup .= $data[$value];
            }
        }

        return 
$markup;
    }

    
/**
     * Create a key => value options for days
     *
     * @param string  $pattern Pattern to use for days
     * @return array
     */
    
protected function getDaysOptions($pattern)
    {
        
$keyFormatter   = new IntlDateFormatter($this->getLocale(), nullnullnullnull'dd');
        
$valueFormatter = new IntlDateFormatter($this->getLocale(), nullnullnullnull$pattern);
        
$date           = new DateTime('1970-01-01');

        
$result = array();
        for (
$day 1$day <= 31$day++) {
            
$key   $keyFormatter->format($date);
            
$value $valueFormatter->format($date);
            
$result[$key] = $value;

            
$date->modify('+1 day');
        }

        return 
$result;
    }
}