Jump to content

Hook to prevent date fields from changing incorrectly-formatted input values? (erase instead)


Recommended Posts

Posted (edited)

PW date fields allow date strings such as "2020-00-01", as allowed by strtotime PHP function, but they will change upon save, with no warning.

This erases the value on 1st save if it would otherwise be changed, but if it's valid, erases on 2nd save:

$this->addHookAfter('InputfieldDatetime::processInput', function(HookEvent $event) {
    // Get the object the event occurred on, if needed
    $InputfieldDatetime = $event->object;

    // An 'after' hook can retrieve and/or modify the return value
    $return = $event->return;

    // Get values of arguments sent to hook (if needed)
    $input = $event->arguments(0);
    $fname = $InputfieldDatetime->attributes['name']; // 'dated';

    $new = $input[$fname];
    $old = $return->hasPage->$fname;

    /* Your code here, perhaps modifying the return value */

    $return->hasPage->$fname = '';

    // Populate back return value, if you have modified it
    $event->return = $return;
});

 

Edited by hellomoto
  • hellomoto changed the title to Hook to prevent date fields from changing incorrectly-formatted input values? (erase instead)
Posted (edited)

Why does this hook require saving 2x before applying the updated return value?

	function hookAfter_processInput(HookEvent $event) {
		// Get values of arguments sent to hook (if needed)
		$input = $event->arguments(0);
		$page = $event->return->hasPage;

		/* Your code here, perhaps modifying the return value */
		$fname = $event->object->attributes['name'];
		$field = wire('fields')->get($fname);
		if (is_null($field) || !in_array($field->id, $this->data['fields'])) return;

		$newvalue = $input->$fname;
		$existing = $event->return->hasPage->$fname;

		$ok = $this->validate_date($newvalue, $existing); 

		if ($ok) return;
		
		else {
			// Invalid:
			$event->return->hasPage->$fname = ''; // need to save 2x to affect ??
			// $page->of(false); $page->setAndSave($fname, '', ['noHooks' => true]); // nothing
			$this->error("Invalid date text input for field `".$page->getField($field)->get('label|name')."`: $newvalue");
		}
	}

 

Edited by hellomoto
Posted (edited)

This does not work:

// Prevent textual input from changing, e.g., if '2020-00-01' is entered, erase
$this->addHookAfter('InputfieldDatetime::processInput', function(HookEvent $event) {
    // Get the object the event occurred on, if needed
    $InputfieldDatetime = $event->object;

    // An 'after' hook can retrieve and/or modify the return value
    $return = $event->return;

    // Get values of arguments sent to hook (if needed)
    $input = $event->arguments(0);
    $page = $return->hasPage;
    $fname = $InputfieldDatetime->attributes['name'];

    $val = $input[$fname];
    // $old = $return->hasPage->$fname;
    // bd(date('Y-m-d', $old));

    /* Your code here, perhaps modifying the return value */
    $fmt = $page->getField($fname)->dateInputFormat;
    // bd($fmt);
    $new = date('Y-m-d', strtotime($val));
    if ($val == $new) return;
    // bd($val, $new);

    $this->wire->error(
        sprintf("Skipping field `%s` date string input: '%s' (format='%s')", 
        $page->getField($fname)->get('label|name'), $val, $fmt)
    );
    $return->hasPage->$fname = ''; // clear value

    // Populate back return value, if you have modified it
    $event->return = $return;
});

I guess it might be better hook sanitizeValue in the Fieldtype? Sorry I'm getting very confused.

The $event->return->hasPage->$fname has worked in prior tests, but I'm also confused because initially that property is set to the old value.

Edited by hellomoto

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...