Quick search:

How to convert and validate user input

PhpPeanuts can automatically convert and validate user input and report mistakes back to the user. This happens through a series of steps, that are taken care of by different objects.

Let's assume the user entered some data into the form of an EditDetailsPage and presses 'Update'. The form is then submitted by the browser to the server, usually leading it to be processed by an ObjectSaveAction. The first thing the ObjectSaveAction will do is retrieve the object that needs to be updated. It will do this using the pntType and id parameters. This object is called the 'requested object'.

Next the ObjectSaveAction will build an array of FormNavValue called the formTexts. These formTexts are used to hold the values from the form and eventual errors from the processing, so that all values can be processed frist and then all eventual errors can be reported at once. For each property that is edited in the EditDetailsPage, one formText is created and initalized

Once the formTexts have been built and initialized, StringConverters are invoked to convert the strings the user has entered into values of the correct type. What type that is depends on the propertyDescriptor of the property the form field corresponds to. If the propertyDescriptor's type is 'number', the StringConverter will attemp to convert the string to an integer or float, according to the numberformat that was specified on the StringConvertor. See how to localize data formats to modify these specifications.

If there are no errors from the conversions, the SaveAction will have the requested object validate the values one by one. This is done by calling the objects validateGetErrorString method for each of the formTexts. Usually the objects inherited method will handle this call, but if you like you can override it to specialize the validations. If you don't, the inherited method will get a validator from the propertyDescriptor and have it validat the value. The validator will already be initialized according to the propertyDescriptor, so if the propertyDescriptor's 'minValue'has been set to 10, the validator will return an error message if the value is below 10.

ValueValidators will check numeric, date, time and timestamp values are against minimum and maximum value as set on the propertyDescriptor, or against the higest and lowest possible value if no minumum or maximum has been set. Strings are checked for minimum and maximum length if specified on the propertyDescriptor. All values are checked for null if a minumum length is specified larger then 0: the property is said to be compulsory. Version 1.2 and up show an asterisk in the editDetailsForm if a property is compulsory. Single value derived properties are also cumpulsory if their idPropterty is compulsory.

Validation or conversion error messages will be put into the formTexts so that they can be reported back to the user later. So if you have a column in a table specified to be 'not null', set the corresponding property to a minimum length larger then 0, and the user will get an error if he enters nothing.

ValueValidators will also check selections that are made by the user using either a select widget (dropdown) or a dialog widget (opens a dialog for search and selection). Though these widgets suggest the selction of objects, the form will only pass values according to the selection. So the values must in some way be be processed to actually get the corresponding objects. This is actually not done by the ObjectSaveAction. ObjectSaveAction simply sees them as values for properties that hold the id's. It will just convert and check them like normal values. Additionally, if the derivedPropertyDescriptor that uses the id has a minimum length larger then 0, it will check against null values. 

When all values in the formTexts are found to be valid, they are set to the properties of the requested object. Then the object is again asked to validate. This time the object validates itself, so that it can check for combinations of values, maybe also with combinations with other data that came from the database when the object was retrieved or maybe for combinations with data from other objects it retrieves from the database. This is all up to you to program into the getSaveErrorMessages method on the object's class. By default the inherited method will not do any validations and simply return an empty array.

If the SaveAction gets this far without finding any error messages, it will finally call save on the object so that the object will update the database. In case of errors the formTexts are passed to an EditDetailsPage that will show the error messages and output a new form with the values exactly as the user entered them so that the user can correct them instead of having to start from scratch.

ObjectSaveAction supplies default behavior for processing forms from EditDetailsPages. If you need specific handling on the level of form parameters, you can make a subclass of ObjectSaveAction, like EmployeeSaveAction, to handle a specific type (in this case Employee), or you can put a different value for the pntHandler parameter in the form. In the specific SaveAction class you can override the default behavion however you like.