Overview

Namespaces

  • Budovy
  • Kdyby
    • BootstrapFormRenderer
      • DI
      • Latte
  • Nette
    • Application
      • Diagnostics
      • Responses
      • Routers
      • UI
    • Caching
      • Storages
    • ComponentModel
    • Database
      • Diagnostics
      • Drivers
      • Reflection
      • Table
    • DI
      • Config
        • Adapters
      • Diagnostics
      • Extensions
    • Diagnostics
    • Forms
      • Controls
      • Rendering
    • Http
      • Diagnostics
    • Iterators
    • Latte
      • Macros
    • Loaders
    • Localization
    • Mail
    • PhpGenerator
    • Reflection
    • Security
      • Diagnostics
    • Templating
    • Utils
  • NetteModule
  • Nextras
    • Datagrid
  • None
  • PHP
  • Tester
    • CodeCoverage
    • Runner
      • Output
  • Vodacek
    • Forms
      • Controls
  • WebLoader
    • Filter
    • Nette

Classes

  • DateInput
  • Overview
  • Namespace
  • Class
  • Tree
  1: <?php
  2: /*
  3:  * Copyright (c) 2011, Ondřej Vodáček
  4:  * All rights reserved.
  5:  *
  6:  * Redistribution and use in source and binary forms, with or without
  7:  * modification, are permitted provided that the following conditions are met:
  8:  *     * Redistributions of source code must retain the above copyright
  9:  *       notice, this list of conditions and the following disclaimer.
 10:  *     * Redistributions in binary form must reproduce the above copyright
 11:  *       notice, this list of conditions and the following disclaimer in the
 12:  *       documentation and/or other materials provided with the distribution.
 13:  *     * Neither the name of the Ondřej Vodáček nor the
 14:  *       names of its contributors may be used to endorse or promote products
 15:  *       derived from this software without specific prior written permission.
 16:  *
 17:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 18:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 19:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 20:  * DISCLAIMED. IN NO EVENT SHALL Ondřej Vodáček BE LIABLE FOR ANY
 21:  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 22:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 23:  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 24:  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 25:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 26:  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 27:  */
 28: 
 29: namespace Vodacek\Forms\Controls;
 30: 
 31: use Nette\Forms\IControl,
 32:     Nette\Forms\Controls\BaseControl;
 33: 
 34: /**
 35:  * @author Ondřej Vodáček <ondrej.vodacek@gmail.com>
 36:  * @copyright 2011, Ondřej Vodáček
 37:  * @license New BSD License
 38:  */
 39: class DateInput extends BaseControl  {
 40: 
 41:     const TYPE_DATETIME = 'datetime',
 42:             TYPE_DATETIME_LOCAL = 'datetime-local',
 43:             TYPE_DATE = 'date',
 44:             TYPE_MONTH = 'month',
 45:             TYPE_TIME = 'time',
 46:             TYPE_WEEK = 'week';
 47: 
 48:     /** @var string */
 49:     protected $type;
 50: 
 51:     /** @var array */
 52:     protected $range = array('min' => null, 'max' => null);
 53: 
 54:     /** @var mixed */
 55:     protected $submitedValue = null;
 56: 
 57:     private static $formats = array(
 58:         self::TYPE_DATETIME => 'Y-m-d\TH:i:se',
 59:         self::TYPE_DATETIME_LOCAL => 'Y-m-d\TH:i:s',
 60:         self::TYPE_DATE => 'Y-m-d',
 61:         self::TYPE_MONTH => 'Y-m',
 62:         self::TYPE_TIME => 'H:i:s',
 63:         self::TYPE_WEEK => 'o-\WW'
 64:     );
 65: 
 66:     public static function register() {
 67:         $class = __CLASS__;
 68:         \Nette\Forms\Container::extensionMethod('addDate', function (\Nette\Forms\Container $form, $name, $label = null, $type = 'datetime-local') use ($class) {
 69:             $component = new $class($label, $type);
 70:             $form->addComponent($component, $name);
 71:             return $component;
 72:         });
 73:         \Nette\Forms\Rules::$defaultMessages[__CLASS__.'::validateDateInputRange'] = \Nette\Forms\Rules::$defaultMessages[\Nette\Forms\Form::RANGE];
 74:         \Nette\Forms\Rules::$defaultMessages[__CLASS__.'::validateDateInputValid'] = 'Please enter a valid date.';
 75:     }
 76: 
 77:     /**
 78:      * @param string
 79:      * @param string
 80:      * @throws \InvalidArgumentException
 81:      */
 82:     public function __construct($label = null, $type = self::TYPE_DATETIME_LOCAL) {
 83:         if (!isset(self::$formats[$type])) {
 84:             throw new \InvalidArgumentException("invalid type '$type' given.");
 85:         }
 86:         parent::__construct($label);
 87:         $this->control->type = $this->type = $type;
 88:         $this->control->data('dateinput-type', $type);
 89:     }
 90: 
 91:     public function setValue($value = null) {
 92:         if ($value === null || $value instanceof \DateTime) {
 93:             $this->value = $value;
 94:             $this->submitedValue = null;
 95:         } elseif (is_string($value)) {
 96:             if ($value === '') {
 97:                 $this->value = null;
 98:                 $this->submitedValue = null;
 99:             } else {
100:                 $this->value = $this->parseValue($value);
101:                 if ($this->value !== false) {
102:                     $this->submitedValue = null;
103:                 } else {
104:                     $this->value = null;
105:                     $this->submitedValue = $value;
106:                 }
107:             }
108:         } else {
109:             $this->submitedValue = $value;
110:             throw new \InvalidArgumentException("Invalid type for \$value.");
111:         }
112:         return $this;
113:     }
114: 
115:     public function getControl() {
116:         $control = parent::getControl();
117:         $format = self::$formats[$this->type];
118:         if ($this->value !== null) {
119:             $control->value = $this->value->format($format);
120:         }
121:         if ($this->submitedValue !== null && is_string($this->submitedValue)) {
122:             $control->value = $this->submitedValue;
123:         }
124:         if ($this->range['min'] !== null) {
125:             $control->min = $this->range['min']->format($format);
126:         }
127:         if ($this->range['max'] !== null) {
128:             $control->max = $this->range['max']->format($format);
129:         }
130:         return $control;
131:     }
132: 
133:     public function addRule($operation, $message = null, $arg = null) {
134:         if ($operation === \Nette\Forms\Form::RANGE) {
135:             $this->range['min'] = $this->normalizeDate($arg[0]);
136:             $this->range['max'] = $this->normalizeDate($arg[1]);
137:             $operation = __CLASS__.'::validateDateInputRange';
138:             $arg[0] = $this->formatDate($arg[0]);
139:             $arg[1] = $this->formatDate($arg[1]);
140:         } elseif ($operation === \Nette\Forms\Form::VALID) {
141:             $operation = __CLASS__.'::validateDateInputValid';
142:         }
143:         return parent::addRule($operation, $message, $arg);
144:     }
145: 
146:     public static function validateFilled(IControl $control) {
147:         if (!$control instanceof self) {
148:             throw new \InvalidArgumentException("Cant't validate control '".\get_class($control)."'.");
149:         }
150:         return ($control->value !== null || $control->submitedValue !== null);
151:     }
152: 
153:     /**
154:      * Valid validator: is control valid?
155:      * @param  IControl
156:      * @return bool
157:      */
158:     public static function validateDateInputValid(IControl $control) {
159:         return self::validateValid($control);
160:     }
161: 
162:     public static function validateValid(IControl $control) {
163:         if (!$control instanceof self) {
164:             throw new \InvalidArgumentException("Cant't validate control '".\get_class($control)."'.");
165:         }
166:         return $control->submitedValue === null;
167:     }
168: 
169:     /**
170:      * @param self $control
171:      * @param array $args
172:      * @return bool
173:      */
174:     public static function validateDateInputRange(self $control) {
175:         if ($control->range['min'] !== null) {
176:             if ($control->range['min'] > $control->value) {
177:                 return false;
178:             }
179:         }
180:         if ($control->range['max'] !== null) {
181:             if ($control->range['max'] < $control->value) {
182:                 return false;
183:             }
184:         }
185:         return true;
186:     }
187: 
188:     /**
189:      * @param string $value
190:      * @return \DateTime
191:      */
192:     private function parseValue($value) {
193:         $date = null;
194:         if ($this->type === self::TYPE_WEEK) {
195:             try {
196:                 $date = new \DateTime($value."1");
197:             } catch (\Exception $e) {
198:                 $date = false;
199:             }
200:         } else {
201:             $date = \DateTime::createFromFormat('!'.self::$formats[$this->type], $value);
202:         }
203:         return $date;
204:     }
205: 
206:     /**
207:      * @param \DateTime $value
208:      * @return string
209:      */
210:     private function formatDate(\DateTime $value = null) {
211:         if ($value) {
212:             $value = $value->format(self::$formats[$this->type]);
213:         }
214:         return $value;
215:     }
216: 
217:     /**
218:      * @param \DateTime
219:      * @return \DateTime
220:      */
221:     private function normalizeDate(\DateTime $value = null) {
222:         if ($value) {
223:             $value = $this->formatDate($value);
224:             $value = $this->parseValue($value);
225:         }
226:         return $value;
227:     }
228: }
229: 
API documentation generated by ApiGen 2.8.0