Martin Muzatko

validate field using ___processField

5 posts in this topic

Hello!

I'm trying to use the data I create in Processwire as much as possible.

So for a form, I try to use the fields description, name and also its built-in validation rules I defined in ProcessWire on the front-end. (minlength, ranges, patterns, etc)

I already looked into this tutorial, but it is using external resources to validate the form.

Since ProcessWire does all the heavy lifting, when processing data, I don't have to sanitize anything - ___processInput should do the job just fine.

However, it is not actually working correctly. 

$fields = $templates->get('user')->fields;
$submission = $input->post;
foreach ($submission as $key => $value) {
    $field = $fields->{$key};
    if ($field instanceof Field) {
        $field = $field->getInputfield($user);
        $field->___processInput(new WireInputData([$key => $value]));
        var_dump($field->getErrors(true)); // retrieve validation error
    }
}

This works for some constraints, but the values are not correctly validated.

Example: 

postman.thumb.jpg.f81575155a7d8cca2f22fe894089090a.jpg

All the fields are required and zip is an integer field.

Yet, I get no validation error for zip, although it was entered as a string, and not an integer. Funny enough: if I provide a number outside the range, I get "Specified value 2 removed because it is out of bounds (min=1000, max=99999)".
firstname will not return any error for being a required field.

From what I have looked through the source code, there is no check for "required". Some fields only validate on setAttribute. Am I missing anything or am I doomed to build my own validation process?

Thank you in advance!

Best,
Martin

Share this post


Link to post
Share on other sites

I've read a lot into this tutorial, which uses the built-in validation:

Thank you a lot for that @Soma!

Although, CSRF does not work correctly, so I read through this topic here: 

But I can't find a clue, why when ajax-posting to my form, this fails.

 

Share this post


Link to post
Share on other sites

@matjazp I'm not sure. I made it now work with the following:

 

$data = new WireInputData([
    'email' => $input->post->email,
    'username' => $input->post->username,
    'species' => $input->post->species,
    'firstname' => $input->post->firstname,
    'lastname' => $input->post->lastname,
    'password' => $input->post->password,
    'password_repeat' => $input->post->password_repeat,
    'email' => $input->post->email,
    'street' => $input->post->street,
    'zip' => $input->post->zip,
    'city' => $input->post->city,
    'country' => $input->post->country,
    'birthday' => $input->post->birthday
]);

$token = $session->CSRF->getTokenName();
$data->$token = $session->CSRF->getTokenValue();

$post = $input->post;
$post->setArray(array_merge($data->getArray(), $post->getArray()));

 

Share this post


Link to post
Share on other sites
3 hours ago, Martin Muzatko said:

$token = $session->CSRF->getTokenName(); 
$data->$token = $session->CSRF->getTokenValue();

 

You shouldn't use the actual token value you get from the session, you must use the value from the guest. The whole premise of CSRF (cross site request forgery) protection is to detect requests with invalid/missing tokens, so you know they're originated from a form on your site.

If you don't use the posted value (a field starting with TOKEN in $input->post and its value that is sent with the request) you're practically removing CSRF protection altogether.

2 people like this

Share this post


Link to post
Share on other sites

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.

  • Similar Content

    • By Cody Connor
      I am currently working on a website in process wire.  I created an image field and added svg as a valid file extension and could upload a png image and a jpg image but when I try to upload a svg image it is stuck loading at 100%.  I figured out that the image field does not take the extension svg even if I add it as an extension. and I was wondering if their is any way to upload a svg image to an image field in processwire?
      I am working with processwire version 3.0.61

    • By bmacnaughton
      I have a hook that creates a page for a subset of the pages on our site. It uses the saved page's name as part of the created page's name.
      The problem I am having is that my hook, attached to Pages::saved(), is being called even when the page save failed because of missing fields. Is there a way I can tell that the page save failed due to missing fields?
       
      Never mind - it does succeed; it just issues warnings about required fields.
       
    • By psy
      I've configured my PW site to use regions and mostly it's fabulous. However I encountered a strange problem when appending scripts to the body tag of a template. The body tag id is "bodyTag" (duh!).
      There are 3 scripts - two external and one inline. My first attempt was to append each script individually thinking they'd appear in the same order on the output:
      <script id="googlemapskey" type="text/javascript" src="https://maps.google.com/maps/api/js?key=XXXXXXXXXXXXXXXXXXXXXX" pw-append="bodyTag"></script> <script id="localMapsJS" type="text/javascript" src="<?=$bootstrap?>js/jquery.gmap.js" pw-append="bodyTag"></script> <script type="text/javascript" pw-append="bodyTag"> jQuery(document).ready(function($){ ... }); </script> Not so! Got lots of js errors and discovered the output had placed the scripts in the incorrect order, ie:
      <script type="text/javascript" pw-append="bodyTag"> jQuery(document).ready(function($){ ... }); </script> <script id="localMapsJS" type="text/javascript" src="/site/assets/mytheme/js/jquery.gmap.js"></script> <script id="googlemapskey" type="text/javascript" src="https://maps.google.com/maps/api/js?key=XXXXXXXXXXXXXXXXXXXXXX"></script> In other places I've appended multiple HTML regions to the same tag and it's worked fine. It only happens with scripts.
      After trying a few things, I discovered a workaround which was to wrap all the scripts into one div which is then appended to the body tag. This is OK but not ideal. I think (?), the partial is rendered in its entirety before being appended to the body tag:
      <div pw-append="bodyTag"> <script id="googlemapskey" type="text/javascript" src="https://maps.google.com/maps/api/js?key=XXXXXXXXXXXXXXXXXXXXXX"></script> <script id="localMapsJS" type="text/javascript" src="<?=$bootstrap?>js/jquery.gmap.js"></script> <script type="text/javascript" pw-append="bodyTag"> jQuery(document).ready(function($){ ... }); </script> </div> Curious to know where I went wrong in the first example with each script appended individually or is this behaviour with scripts an undocumented feature of regions?
      Using PW 3.0.61 with both Chrome and Firefox
    • By Harmen
      Hi folks,
       
      On the website I am working on I do have a form which needs to be filled in (duh) and when the user clicks on download, the data is send with ajax and processed in the same file by using the ProcessWire API with $config->ajax;
      The data which is provided by the user will be checked with data in my database. If the data is correct I want to push a file download. But this is not working at the moment. It seems like the content of the (.exe) file is pasted in the console instead of pushing the file. My code looks like this:
      if ($config->ajax){ $serial = $input->post('serial'); $DB = DB(); $query = $DB->prepare("/*My query here*/"); $query->bindParam("comparision", $serial, PDO::PARAM_STR); $query->execute(); $reply = ''; $SN_rows = $query->rowCount(); if (!$SN_rows > 0) { $reply = 'error'; } else { $reply = 'success'; $installer = $page->attachments->eq(1); $filename = "Filename"; $filepath = $installer->filename; $options = array( 'forceDownload' => true, 'exit' => true, 'downloadFilename' => $filename ); wireSendFile($filepath, $options); } echo $reply; exit(); } What am I doing wrong here or is it a bug? Is there another way to do this with the processwire API?
       
      Thanks in advance,
       
      ~Harmen
    • By nbcommunication
      Hi,
      I'm sure this is maybe in the works already, given that findMany() is a recent addition to the API, but having this (and the other new find options) available to $users would be a great addition.
      Cheers,
      Chris
      NB Communication