-
Notifications
You must be signed in to change notification settings - Fork 0
Docs Request Broker
When working with forms you often find yourself in doing the same work again and again: Reading data from the request, checking for validity and filtering the request values, and if the data is correct putting it into the right classes. Why not simplify this process for simple input stuff? This is the basic idea of the request broker.
The request broker takes any object, checks each public non-static property and method for an annotation of type [source:trunk/src/main/php/net/stubbles/ipo/request/broker/annotations/stubFilterAnnotation.php] which in turn can create the filter object used by the broker to pull the data from the request. If anything other then null is returned from the request (null will be returned if the request value is not present or in case the filter detected errors) it the property will be populated with the value (or the method will be called with the value as its argument).
See request broker example on our examples page.
Filters floats. Can be customized with minValue and maxValue, but both are optional: @Filter[FloatFilter](minValue=2, maxValue=40)
Used error ids can be customized with minErrorId and maxErrorId, both are optional: @Filter[FloatFilter](minValue=2, maxValue=40, minErrorId='FOO_ERROR_ID', maxErrorId='BAR_ERROR_ID')
Filters integers. Can be customized with minValue and maxValue, but both are optional: @Filter[IntegerFilter](minValue=2, maxValue=40)
Used error ids can be customized with minErrorId and maxErrorId, both are optional: @Filter[IntegerFilter](minValue=2, maxValue=40, minErrorId='FOO_ERROR_ID', maxErrorId='BAR_ERROR_ID')
Filters URLs of type HTTP and HTTPS: @Filter[HTTPURLFilter]
Filters mail addresses: @Filter[MailFilter]
Filters passwords. Can be customized with minLength. If this value is not set the minimum length of the password will default to 6. @Filter[PasswordFilter](minLength=8)
The type of the password encoding can be changed with the encoder property: @Filter[PasswordFilter](encoder=my.own.package.MyOwnEncoder.class) If not set the default encoding of a password will be md5.
Filters strings. Removes line breaks and tags. Can be customized with minLength and maxLength. A regular expression must be supplied with regex. @Filter[StringFilter](minLength=4, maxLength=10, regex='/([a-z]*)/') Can also be used as: @Filter[StringFilter](regex='/^[a-z]{4,10}$/')
The error ids for min length and max length validation are customizable: @Filter[StringFilter](minLength=4, minLengthErrorId='FOO_ERROR_ID', maxLength=10, maxLengthErrorId='BAR_ERROR_ID', regex='/([a-z]*)/') Both are optional.
The filter can apply an encoder onto the value to filter with the encoder property: @Filter[StringFilter](regex='/^[a-z]{4,10}$/', encoder=my::own::package::MyOwnEncoder.class, encoderMode=stubStringEncoder::MODE_ENCODE) If not set no encoder will be applied. The encoderMode property is optional, if not set the value will default to stubStringEncoder::MODE_DECODE. If any other value than stubStringEncoder::MODE_DECODE or stubStringEncoder::MODE_ENCODE is set the annotation API will throw an exception when retrieving the annotation.
Filters texts. Removes line breaks of type \r. Removes tags, but it is possible to supply a list of allowed tags. However this option should be used very careful. Allowing certain tags does not protect against cross-site-scripting attacks! @Filter[TextFilter] - no tags allowed. @Filter[TextFilter](allowedTags='b,i,em,bold') - strips all tags except <b>, <i>, <em> and <bold> and their closing counterparts.
The filter can apply an encoder onto the value to filter with the encoder property: @Filter[TextFilter](encoder=my::own::package::MyOwnEncoder.class, encoderMode=stubStringEncoder::MODE_ENCODE) If not set no encoder will be applied. The encoderMode property is optional, if not set the value will default to stubStringEncoder::MODE_DECODE. If any other value than stubStringEncoder::MODE_DECODE or stubStringEncoder::MODE_ENCODE is set the annotation API will throw an exception when retrieving the annotation.
Filters a value out of a list of preselected values. The list comes from a class named with the sourceDataClass property. The method stated with the sourceDataMethod will be invoked statically and needs to return an array containing of allowed values. If none of these equals the request input an error will with given errorId be set. Both sourceDataMethod and errorId are optional. If no sourceDataMethod is set it will fallback to a method getData() which needs to be defined within the given class. If no errorId is set it will fallback to FIELD_WRONG_VALUE. @Filter[PreselectFilter](sourceDataClass=my::own::package::ListProvider.class, sourceDataMethod='getCategories', errorId='INCORRECT_SELECTION')
Filters dates into instances of type net::stubbles::lang::types::stubDate. Most basic usage: @Filter[DateFilter]
This does no checks whether the date is in a valid range, but only if the given value is a date. To check if the date is inbetween a certain range the annotation allows to define the min and max date: @Filter[DateFilter](minDate='now', maxDate='+7 days')
Every date form supported by date_create() can be used: unix timestamps, dates or strings as supported by strtotime().
Not every time it is possible to write the min date and max date into the annotation directly, but it is required to set the values dynamically. To use a more dynamic approach one may reference a provider class: @Filter[DateFilter](minDateProviderClass=my::own::package::DateProvider.class, maxDateProviderClass=my::own::package::DateProvider.class)
By default the provider class needs to have the methods getMinDate() and getMaxDate() then. If the methods in the provider class are different, they must be stated within the annotation:
@Filter[DateFilter](minDateProviderClass=my::own::package::DateProvider.class, minDateProviderMethod='getMinimumDate', maxDateProviderClass=my::own::package::DateProvider.class, maxDateProviderMethod='getMaximumDate' )
The return value of the provider method may be a unix timestamp, an instance of net::stubbles::lang::types::stubDate or a string supported by strtotime().
Please note that the provider class is only utilized if no values for the minDate and/or maxDate properties are supplied. This means you can even use a mix of both: @Filter[DateFilter](minDateProviderClass=my::own::package::DateProvider.class, maxDate='now') or vice versa.
It is possible to only define a minimum date or a maximum date: @Filter[DateFilter](minDate='now') This filter accepts all dates starting today and in the future.
@Filter[DateFilter](maxDate='now') This filter accepts all dates from the past and today. Both ways can be used with providers as well.
To change the way dates are formatted in error messages set the dateFormat property: @Filter[DateFilter](maxDate='now', dateFormat='d/m/Y') It accepts all formats supported by date().
All filters are set to require the value by default, but every filter annotation can be set as required or not: @Filter[IntegerFilter](required=false)
Sometimes it is required to have a different or modified filter instead of the annotated filter. The request broker allows overruling of annotated filters:
#php $overrulingFilters = array('prefix_my_fieldname' => stubFilterFactory::forType('string')); $requestBroker->process($request, $object, 'prefix_', $overrulingFilters);
Here, the value for a property or method with a filter annotation for the request value prefix_my_fieldname will be overruled with the filter instance given with the array $overrulingFilters, the annotated filter will be ignored.
As it is possible to define your own filters it is possible to define your own filter annotations. Basically you just need to implement the [source:trunk/src/main/php/net/stubbles/ipo/request/filter/annotation/stubFilterAnnotationReader.php] interface. To save some work you may extend the [source:trunk/src/main/php/net/stubbles/ipo/request/filter/annotation/stubAbstractFilterAnnotationReader.php] class. If you do this you just have to implement protected function doCreateFilter() where the filter instance is created.
#php class ExampleFilterAnnotationReader extends stubAbstractFilterAnnotationReader { /** ***creates filter from given annotation * ***@param stubFilterFactory $filterFactory ***@param stubAnnotation $filterAnnotation ***@return stubFilterBuilder ***/ protected function doCreateFilter(stubFilterFactory $filterFactory, stubAnnotation $filterAnnotation) { return $filterFactory->createForType('example'); } }
Now, add the annotation reader:
$ipoBindingModule->addFilterAnnotationReader('my::package::filter::ExampleFilterAnnotationReader', 'ExampleFilter');
Afterwards, you can use the annotation: @Filter[ExampleFilter]
In case you have a module which provides filter annotation readers you can add them to be automatically available and detected by the framework. To enable this you need to have a file ipo/filter.ini in your star file. The content of the file should look like this:
[annotationReader] ExampleFilter=my::package::filter::ExampleFilterAnnotationReader
With this and the star module within the lib directory of an application the application will automatically recognize @Filter[ExampleFilter] without adding it manually as described above.