ProcessWire 3.0.125 has several useful new $sanitizer methods and options, as well as new ways to access them directly from the $input API variable.
This makes dealing with user input even easier than it was before. This version also brings updates to our translation functions and improvements to our API documentation.
New available $sanitizer syntax options
One thing that’s been in the back of my mind for awhile is the desire to be able to specify sanitizers in a way that could easily be stored with settings, like module or field configuration. This need has come up a few times, and most recently while working on ProMailer. It lets you specify custom fields for your subscribers lists, and I needed a simple way to designate how fields should sanitize without a bunch of admin processes or code. Basically, I was looking for a simple way to pass text-based instructions into $sanitizer, have it process them, and then return a sanitized value.
That ability is now present, at least in its first iteration. You can call this:
$value = $sanitizer->sanitize($value, 'instructions');
...where the instructions are a CSV list of sanitizers to apply to the $value. For example, the following runs $value through $sanitizer->text() and then $sanitizer->entities, and then returns the value:
$value = $sanitizer->sanitize($value, 'text, entities');
If you append a number to any string sanitizer then it treats that as the maximum length that is applied as well:
$value = $sanitizer->sanitize($value, 'text50, entities');
The above says “sanitize value as text, limit length to 50 characters, and then entity encode it.”
One of the reasons for this sanitize() method is actually to support a shorter syntax, which is demonstrated below. It lets you specify any sanitizer(s) as a method call, and separate them with underscores:
$value = $sanitizer->text50_entities($value);
Most of the time an appended number refers to the max length. But for number-based sanitizers, it can refer to the action of the sanitizer. The only examples right now are the new min and max sanitizers which use the appended number to refer to the min/max value that they accept. Here we’ll combine the int, min and max sanitizers in one call. This call below is sanitizing to an integer between 1 and 100, like you might use for a percentage:
$percent = $sanitizer->int_min1_max100($value);
New $sanitizer methods
Several new $sanitizer methods were added in 3.0.125:
$sanitizer->range($value, $min, $max);
Sanitizes the given integer or float to the given range. details
$sanitizer->min($value, $min);
Sanitizes integer or float to be equal to or higher than $min. details
$sanitizer->max($value, $max);
Sanitizes integer or float to be no higher than $max. details
$sanitizer->bit($value);
Sanitize to bit (0 or 1). details
$sanitizer->maxLength($value, $maxLength);
Sanitize to given maximum length in characters. Works with strings, arrays, integers and floats. details
$sanitizer->maxBytes($value, $maxBytes);
Same as maxLength but uses bytes rather than characters and does not break multibyte characters. details
$sanitizer->sanitize($value, $method);
Sanitize $value using $method as the instructions containing one or more comma-separated sanitizers. details
$sanitizer->validate($value, $method, $fallback = null);
Works the same as the sanitize() method except that rather than sanitize it validates, returning the $fallback (null) if the $method instructions change something about the $value. If the $value does validate then it returns it. details
$sanitizer->valid($value, $method);
Like the validate() sanitizer except that it only returns true or false as to whether the value is valid or not according to the given $method instructions. details
Next are some upgrades to the $input API, which are very much related to these $sanitizer upgrades:
Input API variable upgrades
ProcessWire’s $input->get()
, $input->post()
and $input->cookie()
methods now support more arguments. Previously they just supported a single argument where you could provide the name of the input variable you wanted to retrieve. Below are some of the upgrades, along with examples of each. We are using $input->get() for these examples, but you can replace any of them with $input->post() or $input->cookie().
Provide a sanitization method as the 2nd argument to include sanitization in the return value. You can specify almost any sanitizer method available in the Sanitizer class:
// single sanitizer
$q = $input->get('q', 'text');
// multiple sanitizers
$q = $input->get('q', 'text,entities');
Numbers after any string sanitizer imply the maximum allowed length:
// text sanitizer, max length 40 chars
$q = $input->get('q', 'text40');
// maximum 3 digits
$q = $input->get('qty', 'digits3');
You can use the new min/max sanitizers with a number as well. In this case, they refer to the action of the sanitizer (minimum or maximum allowed value):
$q = $input->get('qty', 'int,min1,max10');
This is one of my favorites—provide an array of valid values (a whitelist) as the 2nd argument to limit input to those values:
$color = $input->get('color', [ 'red', 'blue', 'green' ]);
Provide a callback function that receives the value and returns a validated value:
$active = $input->get('active', function($val) {
return $val ? true : false;
});
Provide a fallback value as the 3rd argument to use if value not present:
// return 1 if no qty provided
$qty = $input->get('qty', 'int', 1);
// return red if no color selected
$color = $input->get('color', [ 'red', 'blue', 'green' ], 'red');
Append “[]” to the 1st argument to always force return value to be an array (regardless of whether it is in the input):
$value = $input->get('colors[]');
The ability to get input and sanitize it at the same time was previously only available with this syntax:
// text sanitizer can also be any other sanitizer
$val = $input->get->text('varName');
Of course, this still works. But you’ll be glad to know it has also been expanded to support multiple sanitizers and implied max-lengths the way the above syntax has. For instance these 3 calls below are equivalent. They are asking for a text string maximum 50 characters and then entity encoded:
// access sanitizer on $input as method
$q = $input->get->text50_entities('q');
// specify sanitizer as argument
$q = $input->get('q' , 'text50,entities');
// the original way, achives the same as the two above
$q = $sanitizer->entities($sanitizer->text($input->get('q'), [ 'maxLength' => 50 ]));
Upgrades to static translation functions
If you are familiar with the __('text');
function, this week it got some upgrades and new API documentation. It now supports the ability to specify options that affect future calls to it. There are only two options at present “entityEncode” and “translations”, though there may be more down the road, since it now supports the capability.
The entityEncode option lets you specify how you want it to handle future calls with regard to entity encoding. The translations option lets you specify an array of fallback translations to use when a value hasn’t yet been translated. I suspect most won’t need this often, but the need has come up here a couple of times so I went ahead and added it, and it’s available to use should you also need it sometime. Rather than re-writing all the details here, I’ll point you to the new documentation page for this function here.
Documentation improvements
ProcessWire’s API documentation is itself powered by static text in ProcessWire’s core code. The core code provides the actual content of the documentation, in addition to the delivery of it. This content is in phpdoc format (along with embedded markdown where helpful). Consistent with recently launching a new site, we’ve been making improvements to the API documentation section of the site. This means also improving the phpdoc documentation in the code that provides its content. ProcessWire 3.0.125 contains a whole lot of documentation improvements relative to 3.0.124. It also includes more complete documentation for our procedural functions, which previously didn’t have on-site documentation, but now do.
Thanks for reading and enjoy reading the ProcessWire Weekly this weekend as well. Have a great weekend!
Comments
Teppo
Hey Ryan!
Just wanted to say thanks for this week's updates. Brilliant stuff.
Those new Sanitizer methods look useful, valid() and validate() are a huge deal to me personally, and the whitelist thing for $input streamlines a lot of my code – great work! :)
Also, thanks for your continuous work on improving the documentation.
Have a great weekend!
Reply
Bacelo
- 6 years ago
- 112
★★★★★Hi Ryan,
I want to send you and all the supporters of ProcessWire a biiig "THANK YOU" for developing such an fantastic open source software!!!
Currently I'm working on my 3rd project based on ProcessWire and I love it - even more from day to day.
-> For me, it's the best CMS out there by far.
Best Regards from Hamburg/Germany
Bacelo
Reply