ん~ なんか色々ハマったけど、何とか動くものができた。
まず標準の DateTimeSelect のままではエラーが出るので、 オリジナルのDateTimeSelectを追加。
と言ってもDateTimeSelectを継承して
- getHoursOptions
- getMinutesOptions
- getSecondsOptions
をオーバーライドしたものです。
\module\Application\config\module.config.php
に
\module\Application\config\module.config.php
'view_helpers' => array(
'invokables' => array(
'formDateTimeSelect2' => 'Application\View\Helper\FormDateTimeSelect2',
),
),
を追加する。 次に Application\View\Helper\FormDateTimeSelect2.php を追加する。 中身はこんな感じ。
\module\Application\src\Application\View\Helper\FormDateTimeSelect2.php
namespace Application\View\Helper;
use DateTime;
use IntlDateFormatter;
use Zend\Form\View\Helper\FormDateTimeSelect;
class FormDateTimeSelect2 extends FormDateTimeSelect
{
protected function getHoursOptions($pattern)
{
$keyFormatter = new IntlDateFormatter($this->getLocale(), null, null, null, null, 'HH');
$valueFormatter = new IntlDateFormatter($this->getLocale(), null, null, null, null, $pattern);
$date = new DateTime('1970-01-01 00:00:00');
$result = array();
for ($hour = 1; $hour <= 24; $hour++) {
$key = $keyFormatter->format($date->getTimestamp());
$value = $valueFormatter->format($date->getTimestamp());
$result[$key] = $value;
$date->modify('+1 hour');
}
return $result;
}
protected function getMinutesOptions($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 00:00:00');
$result = array();
for ($min = 1; $min <= 60; $min++) {
$key = $keyFormatter->format($date->getTimestamp());
$value = $valueFormatter->format($date->getTimestamp());
$result[$key] = $value;
$date->modify('+1 minute');
}
return $result;
}
protected function getSecondsOptions($pattern)
{
$keyFormatter = new IntlDateFormatter($this->getLocale(), null, null, null, null, 'ss');
$valueFormatter = new IntlDateFormatter($this->getLocale(), null, null, null, null, $pattern);
$date = new DateTime('1970-01-01 00:00:00');
$result = array();
for ($sec = 1; $sec <= 60; $sec++) {
$key = $keyFormatter->format($date->getTimestamp());
$value = $valueFormatter->format($date->getTimestamp());
$result[$key] = $value;
$date->modify('+1 second');
}
return $result;
}
}
phtmlファイルでは下記のように記述
formDateTimeSelect2($form->get('date_from'), IntlDateFormatter::SHORT, IntlDateFormatter::LONG, 'ja'); ?>
これで動くはずです。
余談ですが、サンプルのAlbumモジュールのように実装してもvalidatorのところが上手く動作しません。
\Zend\Form\Element\DateTimeSelect.php::getInputSpecification
を見ると解るんですが、下記のようにフィルターでコールバックを追加してStringに変換しなければなりません。
そして、ValidatorでDateでチェックするようです。
protected function getValidator()
{
if (null === $this->validator) {
$this->validator = new DateValidator(array('format' => 'Y-m-d H:i:s'));
}
return $this->validator;
}
public function getInputSpecification()
{
return array(
'name' => $this->getName(),
'required' => false,
'filters' => array(
array(
'name' => 'Callback',
'options' => array(
'callback' => function($date) {
// Convert the date to a specific format
if (is_array($date)) {
if (!isset($date['second'])) {
$date['second'] = '00';
}
$date = sprintf('%s-%s-%s %s:%s:%s',
$date['year'], $date['month'], $date['day'],
$date['hour'], $date['minute'], $date['second']
);
}
return $date;
}
)
)
),
'validators' => array(
$this->getValidator(),
)
);
}
これをデフォルトとしてFormオブジェクト作成時にセットしたいんですが、ちょっとやり方が解りませんでした。。
そこで、アクション内で
\module\Album\src\Album\Controller\IndexController.php
if ($request->isPost()) {
$album= new Album();
$form->setInputFilter($album->getInputFilter($form->getInputFilter()));
$form->setData($request->getPost());
...
\module\Album\src\Album\Model\Album.php
public function getInputFilter(InputFilterInterface $defaultInputFilter = NULL)
{
if (!$this->inputFilter) {
if (is_null($defaultInputFilter)) {
$inputFilter = new InputFilter();
} else {
$inputFilter = $defaultInputFilter;
}
}
$factory = new InputFactory();
という感じにしました。