[Developer Tool] "time" support for \XF\InputFilterer

DragonByte Tech

Well-known member
At the moment, there doesn't appear to be a good way to combine both date and time input fields into a single timestamp. In order to resolve this, I've created two new input filterer types, as well as made a minor, non-BC breaking change to the existing datetime filterer.

The changes have been tested locally and found working. Given the fact that the change made to the existing datetime filterer has no effect when the option doesn't exist in the options array, I believe that implementing this change should not require extensive testing or cause any issues with existing code.

These are the two new filterers:
PHP:
            case 'datetimeinput':
                if (is_array($value) && isset($value['date']) && isset($value['time']))
                {
                    $time = $this->cleanInternal($value['time'], 'time', $options);
                    
                    $value = $this->cleanInternal($value['date'], 'datetime', array_merge($options, [
                        'time' => $time
                    ]));
                }
                else
                {
                    $value = 0;
                }
                break;
                
            case 'time':
                if (strpos($value, ':') === false)
                {
                    // We didn't have a valid time string
                    $hours = 0;
                    $minutes = 0;
                }
                else
                {
                    list($hours, $minutes) = explode(':', $value);
                    
                    // Sanitise hours and minutes to a maximum of 23:59
                    $hours = min(intval($hours), 23);
                    $minutes = min(intval($minutes), 59);
                }
                
                $value = ['hours' => $hours, 'minutes' => $minutes];
                break;
And I've applied the following change to the existing datetime filterer:
Diff:
--- src/XF/InputFilterer.php    2018-09-08 14:58:52.000000000
+++ src/XF/InputFilterer.php    2018-09-08 15:29:31.000000000
@@ -358,12 +358,16 @@
                         {
                             $dt = new \DateTime($value, $tz);
                             if (!empty($options['end']))
                             {
                                 $dt->setTime(23, 59, 59);
                             }
+                            else if (!empty($options['time']) && is_array($options['time']))
+                            {
+                                $dt->setTime($options['time']['hours'], $options['time']['minutes']);
+                            }
 
                             $value = intval($dt->format('U'));
                         }
                         catch (\Exception $e)
                         {
                             // probably a formatting issue, ignore
Here's the HTML usage:
HTML:
            <xf:formrow label="{{ phrase('date') }}" rowtype="input">
                <div class="inputGroup">
                    <xf:dateinput name="date_field[date]" value="{{ date($entity.isUpdate() ? $entity.date_field : $xf.time, 'picker') }}"    />
                    <span class="inputGroup-splitter"></span>
                    <xf:textbox type="time" name="date_field[time]" value="{{ date($entity.isUpdate() ? $entity.date_field : $xf.time, 'H:i') }}" />
                </div>
            </xf:formrow>
And here's how it would be used in the code:
PHP:
        $input = $this->filter([
            // Other fields go here
            'date_field' => 'datetimeinput'
        ]);

I am currently doing this in a class extension, which I have attached to this post if any other developer finds this interesting.


Fillip
 

Attachments

Upvote 7
Top Bottom