Validation-Class-7.900059000755000765000024 014410403624 15533 5ustar00christiaanstaff000000000000README100644000765000024 11233414410403624 16540 0ustar00christiaanstaff000000000000Validation-Class-7.900059SYNOPSIS use Validation::Class::Simple::Streamer; my $params = {username => 'admin', password => 's3cret'}; my $input = Validation::Class::Simple::Streamer->new(params => $params); # check username parameter $input->check('username')->required->between('5-255'); $input->filters([qw/trim strip/]); # check password parameter $input->check('password')->required->between('5-255')->min_symbols(1); $input->filters([qw/trim strip/]); # run validate $input->validate or die $input->errors_to_string; DESCRIPTION Validation::Class is a scalable data validation library with interfaces for applications of all sizes. The most common usage of Validation::Class is to transform class namespaces into data validation domains where consistency and reuse are primary concerns. Validation::Class provides an extensible framework for defining reusable data validation rules. It ships with a complete set of pre-defined validations and filters referred to as "directives". The core feature-set consist of self-validating methods, validation profiles, reusable validation rules and templates, pre and post input filtering, class inheritance, automatic array handling, and extensibility (e.g. overriding default error messages, creating custom validators, creating custom input filters and much more). Validation::Class promotes DRY (don't repeat yourself) code. The main benefit in using Validation::Class is that the architecture is designed to increase the consistency of data input handling. The following is a more traditional usage of Validation::Class, using the DSL to construct a validator class: package MyApp::Person; use Validation::Class; # data validation template mixin basic => { required => 1, max_length => 255, filters => [qw/trim strip/] }; # data validation rules for the username parameter field username => { mixin => 'basic', min_length => 5 }; # data validation rules for the password parameter field password => { mixin => 'basic', min_length => 5, min_symbols => 1 }; package main; my $person = MyApp::Person->new(username => 'admin', password => 'secr3t'); # validate rules on the person object unless ($person->validates) { # handle the failures warn $person->errors_to_string; } 1; QUICKSTART If you are looking for a simple in-line data validation module built using the same tenets and principles as Validation::Class, please review Validation::Class::Simple or Validation::Class::Simple::Streamer. If you are new to Validation::Class, or would like more information on the underpinnings of this library and how it views and approaches data validation, please review Validation::Class::Whitepaper. Please review the "GUIDED-TOUR" in Validation::Class::Cookbook for a detailed step-by-step look into how Validation::Class works. UPGRADE Validation::Class is stable, its feature-set is complete, and is currently in maintenance-only mode, i.e. Validation::Class will only be updated with minor enhancements and bug fixes. However, the lessons learned will be incorporated into a compelete rewrite uploaded under the namespace Validation::Interface. The Validation::Interface fork is designed to have a much simpler API with less options and better execution, focused on validating hierarchical data as its primarily objective. The adopt keyword (or adt) copies configuration and functionality from other Validation::Class classes. The adopt keyword takes three arguments, the name of the class to be introspected, and the configuration type and name to be recreated. Basically, anything you can configure using a Validation::Class keyword can be adopted into other classes using this keyword with the exception of coderefs registered using the build keyword. Please note! If you are adopting a field declaration which has an associated mixin directive defined on the target class, you must adopt the mixin explicitly if you wish it's values to be interpolated. package MyApp::Exployee; use Validate::Class; use MyApp::Person; adopt MyApp::Person, mixin => 'basic'; adopt MyApp::Person, field => 'first_name'; adopt MyApp::Person, field => 'last_name'; adopt MyApp::Person, profile => 'has_fullname'; 1; The attribute keyword (or has) registers a class attribute, i.e. it creates an accessor (getter and setter) on the class. Attribute declaration is flexible and only requires an attribute name to be configured. Additionally, the attribute keyword can takes two arguments, the attribute's name and a scalar or coderef to be used as it's default value. package MyApp::Person; use Validate::Class; attribute 'first_name' => 'Peter'; attribute 'last_name' => 'Venkman'; attribute 'full_name' => sub { join ', ', $_[0]->last_name, $_[0]->first_name }; attribute 'email_address'; 1; The build keyword (or bld) registers a coderef to be run at instantiation much in the same way the common BUILD routine is used in modern OO frameworks. package MyApp::Person; use Validation::Class; build sub { my ($self, $args) = @_; # run after instantiation in the order defined }; 1; The build keyword takes one argument, a coderef which is passed the instantiated class object. The directive keyword (or dir) registers custom validator directives to be used in your field definitions. Please note that custom directives can only be used with field definitions. This is a means of extending the list of directives per instance. See the list of core directives, Validation::Class::Directives, or review Validation::Class::Directive for insight into creating your own CPAN installable directives. package MyApp::Person; use Validate::Class; # define a custom class-level directive directive 'blacklisted' => sub { my ($self, $field, $param) = @_; if (defined $field->{blacklisted} && defined $param) { if ($field->{required} || $param) { if (exists_in_blacklist($field->{blacklisted}, $param)) { my $handle = $field->label || $field->name; $field->errors->add("$handle has been blacklisted"); return 0; } } } return 1; }; field 'email_address' => { blacklisted => '/path/to/blacklist' email => 1, }; 1; The directive keyword takes two arguments, the name of the directive and a coderef which will be used to validate the associated field. The coderef is passed four ordered parameters; a directive object, the class prototype object, the current field object, and the matching parameter's value. The validator (coderef) is evaluated by its return value as well as whether it altered any error containers. The document keyword (or doc) registers a data matching profile which can be used to validate heiarchal data. It will store a hashref with pre-define path matching rules for the data structures you wish to validate. The "path matching rules", which use a specialized object notation, referred to as the document notation, can be thought of as a kind-of simplified regular expression which is executed against the flattened data structure. The following are a few general use-cases: package MyApp::Person; use Validation::Class; field 'string' => { mixin => [':str'] }; # given this JSON data structure { "id": "1234-A", "name": { "first_name" : "Bob", "last_name" : "Smith", }, "title": "CIO", "friends" : [], } # select id to validate against the string rule document 'foobar' => { 'id' => 'string' }; # select name -> first_name/last_name to validate against the string rule document 'foobar' => {'name.first_name' => 'string', 'name.last_name' => 'string'}; # or document 'foobar' => {'name.*_name' => 'string'}; # select each element in friends to validate against the string rule document 'foobar' => { 'friends.@' => 'string' }; # or select an element of a hashref in each element in friends to validate # against the string rule document 'foobar' => { 'friends.@.name' => 'string' }; The document declaration's keys should follow the aforementioned document notation schema and it's values should be strings which correspond to the names of fields (or other document declarations) that will be used to preform the data validation. It is possible to combine document declarations to validate hierarchical data that contains data structures matching one or more document patterns. The following is an example of what that might look like. package MyApp::Person; use Validation::Class; # data validation rule field 'name' => { mixin => [':str'], pattern => qr/^[A-Za-z ]+$/, max_length => 20, }; # data validation map / document notation schema document 'friend' => { 'name' => 'name' }; # data validation map / document notation schema document 'person' => { 'name' => 'name', 'friends.@' => 'friend' }; package main; my $data = { "name" => "Anita Campbell-Green", "friends" => [ { "name" => "Horace" }, { "name" => "Skinner" }, { "name" => "Alonzo" }, { "name" => "Frederick" }, ], }; my $person = MyApp::Person->new; unless ($person->validate_document(person => $data)) { warn $person->errors_to_string if $person->error_count; } 1; Alternatively, the following is a more verbose data validation class using traditional styling and configuration. package MyApp::Person; use Validation::Class; field 'id' => { mixin => [':str'], filters => ['numeric'], max_length => 2, }; field 'name' => { mixin => [':str'], pattern => qr/^[A-Za-z ]+$/, max_length => 20, }; field 'rating' => { mixin => [':str'], pattern => qr/^\-?\d+$/, }; field 'tag' => { mixin => [':str'], pattern => qr/^(?!evil)\w+/, max_length => 20, }; document 'person' => { 'id' => 'id', 'name' => 'name', 'company.name' => 'name', 'company.supervisor.name' => 'name', 'company.supervisor.rating.@.*' => 'rating', 'company.tags.@' => 'name' }; package main; my $data = { "id" => "1234-ABC", "name" => "Anita Campbell-Green", "title" => "Designer", "company" => { "name" => "House of de Vil", "supervisor" => { "name" => "Cruella de Vil", "rating" => [ { "support" => -9, "guidance" => -9 } ] }, "tags" => [ "evil", "cruelty", "dogs" ] }, }; my $person = MyApp::Person->new; unless ($person->validate_document(person => $data)) { warn $person->errors_to_string if $person->error_count; } 1; Additionally, the following is yet another way to validate a document by passing the document specification directly instead of by name. package MyApp::Person; use Validation::Class; package main; my $data = { "id" => "1234-ABC", "name" => "Anita Campbell-Green", "title" => "Designer", "company" => { "name" => "House of de Vil", "supervisor" => { "name" => "Cruella de Vil", "rating" => [ { "support" => -9, "guidance" => -9 } ] }, "tags" => [ "evil", "cruelty", "dogs" ] }, }; my $spec = { 'id' => { max_length => 2 }, 'name' => { mixin => ':str' }, 'company.name' => { mixin => ':str' }, 'company.supervisor.name' => { mixin => ':str' }, 'company.supervisor.rating.@.*' => { pattern => qr/^(?!evil)\w+/ }, 'company.tags.@' => { max_length => 20 }, }; my $person = MyApp::Person->new; unless ($person->validate_document($spec => $data)) { warn $person->errors_to_string if $person->error_count; } 1; The ensure keyword (or ens) is used to convert a pre-existing method into an auto-validating method. The auto-validating method will be registered and function as if it was created using the method keyword. The original pre-existing method will be overridden with a modified version which performs the pre and/or post validation routines. package MyApp::Person; use Validation::Class; sub register { ... } ensure register => { input => ['name', '+email', 'username', '+password', '+password2'], output => ['+id'], # optional output validation, dies on failure }; package main; my $person = MyApp::Person->new(params => $params); if ($person->register) { # handle the successful registration } 1; The ensure keyword takes two arguments, the name of the method to be overridden and a hashref of required key/value pairs. The hashref may have an input key (e.g. input, input_document, input_profile, or input_method). The `input` key (specifically) must have a value which must be either an arrayref of fields to be validated, or a scalar value which matches (a validation profile or auto-validating method name). The hashref may also have an output key (e.g. output, output_document, output_profile, or output_method). The `output` key (specifically) must have a value which must be either an arrayref of fields to be validated, or a scalar value which matches (a validation profile or auto-validating method name). Whether and what the method returns is yours to decide. The method will return undefined if validation fails. The ensure keyword wraps and functions much in the same way as the method keyword. The field keyword (or fld) registers a data validation rule for reuse and validation in code. The field name should correspond with the parameter name expected to be passed to your validation class or validated against. package MyApp::Person; use Validation::Class; field 'username' => { required => 1, min_length => 1, max_length => 255 }; The field keyword takes two arguments, the field name and a hashref of key/values pairs known as directives. For more information on pre-defined directives, please review the "list of core directives". The field keyword also creates accessors which provide easy access to the field's corresponding parameter value(s). Accessors will be created using the field's name as a label having any special characters replaced with an underscore. # accessor will be created as send_reminders field 'send-reminders' => { length => 1 }; Please note that prefixing field names with a double plus-symbol instructs the register to merge your declaration with any pre-existing declarations within the same scope (e.g. fields imported via loading roles), whereas prefixing field names with a single plus-symbol instructs the register to overwrite any pre-existing declarations. package MyApp::Person; use Validation::Class; set role => 'MyApp::User'; # append existing field and overwrite directives field '++email_address' => { required => 1 }; # redefine existing field field '+login' => { required => 1 }; 1; The filter keyword (or flt) registers custom filters to be used in your field definitions. It is a means of extending the pre-existing filters declared by the "filters directive" before instantiation. package MyApp::Person; use Validate::Class; filter 'flatten' => sub { $_[0] =~ s/[\t\r\n]+/ /g; return $_[0]; }; field 'biography' => { filters => ['trim', 'strip', 'flatten'] }; 1; The filter keyword takes two arguments, the name of the filter and a coderef which will be used to filter the value the associated field. The coderef is passed the value of the field and that value MUST be operated on directly. The coderef should also return the transformed value. The load keyword (or set), which can also be used as a class method, provides options for extending the current class by declaring roles, requirements, etc. The process of applying roles, requirement, and other settings to the current class mainly involves introspecting the namespace's methods and merging relevant parts of the prototype configuration. The `classes` (or class) option uses Module::Find to load all child classes (in-all-subdirectories) for convenient access through the "class" in Validation::Class::Prototype method, and when introspecting a larger application. This option accepts an arrayref or single argument. package MyApp; use Validation::Class; load classes => ['MyApp::Domain1', 'MyApp::Domain2']; package main; my $app = MyApp->new; my $person = $app->class('person'); # return a new MyApp::Person object 1; package MyApp::User; use Validate::Class; load requirements => 'activate'; package MyApp::Person; use Validation::Class; load role => 'MyApp::User'; sub activate {} 1; The `requirements` (or required) option is used to ensure that if/when the class is used as a role the calling class has specific pre-existing methods. This option accepts an arrayref or single argument. package MyApp::User; use Validate::Class; load requirements => ['activate', 'deactivate']; 1; package MyApp::Person; use Validation::Class; load role => 'MyApp::User'; 1; The `roles` (or role) option is used to load and inherit functionality from other validation classes. These classes should be used and thought-of as roles although they can also be fully-functioning validation classes. This option accepts an arrayref or single argument. package MyApp::Person; use Validation::Class; load roles => ['MyApp::User', 'MyApp::Visitor']; 1; The message keyword (or msg) registers a class-level error message template that will be used in place of the error message defined in the corresponding directive class if defined. Error messages can also be overridden at the individual field-level as well. See the Validation::Class::Directive::Messages for instructions on how to override error messages at the field-level. package MyApp::Person; use Validation::Class; field email_address => { required => 1, min_length => 3, messages => { # field-level error message override min_length => '%s is not even close to being a valid email address' } }; # class-level error message overrides message required => '%s is needed to proceed'; message min_length => '%s needs more characters'; 1; The message keyword takes two arguments, the name of the directive whose error message you wish to override and a string which will be used to as a template which is feed to sprintf to format the message. The method keyword (or mth) is used to register an auto-validating method. Similar to method signatures, an auto-validating method can leverage pre-existing validation rules and profiles to ensure a method has the required pre/post-conditions and data necessary for execution. package MyApp::Person; use Validation::Class; method 'register' => { input => ['name', '+email', 'username', '+password', '+password2'], output => ['+id'], # optional output validation, dies on failure using => sub { my ($self, @args) = @_; # do something registrationy $self->id(...); # set the ID field for output validation return $self; } }; package main; my $person = MyApp::Person->new(params => $params); if ($person->register) { # handle the successful registration } 1; The method keyword takes two arguments, the name of the method to be created and a hashref of required key/value pairs. The hashref may have a `using` key whose value is the coderef to be executed upon successful validation. The `using` key is only optional when a pre-existing subroutine has the same name or the method being declared prefixed with a dash or dash-process-dash. The following are valid subroutine names to be called by the method declaration in absence of a `using` key. Please note, unlike the ensure keyword, any pre-existing subroutines will not be wrapped-and-replaced and can be executed without validation if called directly. sub _name { ... } sub _process_name { ... } The hashref may have an input key (e.g. input, input_document, input_profile, or input_method). The `input` key (specifically) must have a value which must be either an arrayref of fields to be validated, or a scalar value which matches (a validation profile or auto-validating method name), which will be used to perform data validation before the aforementioned coderef has been executed. Whether and what the method returns is yours to decide. The method will return undefined if validation fails. # alternate usage method 'registration' => { input => ['name', '+email', 'username', '+password', '+password2'], output => ['+id'], # optional output validation, dies on failure }; sub _process_registration { my ($self, @args) = @_; $self->id(...); # set the ID field for output validation return $self; } Optionally the hashref may also have an output key (e.g. output, output_document, output_profile, or output_method). The `output` key (specifically) must have a value which must be either an arrayref of fields to be validated, or a scalar value which matches (a validation profile or auto-validating method name), which will be used to perform data validation after the aforementioned coderef has been executed. Please note that output validation failure will cause the program to die, the premise behind this decision is based on the assumption that given successfully validated input a routine's output should be predictable and if an error occurs it is most-likely a program error as opposed to a user error. See the ignore_failure and report_failure attributes on the prototype to control how method validation failures are handled. The mixin keyword (or mxn) registers a validation rule template that can be applied (or "mixed-in") to any field by specifying the mixin directive. Mixin directives are processed first so existing field directives will override any directives created by the mixin directive. package MyApp::Person; use Validation::Class; mixin 'boilerplate' => { required => 1, min_length => 1, max_length => 255 }; field 'username' => { # min_length, max_length, .. required will be overridden mixin => 'boilerplate', required => 0 }; Since version 7.900015, all classes are automatically configured with the following default mixins for the sake of convenience: mixin ':flg' => { required => 1, min_length => 1, filters => [qw/trim strip numeric/], between => [0, 1] }; mixin ':num' => { required => 1, min_length => 1, filters => [qw/trim strip numeric/] }; mixin ':str' => { required => 1, min_length => 1, filters => [qw/trim strip/] }; Please note that the aforementioned mixin names are prefixed with a semi-colon but are treated as an exception to the rule. Prefixing mixin names with a double plus-symbol instructs the register to merge your declaration with any pre-existing declarations within the same scope (e.g. mixins imported via loading roles), whereas prefixing mixin names with a single plus-symbol instructs the register to overwrite any pre-existing declarations. package MyApp::Moderator; use Validation::Class; set role => 'MyApp::Person'; # overwrite and append existing mixin mixin '++boilerplate' => { min_symbols => 1 }; # redefine existing mixin mixin '+username' => { required => 1 }; 1; The mixin keyword takes two arguments, the mixin name and a hashref of key/values pairs known as directives. The new method instantiates a new class object, it performs a series of actions (magic) required for the class to function properly, and for that reason, this method should never be overridden. Use the build keyword for hooking into the instantiation process. In the event a foreign (pre-existing) `new` method is detected, an `initialize_validator` method will be injected into the class containing the code (magic) necessary to normalize your environment. package MyApp::Person; use Validation::Class; # hook build sub { my ($self, @args) = @_; # on instantiation }; sub new { # rolled my own my $self = bless {}, shift; # execute magic $self->initialize_validator; } 1; The profile keyword (or pro) registers a validation profile (coderef) which as in the traditional use of the term is a sequence of validation routines that validates data relevant to a specific action. package MyApp::Person; use Validation::Class; profile 'check_email' => sub { my ($self, @args) = @_; if ($self->email_exists) { my $email = $self->fields->get('email'); $email->errors->add('Email already exists'); return 0; } return 1; }; package main; my $user = MyApp::Person->new(params => $params); unless ($user->validate_profile('check_email')) { # handle failures } 1; The profile keyword takes two arguments, a profile name and coderef which will be used to execute a sequence of actions for validation purposes. The prototype method (or proto) returns an instance of the associated class prototype. The class prototype is responsible for manipulating and validating the data model (the class). It is not likely that you'll need to access this method directly, see Validation::Class::Prototype. package MyApp::Person; use Validation::Class; package main; my $person = MyApp::Person->new; my $prototype = $person->prototype; 1; PROXY METHODS Validation::Class mostly provides sugar functions for modeling your data validation requirements. Each class you create is associated with a prototype class which provides the data validation engine and keeps your class namespace free from pollution, please see Validation::Class::Prototype for more information on specific methods and attributes. Validation::Class injects a few proxy methods into your class which are basically aliases to the corresponding prototype class methods, however it is possible to access the prototype directly using the proto/prototype methods. =proxy_method class $self->class; See "class" in Validation::Class::Prototype for full documentation. =proxy_method clear_queue $self->clear_queue; See "clear_queue" in Validation::Class::Prototype for full documentation. =proxy_method error_count $self->error_count; See "error_count" in Validation::Class::Prototype for full documentation. =proxy_method error_fields $self->error_fields; See "error_fields" in Validation::Class::Prototype for full documentation. =proxy_method errors $self->errors; See "errors" in Validation::Class::Prototype for full documentation. =proxy_method errors_to_string $self->errors_to_string; See "errors_to_string" in Validation::Class::Prototype for full documentation. =proxy_method get_errors $self->get_errors; See "get_errors" in Validation::Class::Prototype for full documentation. =proxy_method get_fields $self->get_fields; See "get_fields" in Validation::Class::Prototype for full documentation. =proxy_method get_hash $self->get_hash; See "get_hash" in Validation::Class::Prototype for full documentation. =proxy_method get_params $self->get_params; See "get_params" in Validation::Class::Prototype for full documentation. =proxy_method get_values $self->get_values; See "get_values" in Validation::Class::Prototype for full documentation. =proxy_method fields $self->fields; See "fields" in Validation::Class::Prototype for full documentation. =proxy_method filtering $self->filtering; See "filtering" in Validation::Class::Prototype for full documentation. =proxy_method ignore_failure $self->ignore_failure; See "ignore_failure" in Validation::Class::Prototype for full documentation. =proxy_method ignore_intervention $self->ignore_intervention; See "ignore_intervention" in Validation::Class::Prototype for full documentation. =proxy_method ignore_unknown $self->ignore_unknown; See "ignore_unknown" in Validation::Class::Prototype for full documentation. =proxy_method is_valid $self->is_valid; See "is_valid" in Validation::Class::Prototype for full documentation. =proxy_method param $self->param; See "param" in Validation::Class::Prototype for full documentation. =proxy_method params $self->params; See "params" in Validation::Class::Prototype for full documentation. =proxy_method plugin $self->plugin; See "plugin" in Validation::Class::Prototype for full documentation. =proxy_method queue $self->queue; See "queue" in Validation::Class::Prototype for full documentation. =proxy_method report_failure $self->report_failure; See "report_failure" in Validation::Class::Prototype for full documentation. =proxy_method report_unknown $self->report_unknown; See "report_unknown" in Validation::Class::Prototype for full documentation. =proxy_method reset_errors $self->reset_errors; See "reset_errors" in Validation::Class::Prototype for full documentation. =proxy_method reset_fields $self->reset_fields; See "reset_fields" in Validation::Class::Prototype for full documentation. =proxy_method reset_params $self->reset_params; See "reset_params" in Validation::Class::Prototype for full documentation. =proxy_method set_errors $self->set_errors; See "set_errors" in Validation::Class::Prototype for full documentation. =proxy_method set_fields $self->set_fields; See "set_fields" in Validation::Class::Prototype for full documentation. =proxy_method set_params $self->set_params; See "set_params" in Validation::Class::Prototype for full documentation. =proxy_method set_method $self->set_method; See "set_method" in Validation::Class::Prototype for full documentation. =proxy_method stash $self->stash; See "stash" in Validation::Class::Prototype for full documentation. =proxy_method validate $self->validate; See "validate" in Validation::Class::Prototype for full documentation. =proxy_method validate_document $self->validate_document; See "validate_document" in Validation::Class::Prototype for full documentation. =proxy_method validate_method $self->validate_method; See "validate_method" in Validation::Class::Prototype for full documentation. =proxy_method validate_profile $self->validate_profile; See "validate_profile" in Validation::Class::Prototype for full documentation. EXTENSIBILITY Validation::Class does NOT provide method modifiers but can be easily extended with Class::Method::Modifiers. before before foo => sub { ... }; See "before method(s) => sub { ... }" in Class::Method::Modifiers for full documentation. around around foo => sub { ... }; See "around method(s) => sub { ... }" in Class::Method::Modifiers for full documentation. after after foo => sub { ... }; See "after method(s) => sub { ... }" in Class::Method::Modifiers for full documentation. SEE ALSO Validation::Class does not validate blessed objects. If you need a means for validating object types you should use a modern object system like Moo, Mouse, or Moose. Alternatively, you could use decoupled object validators like Type::Tiny, Params::Validate or Specio. POD ERRORS Hey! The above document had some coding errors, which are explained below: Around line 96: Unknown directive: =keyword Around line 120: Unknown directive: =keyword Around line 142: Unknown directive: =keyword Around line 164: Unknown directive: =keyword Around line 210: Unknown directive: =keyword Around line 428: Unknown directive: =keyword Around line 473: Unknown directive: =keyword Around line 528: Unknown directive: =keyword Around line 555: Unknown directive: =keyword Around line 564: Unknown directive: =keyword Around line 585: Unknown directive: =keyword Around line 615: Unknown directive: =keyword Around line 638: Unknown directive: =keyword Around line 669: Unknown directive: =keyword Around line 764: Unknown directive: =keyword Around line 837: Unknown directive: =method Around line 871: Unknown directive: =keyword Around line 908: Unknown directive: =method LICENSE100644000765000024 4364214410403624 16652 0ustar00christiaanstaff000000000000Validation-Class-7.900059This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. Terms of the Perl programming language system itself a) the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version, or b) the "Artistic License" --- The GNU General Public License, Version 1, February 1989 --- This software is Copyright (c) 2011 by Al Newkirk. This is free software, licensed under: The GNU General Public License, Version 1, February 1989 GNU GENERAL PUBLIC LICENSE Version 1, February 1989 Copyright (C) 1989 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The license agreements of most software companies try to keep users at the mercy of those companies. By contrast, our General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. The General Public License applies to the Free Software Foundation's software and to any other program whose authors commit to using it. You can use it for your programs, too. When we speak of free software, we are referring to freedom, not price. Specifically, the General Public License is designed to make sure that you have the freedom to give away or sell copies of free software, that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of a such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must tell them their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any work containing the Program or a portion of it, either verbatim or with modifications. Each licensee is addressed as "you". 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this General Public License and to the absence of any warranty; and give any other recipients of the Program a copy of this General Public License along with the Program. You may charge a fee for the physical act of transferring a copy. 2. You may modify your copy or copies of the Program or any portion of it, and copy and distribute such modifications under the terms of Paragraph 1 above, provided that you also do the following: a) cause the modified files to carry prominent notices stating that you changed the files and the date of any change; and b) cause the whole of any work that you distribute or publish, that in whole or in part contains the Program or any part thereof, either with or without modifications, to be licensed at no charge to all third parties under the terms of this General Public License (except that you may choose to grant warranty protection to some or all third parties, at your option). c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the simplest and most usual way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this General Public License. d) You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. Mere aggregation of another independent work with the Program (or its derivative) on a volume of a storage or distribution medium does not bring the other work under the scope of these terms. 3. You may copy and distribute the Program (or a portion or derivative of it, under Paragraph 2) in object code or executable form under the terms of Paragraphs 1 and 2 above provided that you also do one of the following: a) accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Paragraphs 1 and 2 above; or, b) accompany it with a written offer, valid for at least three years, to give any third party free (except for a nominal charge for the cost of distribution) a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Paragraphs 1 and 2 above; or, c) accompany it with the information you received as to where the corresponding source code may be obtained. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form alone.) Source code for a work means the preferred form of the work for making modifications to it. For an executable file, complete source code means all the source code for all modules it contains; but, as a special exception, it need not include source code for modules which are standard libraries that accompany the operating system on which the executable file runs, or for standard header files or definitions files that accompany that operating system. 4. You may not copy, modify, sublicense, distribute or transfer the Program except as expressly provided under this General Public License. Any attempt otherwise to copy, modify, sublicense, distribute or transfer the Program is void, and will automatically terminate your rights to use the Program under this License. However, parties who have received copies, or rights to use copies, from you under this General Public License will not have their licenses terminated so long as such parties remain in full compliance. 5. By copying, distributing or modifying the Program (or any work based on the Program) you indicate your acceptance of this license to do so, and all its terms and conditions. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. 7. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of the license which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the license, you may choose any version ever published by the Free Software Foundation. 8. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to humanity, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19xx name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (a program to direct compilers to make passes at assemblers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice That's all there is to it! --- The Artistic License 1.0 --- This software is Copyright (c) 2011 by Al Newkirk. This is free software, licensed under: The Artistic License 1.0 The Artistic License Preamble The intent of this document is to state the conditions under which a Package may be copied, such that the Copyright Holder maintains some semblance of artistic control over the development of the package, while giving the users of the package the right to use and distribute the Package in a more-or-less customary fashion, plus the right to make reasonable modifications. Definitions: - "Package" refers to the collection of files distributed by the Copyright Holder, and derivatives of that collection of files created through textual modification. - "Standard Version" refers to such a Package if it has not been modified, or has been modified in accordance with the wishes of the Copyright Holder. - "Copyright Holder" is whoever is named in the copyright or copyrights for the package. - "You" is you, if you're thinking about copying or distributing this Package. - "Reasonable copying fee" is whatever you can justify on the basis of media cost, duplication charges, time of people involved, and so on. (You will not be required to justify it to the Copyright Holder, but only to the computing community at large as a market that must bear the fee.) - "Freely Available" means that no fee is charged for the item itself, though there may be fees involved in handling the item. It also means that recipients of the item may redistribute it under the same conditions they received it. 1. You may make and give away verbatim copies of the source form of the Standard Version of this Package without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers. 2. You may apply bug fixes, portability fixes and other modifications derived from the Public Domain or from the Copyright Holder. A Package modified in such a way shall still be considered the Standard Version. 3. You may otherwise modify your copy of this Package in any way, provided that you insert a prominent notice in each changed file stating how and when you changed that file, and provided that you do at least ONE of the following: a) place your modifications in the Public Domain or otherwise make them Freely Available, such as by posting said modifications to Usenet or an equivalent medium, or placing the modifications on a major archive site such as ftp.uu.net, or by allowing the Copyright Holder to include your modifications in the Standard Version of the Package. b) use the modified Package only within your corporation or organization. c) rename any non-standard executables so the names do not conflict with standard executables, which must also be provided, and provide a separate manual page for each non-standard executable that clearly documents how it differs from the Standard Version. d) make other distribution arrangements with the Copyright Holder. 4. You may distribute the programs of this Package in object code or executable form, provided that you do at least ONE of the following: a) distribute a Standard Version of the executables and library files, together with instructions (in the manual page or equivalent) on where to get the Standard Version. b) accompany the distribution with the machine-readable source of the Package with your modifications. c) accompany any non-standard executables with their corresponding Standard Version executables, giving the non-standard executables non-standard names, and clearly documenting the differences in manual pages (or equivalent), together with instructions on where to get the Standard Version. d) make other distribution arrangements with the Copyright Holder. 5. You may charge a reasonable copying fee for any distribution of this Package. You may charge any fee you choose for support of this Package. You may not charge a fee for this Package itself. However, you may distribute this Package in aggregate with other (possibly commercial) programs as part of a larger (possibly commercial) software distribution provided that you do not advertise this Package as a product of your own. 6. The scripts and library files supplied as input to or produced as output from the programs of this Package do not automatically fall under the copyright of this Package, but belong to whomever generated them, and may be sold commercially, and may be aggregated with this Package. 7. C or perl subroutines supplied by you and linked into this Package shall not be considered part of this Package. 8. The name of the Copyright Holder may not be used to endorse or promote products derived from this software without specific prior written permission. 9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. The End Changes100644000765000024 603014410403624 17106 0ustar00christiaanstaff000000000000Validation-Class-7.900059================================================== Changes from 2022-03-27 00:00:00 +0000 to present. ================================================== --------------------------------------------- version 7.900059 at 2023-03-27 21:16:00 +0000 --------------------------------------------- Change: 8e4779d9d7127d11626058d1809df691b91dd35a Author: Christiaan Kras Date : 2023-03-27 22:16:38 +0000 Wrong usage of between-directive in test Change: 7efcee6e33044b40a4d83c4423b01a7eda6fba38 Author: Christiaan Kras Date : 2023-03-27 21:26:57 +0000 Fix POD error Change: 261609a9971e6fcc12722c59cf12d8fb2f733503 Author: Christiaan Kras Date : 2023-03-27 20:57:24 +0000 Fixed the between-directive to actually check the range, not the length This fixes rt-114159 (https://rt.cpan.org/Ticket/Display.html?id=114159) --------------------------------------------- version 7.900058 at 2022-06-22 11:59:18 +0000 --------------------------------------------- Change: b4a0da93209dcec255df34c614ec4d2597c989f3 Author: Christiaan Kras Date : 2022-06-22 13:59:18 +0000 v7.900058 Change: b687cf15cb4d82d62c7e76b1f213a81438e20d23 Author: Christiaan Kras Date : 2022-06-22 13:51:59 +0000 v7.900058 Change: 23492e055dd1a08153d103f1e382fe8716061b63 Author: Christiaan Kras Date : 2022-06-22 13:49:34 +0000 Merge pull request #1 from Htbaa/field-append-overrides-base-class Field append overrides base class Change: 8d2f1a0903917dc627bcd09f62411623f247f298 Author: Christiaan Kras Date : 2022-06-22 13:46:03 +0000 .gitignore update Change: aab9cce8c2fde3fe2738f91269a6ce76716f01e2 Author: Christiaan Kras Date : 2022-02-07 11:59:40 +0000 Applied patch from RT-86158 Spelling errors Change: 649e5a696cf3bb55b106aa65a3a136ad5cc612db Author: Christiaan Kras Date : 2022-02-07 11:55:52 +0000 Fix Clone dependency in dist.ini Change: 8e540f9fd541d491d7286a53f5e527870afb009e Author: Christiaan Kras Date : 2022-02-07 11:53:38 +0000 Style match Change: fd98836ab6684f9b609db63bc8ee57f59fdb2315 Author: Christiaan Kras Date : 2022-02-07 11:52:18 +0000 Declared Clone dependency This fixes RT-130246 Change: 2893fde604b0904bf868806335b3aad0caee232f Author: Christiaan Kras Date : 2022-02-07 11:50:25 +0000 Test for RT-124086 Change: cb7c962bdb03a3d2a44395b1311849fe3cfe87b8 Author: Christiaan Kras Date : 2022-02-07 11:49:16 +0000 Fix: Field append overrides field from base class This fixes RT-124086 which caused field append to override the field in the base class. =============================================== Plus 1 release after 2022-03-27 00:00:00 +0000. =============================================== META.yml100644000765000024 132514410403624 17066 0ustar00christiaanstaff000000000000Validation-Class-7.900059--- abstract: 'Powerful Data Validation Framework' author: - 'Al Newkirk ' build_requires: perl: '5.010' configure_requires: ExtUtils::MakeMaker: '0' dynamic_config: 0 generated_by: 'Dist::Zilla version 6.030, CPAN::Meta::Converter version 2.150010' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: Validation-Class requires: Clone: '0' Hash::Flatten: '0' Hash::Merge: '0' List::MoreUtils: '0' Module::Find: '0' Module::Runtime: '0' Scalar::Util: '0' perl: '5.010' version: '7.900059' x_generated_by_perl: v5.36.0 x_serialization_backend: 'YAML::Tiny version 1.74' x_spdx_expression: 'Artistic-1.0-Perl OR GPL-1.0-or-later' MANIFEST100644000765000024 1604614410403624 16774 0ustar00christiaanstaff000000000000Validation-Class-7.900059# This file was automatically generated by Dist::Zilla::Plugin::Manifest v6.030. Changes LICENSE MANIFEST META.yml Makefile.PL README README.mkdn cpanfile lib/Validation/Class.pm lib/Validation/Class/Configuration.pm lib/Validation/Class/Cookbook.pod lib/Validation/Class/Directive.pm lib/Validation/Class/Directive/Alias.pm lib/Validation/Class/Directive/Between.pm lib/Validation/Class/Directive/City.pm lib/Validation/Class/Directive/Creditcard.pm lib/Validation/Class/Directive/Date.pm lib/Validation/Class/Directive/Decimal.pm lib/Validation/Class/Directive/Default.pm lib/Validation/Class/Directive/DependsOn.pm lib/Validation/Class/Directive/Email.pm lib/Validation/Class/Directive/Error.pm lib/Validation/Class/Directive/Errors.pm lib/Validation/Class/Directive/Filtering.pm lib/Validation/Class/Directive/Filters.pm lib/Validation/Class/Directive/Help.pm lib/Validation/Class/Directive/Hostname.pm lib/Validation/Class/Directive/Label.pm lib/Validation/Class/Directive/Length.pm lib/Validation/Class/Directive/Matches.pm lib/Validation/Class/Directive/MaxAlpha.pm lib/Validation/Class/Directive/MaxDigits.pm lib/Validation/Class/Directive/MaxLength.pm lib/Validation/Class/Directive/MaxSum.pm lib/Validation/Class/Directive/MaxSymbols.pm lib/Validation/Class/Directive/Messages.pm lib/Validation/Class/Directive/MinAlpha.pm lib/Validation/Class/Directive/MinDigits.pm lib/Validation/Class/Directive/MinLength.pm lib/Validation/Class/Directive/MinSum.pm lib/Validation/Class/Directive/MinSymbols.pm lib/Validation/Class/Directive/Mixin.pm lib/Validation/Class/Directive/MixinField.pm lib/Validation/Class/Directive/Multiples.pm lib/Validation/Class/Directive/Name.pm lib/Validation/Class/Directive/Options.pm lib/Validation/Class/Directive/Pattern.pm lib/Validation/Class/Directive/Readonly.pm lib/Validation/Class/Directive/Required.pm lib/Validation/Class/Directive/SSN.pm lib/Validation/Class/Directive/State.pm lib/Validation/Class/Directive/Telephone.pm lib/Validation/Class/Directive/Time.pm lib/Validation/Class/Directive/Toggle.pm lib/Validation/Class/Directive/UUID.pm lib/Validation/Class/Directive/Validation.pm lib/Validation/Class/Directive/Value.pm lib/Validation/Class/Directive/Zipcode.pm lib/Validation/Class/Directives.pm lib/Validation/Class/Errors.pm lib/Validation/Class/Exporter.pm lib/Validation/Class/Field.pm lib/Validation/Class/Fields.pm lib/Validation/Class/Listing.pm lib/Validation/Class/Mapping.pm lib/Validation/Class/Mixin.pm lib/Validation/Class/Mixins.pm lib/Validation/Class/Params.pm lib/Validation/Class/Prototype.pm lib/Validation/Class/Simple.pm lib/Validation/Class/Simple/Streamer.pm lib/Validation/Class/Util.pm lib/Validation/Class/Whitepaper.pod t/00-load-simple.t t/00-load.t t/01-access.t t/02-integrity.t t/03-streaming.t t/04-attribute-assignments.t t/04-dot-notation.t t/04-proxy-methods.t t/05-filters-usage.t t/05-foreign-directive.t t/05-heirarchal-role-handling.t t/05-method-syntax.t t/05-role-requirements.t t/06-load-settings.t t/07-adopt-syntax.t t/08-ensure-syntax.t t/98-02-document-synopsis-adhoc.t t/98-02-document-synopsis-filtering.t t/98-02-document-synopsis.t t/98-03-document-example-composition.t t/98-03-document-example-method-usages.t t/98-03-document-example-nested.t t/98-03-document-example-pruning.t t/98-03-document-example-reporting.t t/99-alias-handling-with-report-unknown-enabled.t t/99-check-queuing-and-alternatives.t t/99-ignore-intervention.tt t/99-instance-based-stash-object.t t/99-objects-not-sharing-params.t t/99-override-bug.t t/99-toggling-filters-during-execution.t t/legacy/01-fields-access.t t/legacy/10-attribute-method.t t/legacy/10-build-method.t t/legacy/10-directive-method.t t/legacy/10-field-method.t t/legacy/10-filter-method.t t/legacy/10-initialize-method.t t/legacy/10-load-method.t t/legacy/10-method-method.t t/legacy/10-mixin-method.t t/legacy/10-profile-method.t t/legacy/10-prototype-method.t t/legacy/90-method-modifiers.t t/legacy/90-rand-bugfixes.t t/legacy/myapp/lib/MyApp/Container.pm t/legacy/myapp/lib/MyApp/Introspect.pm t/legacy/myapp/lib/MyApp/Test.pm t/legacy/myapp/lib/MyApp/Test/Base.pm t/legacy/myapp/lib/MyApp/Test/Base/Email.pm t/legacy/regression/00-load.t t/legacy/regression/01-attributes.t t/legacy/regression/02-package-declaration.t t/legacy/regression/03-mixin-usages.t t/legacy/regression/04-parameters.t t/legacy/regression/04-profile-usages.t t/legacy/regression/10-custom-validation.t t/legacy/regression/10-default-values.t t/legacy/regression/10-stash.t t/legacy/regression/10-validation.t t/legacy/regression/11-array-param-validation.t t/legacy/regression/11-group-validation.t t/legacy/regression/12-queued-rules.t t/legacy/regression/13-independence.t t/legacy/regression/13-multiline-labels-and-errors.t t/legacy/regression/14-relatives.t t/legacy/regression/15-toggling.t t/legacy/regression/16-cascading.t t/legacy/regression/17-pattern-matching.t t/legacy/regression/18-cloning.t t/legacy/regression/21-filtering-behavior.t t/legacy/regression/22-filtering-behavior.t t/legacy/regression/42-inheritence.t t/legacy/regression/97-persistent-values.t t/legacy/regression/98-anomaly.t t/legacy/regression/98-unknown_params.t t/legacy/regression/99-battery.t t/legacy/regression/filters/01-trim.t t/legacy/regression/filters/02-alpha.t t/legacy/regression/filters/03-currency.t t/legacy/regression/filters/03-decimal.t t/legacy/regression/filters/04-strip.t t/legacy/regression/filters/05-numeric.t t/legacy/regression/filters/06-uppercase.t t/legacy/regression/filters/07-lowercase.t t/legacy/regression/filters/08-titlecase.t t/legacy/regression/filters/09-capitalize.t t/legacy/regression/filters/10-alphanumeric.t t/legacy/regression/modules/MyVal.pm t/legacy/regression/modules/MyVal/Person.pm t/legacy/regression/modules/MyVal/Plugin/Glade.pm t/legacy/regression/modules/MyVal/Staff.pm t/legacy/regression/modules/MyVal/Temp.pm t/legacy/regression/modules/MyVal/Ticket.pm t/legacy/regression/validators/01-min_length.t t/legacy/regression/validators/02-max_length.t t/legacy/regression/validators/03-pattern.t t/legacy/regression/validators/04-between.t t/legacy/regression/validators/05-length.t t/legacy/regression/validators/06-matches.t t/legacy/regression/validators/07-options.t t/legacy/regression/validators/08-depends_on.t t/legacy/regression/validators/20-max_alpha.t t/legacy/regression/validators/20-max_digit.t t/legacy/regression/validators/20-max_sum.t t/legacy/regression/validators/20-max_symbols.t t/legacy/regression/validators/21-min_alpha.t t/legacy/regression/validators/21-min_digit.t t/legacy/regression/validators/21-min_sum.t t/legacy/regression/validators/21-min_symbols.t t/legacy/regression/validators/22-city.t t/legacy/regression/validators/22-creditcard.t t/legacy/regression/validators/22-date.t t/legacy/regression/validators/22-decimal.t t/legacy/regression/validators/22-email.t t/legacy/regression/validators/22-hostname.t t/legacy/regression/validators/22-ssn.t t/legacy/regression/validators/22-state.t t/legacy/regression/validators/22-telephone.t t/legacy/regression/validators/22-time.t t/legacy/regression/validators/22-uuid.t t/legacy/regression/validators/22-zipcode.t t/lib/T/Location.pm t/lib/T/User.pm cpanfile100644000765000024 100614410403624 17315 0ustar00christiaanstaff000000000000Validation-Class-7.900059# This file is generated by Dist::Zilla::Plugin::CPANFile v6.030 # Do not edit this file directly. To change prereqs, edit the `dist.ini` file. requires "Clone" => "0"; requires "Hash::Flatten" => "0"; requires "Hash::Merge" => "0"; requires "List::MoreUtils" => "0"; requires "Module::Find" => "0"; requires "Module::Runtime" => "0"; requires "Scalar::Util" => "0"; requires "perl" => "5.010"; on 'test' => sub { requires "perl" => "5.010"; }; on 'configure' => sub { requires "ExtUtils::MakeMaker" => "0"; }; t000755000765000024 014410403624 15717 5ustar00christiaanstaff000000000000Validation-Class-7.90005900-load.t100644000765000024 2017314410403624 17423 0ustar00christiaanstaff000000000000Validation-Class-7.900059/tuse FindBin; use Test::More; use utf8; use strict; use warnings; { use_ok 'Validation::Class'; use_ok 'Validation::Class::Prototype'; } { # no importing - #fail package TestClass; use Validation::Class (); package main; my $class; eval { $class = TestClass->new }; ok !$class, "TestClass cannot be instantiated wo/definitions or importing"; } { # importing nothing - #hack package TestClass::Alt; use Validation::Class qw(//); package main; my $class; $class = TestClass::Alt->new; ok ref $class, "TestClass::Alt instantiated"; ok !$class->can('attribute'), "TestClass::Alt wo/ attribute keyword"; ok !$class->can('bld'), "TestClass::Alt wo/ bld keyword"; ok !$class->can('build'), "TestClass::Alt wo/ build keyword"; ok !$class->can('dir'), "TestClass::Alt wo/ dir keyword"; ok !$class->can('directive'), "TestClass::Alt wo/ directive keyword"; ok !$class->can('doc'), "TestClass::Alt wo/ doc keyword"; ok !$class->can('document'), "TestClass::Alt wo/ document keyword"; ok !$class->can('fld'), "TestClass::Alt wo/ fld keyword"; ok !$class->can('field'), "TestClass::Alt wo/ field keyword"; ok !$class->can('flt'), "TestClass::Alt wo/ flt keyword"; ok !$class->can('filter'), "TestClass::Alt wo/ filter keyword"; ok !$class->can('has'), "TestClass::Alt wo/ has keyword"; ok !$class->can('load'), "TestClass::Alt wo/ load keyword"; ok !$class->can('msg'), "TestClass::Alt wo/ msg keyword"; ok !$class->can('message'), "TestClass::Alt wo/ message keyword"; ok !$class->can('mth'), "TestClass::Alt wo/ mth keyword"; ok !$class->can('method'), "TestClass::Alt wo/ method keyword"; ok !$class->can('mxn'), "TestClass::Alt wo/ mxn keyword"; ok !$class->can('mixin'), "TestClass::Alt wo/ mixin keyword"; ok !$class->can('obj'), "TestClass::Alt wo/ obj keyword"; ok !$class->can('object'), "TestClass::Alt wo/ object keyword"; ok !$class->can('pro'), "TestClass::Alt wo/ pro keyword"; ok !$class->can('profile'), "TestClass::Alt wo/ profile keyword"; ok !$class->can('set'), "TestClass::Alt wo/ set keyword"; } { # no importing - #hack package TestClass::Hack; use Validation::Class (); Validation::Class->prototype(__PACKAGE__); # init prototype and cache it package main; my $class = TestClass::Hack->new; ok "TestClass::Hack" eq ref $class, "TestClass::Hack instantiated, via the setup hack"; ok !$class->can($_), "TestClass::Hack has NOT been injected with the $_ method" for @Validation::Class::EXPORT; ok $class->can($_), "TestClass::Hack has been injected with the $_ method" for qw/new proto prototype/, @Validation::Class::Prototype::proxy_methods, @Validation::Class::Prototype::proxy_methods_wrapped; } { # traditional usage package TestClass::Traditional; use Validation::Class; package main; my $class = TestClass::Traditional->new; ok "TestClass::Traditional" eq ref $class, "TestClass::Traditional instantiated, via the setup hack"; ok $class->can($_), "TestClass::Traditional has been injected with the $_ method" for @Validation::Class::EXPORT; ok $class->can($_), "TestClass::Traditional has been injected with the $_ method" for qw/new proto prototype/, @Validation::Class::Prototype::proxy_methods, @Validation::Class::Prototype::proxy_methods_wrapped; } { # traditional usage with keywords package TestClass::WithKeywords; use Validation::Class; set { # as long as it doesn't fail -- will test elsewhere }; # a mixin template mxn 'basic' => {required => 1}; # a validation rule fld 'login' => { label => 'User Login', error => 'Login invalid.', mixin => 'basic', validation => sub { my ($self, $this_field, $all_params) = @_; return $this_field->{value} eq 'admin' ? 1 : 0; } }; # a validation rule fld 'password' => { label => 'User Password', error => 'Password invalid.', mixin => 'basic', validation => sub {1} # always successful }; # a validation profile pro 'registration' => sub { my ($self, @args) = @_; return $self->validate(qw(+login +password)) }; # an auto-validating method mth 'register' => { input => 'registration', # validate registration profile using => sub {'happy-test'} }; package main; my $class = TestClass::WithKeywords->new( login => 'admin', password => 'pass' ); ok "TestClass::WithKeywords" eq ref $class, "TestClass::WithKeywords instantiated"; ok $class->proto->mixins->{basic}->{required} == 1, 'TestClass::WithKeywords has mixin basic, required directive set'; ok defined $class->fields->{$_}->{label} && defined $class->fields->{$_}->{error} && defined $class->fields->{$_}->{mixin} && defined $class->fields->{$_}->{validation}, "TestClass::WithKeywords has $_ with label, error, mixin " . "and validation directives set" for ('login', 'password'); ok defined $class->proto->profiles->{registration}, "TestClass::WithKeywords has registration profile"; ok defined $class->proto->methods->{register}, "TestClass::WithKeywords has self-validating register method"; ok $class->validate_profile('registration'), "TestClass::WithKeywords has successfully executed the registration profile"; ok "happy-test" eq $class->register(), "TestClass::WithKeywords has successfully executed the register method " . "which returned the desired output"; } { # overriding injected methods (all) package TestClass::Overrider; use Validation::Class; no warnings 'redefine'; sub adt {'noop'} sub adopt {'noop'} sub attribute {'noop'} sub bld {'noop'} sub build {'noop'} sub dir {'noop'} sub directive {'noop'} sub doc {'noop'} sub document {'noop'} sub ens {'noop'} sub ensure {'noop'} sub fld {'noop'} sub field {'noop'} sub flt {'noop'} sub filter {'noop'} sub has {'noop'} sub load {'noop'} sub msg {'noop'} sub message {'noop'} sub mth {'noop'} sub method {'noop'} sub mxn {'noop'} sub mixin {'noop'} sub obj {'noop'} sub object {'noop'} sub pro {'noop'} sub profile {'noop'} sub set {'noop'} sub new {'noop'} sub proto {'noop'} sub prototype {'noop'} sub class {'noop'} sub clear_queue {'noop'} sub error {'noop'} sub error_count {'noop'} sub error_fields {'noop'} sub errors {'noop'} sub errors_to_string {'noop'} sub get_errors {'noop'} sub fields {'noop'} sub filtering {'noop'} sub ignore_failure {'noop'} sub ignore_unknown {'noop'} sub is_valid {'noop'} sub param {'noop'} sub params {'noop'} sub queue {'noop'} sub report_failure {'noop'} sub report_unknown {'noop'} sub reset_errors {'noop'} sub set_errors {'noop'} sub stash {'noop'} sub validate {'noop'} sub validate_profile {'noop'} sub validate_method {'noop'} sub validates {'noop'} sub profile_validates {'noop'} sub method_validates {'noop'} package main; my $class = bless {}, 'TestClass::Overrider'; ok "TestClass::Overrider" eq ref $class, "TestClass::Overrider instantiated"; ok 'noop' eq $class->$_, "TestClass::Overrider method $_ method was overriden" for @Validation::Class::EXPORT; ok !do { eval { 1 if 'noop' eq $class->$_ }; $@; }, "TestClass::Overrider method $_ method was overriden" for qw/new proto prototype/, @Validation::Class::Prototype::proxy_methods, @Validation::Class::Prototype::proxy_methods_wrapped; } done_testing; Makefile.PL100644000765000024 252614410403624 17573 0ustar00christiaanstaff000000000000Validation-Class-7.900059# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v6.030. use strict; use warnings; use 5.010; use ExtUtils::MakeMaker; my %WriteMakefileArgs = ( "ABSTRACT" => "Powerful Data Validation Framework", "AUTHOR" => "Al Newkirk ", "CONFIGURE_REQUIRES" => { "ExtUtils::MakeMaker" => 0 }, "DISTNAME" => "Validation-Class", "LICENSE" => "perl", "MIN_PERL_VERSION" => "5.010", "NAME" => "Validation::Class", "PREREQ_PM" => { "Clone" => 0, "Hash::Flatten" => 0, "Hash::Merge" => 0, "List::MoreUtils" => 0, "Module::Find" => 0, "Module::Runtime" => 0, "Scalar::Util" => 0 }, "VERSION" => "7.900059", "test" => { "TESTS" => "t/*.t t/legacy/*.t t/legacy/regression/*.t t/legacy/regression/filters/*.t t/legacy/regression/validators/*.t" } ); my %FallbackPrereqs = ( "Clone" => 0, "Hash::Flatten" => 0, "Hash::Merge" => 0, "List::MoreUtils" => 0, "Module::Find" => 0, "Module::Runtime" => 0, "Scalar::Util" => 0 ); unless ( eval { ExtUtils::MakeMaker->VERSION(6.63_03) } ) { delete $WriteMakefileArgs{TEST_REQUIRES}; delete $WriteMakefileArgs{BUILD_REQUIRES}; $WriteMakefileArgs{PREREQ_PM} = \%FallbackPrereqs; } delete $WriteMakefileArgs{CONFIGURE_REQUIRES} unless eval { ExtUtils::MakeMaker->VERSION(6.52) }; WriteMakefile(%WriteMakefileArgs); README.mkdn100644000765000024 11141214410403624 17464 0ustar00christiaanstaff000000000000Validation-Class-7.900059# NAME Validation::Class - Powerful Data Validation Framework # VERSION version 7.900059 # SYNOPSIS use Validation::Class::Simple::Streamer; my $params = {username => 'admin', password => 's3cret'}; my $input = Validation::Class::Simple::Streamer->new(params => $params); # check username parameter $input->check('username')->required->between('5-255'); $input->filters([qw/trim strip/]); # check password parameter $input->check('password')->required->between('5-255')->min_symbols(1); $input->filters([qw/trim strip/]); # run validate $input->validate or die $input->errors_to_string; # DESCRIPTION Validation::Class is a scalable data validation library with interfaces for applications of all sizes. The most common usage of Validation::Class is to transform class namespaces into data validation domains where consistency and reuse are primary concerns. Validation::Class provides an extensible framework for defining reusable data validation rules. It ships with a complete set of pre-defined validations and filters referred to as ["directives"](https://metacpan.org/pod/Validation%3A%3AClass%3A%3ADirectives#DIRECTIVES). The core feature-set consist of self-validating methods, validation profiles, reusable validation rules and templates, pre and post input filtering, class inheritance, automatic array handling, and extensibility (e.g. overriding default error messages, creating custom validators, creating custom input filters and much more). Validation::Class promotes DRY (don't repeat yourself) code. The main benefit in using Validation::Class is that the architecture is designed to increase the consistency of data input handling. The following is a more traditional usage of Validation::Class, using the DSL to construct a validator class: package MyApp::Person; use Validation::Class; # data validation template mixin basic => { required => 1, max_length => 255, filters => [qw/trim strip/] }; # data validation rules for the username parameter field username => { mixin => 'basic', min_length => 5 }; # data validation rules for the password parameter field password => { mixin => 'basic', min_length => 5, min_symbols => 1 }; package main; my $person = MyApp::Person->new(username => 'admin', password => 'secr3t'); # validate rules on the person object unless ($person->validates) { # handle the failures warn $person->errors_to_string; } 1; # QUICKSTART If you are looking for a simple in-line data validation module built using the same tenets and principles as Validation::Class, please review [Validation::Class::Simple](https://metacpan.org/pod/Validation%3A%3AClass%3A%3ASimple) or [Validation::Class::Simple::Streamer](https://metacpan.org/pod/Validation%3A%3AClass%3A%3ASimple%3A%3AStreamer). If you are new to Validation::Class, or would like more information on the underpinnings of this library and how it views and approaches data validation, please review [Validation::Class::Whitepaper](https://metacpan.org/pod/Validation%3A%3AClass%3A%3AWhitepaper). Please review the ["GUIDED-TOUR" in Validation::Class::Cookbook](https://metacpan.org/pod/Validation%3A%3AClass%3A%3ACookbook#GUIDED-TOUR) for a detailed step-by-step look into how Validation::Class works. # KEYWORDS ## adopt The adopt keyword (or adt) copies configuration and functionality from other Validation::Class classes. The adopt keyword takes three arguments, the name of the class to be introspected, and the configuration type and name to be recreated. Basically, anything you can configure using a Validation::Class keyword can be adopted into other classes using this keyword with the exception of coderefs registered using the build keyword. Please note! If you are adopting a field declaration which has an associated mixin directive defined on the target class, you must adopt the mixin explicitly if you wish it's values to be interpolated. package MyApp::Exployee; use Validate::Class; use MyApp::Person; adopt MyApp::Person, mixin => 'basic'; adopt MyApp::Person, field => 'first_name'; adopt MyApp::Person, field => 'last_name'; adopt MyApp::Person, profile => 'has_fullname'; 1; ## attribute The attribute keyword (or has) registers a class attribute, i.e. it creates an accessor (getter and setter) on the class. Attribute declaration is flexible and only requires an attribute name to be configured. Additionally, the attribute keyword can takes two arguments, the attribute's name and a scalar or coderef to be used as it's default value. package MyApp::Person; use Validate::Class; attribute 'first_name' => 'Peter'; attribute 'last_name' => 'Venkman'; attribute 'full_name' => sub { join ', ', $_[0]->last_name, $_[0]->first_name }; attribute 'email_address'; 1; ## build The build keyword (or bld) registers a coderef to be run at instantiation much in the same way the common BUILD routine is used in modern OO frameworks. package MyApp::Person; use Validation::Class; build sub { my ($self, $args) = @_; # run after instantiation in the order defined }; 1; The build keyword takes one argument, a coderef which is passed the instantiated class object. ## directive The directive keyword (or dir) registers custom validator directives to be used in your field definitions. Please note that custom directives can only be used with field definitions. This is a means of extending the list of directives per instance. See the list of core directives, [Validation::Class::Directives](https://metacpan.org/pod/Validation%3A%3AClass%3A%3ADirectives), or review [Validation::Class::Directive](https://metacpan.org/pod/Validation%3A%3AClass%3A%3ADirective) for insight into creating your own CPAN installable directives. package MyApp::Person; use Validate::Class; # define a custom class-level directive directive 'blacklisted' => sub { my ($self, $field, $param) = @_; if (defined $field->{blacklisted} && defined $param) { if ($field->{required} || $param) { if (exists_in_blacklist($field->{blacklisted}, $param)) { my $handle = $field->label || $field->name; $field->errors->add("$handle has been blacklisted"); return 0; } } } return 1; }; field 'email_address' => { blacklisted => '/path/to/blacklist' email => 1, }; 1; The directive keyword takes two arguments, the name of the directive and a coderef which will be used to validate the associated field. The coderef is passed four ordered parameters; a directive object, the class prototype object, the current field object, and the matching parameter's value. The validator (coderef) is evaluated by its return value as well as whether it altered any error containers. ## document The document keyword (or doc) registers a data matching profile which can be used to validate heiarchal data. It will store a hashref with pre-define path matching rules for the data structures you wish to validate. The "path matching rules", which use a specialized object notation, referred to as the document notation, can be thought of as a kind-of simplified regular expression which is executed against the flattened data structure. The following are a few general use-cases: package MyApp::Person; use Validation::Class; field 'string' => { mixin => [':str'] }; # given this JSON data structure { "id": "1234-A", "name": { "first_name" : "Bob", "last_name" : "Smith", }, "title": "CIO", "friends" : [], } # select id to validate against the string rule document 'foobar' => { 'id' => 'string' }; # select name -> first_name/last_name to validate against the string rule document 'foobar' => {'name.first_name' => 'string', 'name.last_name' => 'string'}; # or document 'foobar' => {'name.*_name' => 'string'}; # select each element in friends to validate against the string rule document 'foobar' => { 'friends.@' => 'string' }; # or select an element of a hashref in each element in friends to validate # against the string rule document 'foobar' => { 'friends.@.name' => 'string' }; The document declaration's keys should follow the aforementioned document notation schema and it's values should be strings which correspond to the names of fields (or other document declarations) that will be used to preform the data validation. It is possible to combine document declarations to validate hierarchical data that contains data structures matching one or more document patterns. The following is an example of what that might look like. package MyApp::Person; use Validation::Class; # data validation rule field 'name' => { mixin => [':str'], pattern => qr/^[A-Za-z ]+$/, max_length => 20, }; # data validation map / document notation schema document 'friend' => { 'name' => 'name' }; # data validation map / document notation schema document 'person' => { 'name' => 'name', 'friends.@' => 'friend' }; package main; my $data = { "name" => "Anita Campbell-Green", "friends" => [ { "name" => "Horace" }, { "name" => "Skinner" }, { "name" => "Alonzo" }, { "name" => "Frederick" }, ], }; my $person = MyApp::Person->new; unless ($person->validate_document(person => $data)) { warn $person->errors_to_string if $person->error_count; } 1; Alternatively, the following is a more verbose data validation class using traditional styling and configuration. package MyApp::Person; use Validation::Class; field 'id' => { mixin => [':str'], filters => ['numeric'], max_length => 2, }; field 'name' => { mixin => [':str'], pattern => qr/^[A-Za-z ]+$/, max_length => 20, }; field 'rating' => { mixin => [':str'], pattern => qr/^\-?\d+$/, }; field 'tag' => { mixin => [':str'], pattern => qr/^(?!evil)\w+/, max_length => 20, }; document 'person' => { 'id' => 'id', 'name' => 'name', 'company.name' => 'name', 'company.supervisor.name' => 'name', 'company.supervisor.rating.@.*' => 'rating', 'company.tags.@' => 'name' }; package main; my $data = { "id" => "1234-ABC", "name" => "Anita Campbell-Green", "title" => "Designer", "company" => { "name" => "House of de Vil", "supervisor" => { "name" => "Cruella de Vil", "rating" => [ { "support" => -9, "guidance" => -9 } ] }, "tags" => [ "evil", "cruelty", "dogs" ] }, }; my $person = MyApp::Person->new; unless ($person->validate_document(person => $data)) { warn $person->errors_to_string if $person->error_count; } 1; Additionally, the following is yet another way to validate a document by passing the document specification directly instead of by name. package MyApp::Person; use Validation::Class; package main; my $data = { "id" => "1234-ABC", "name" => "Anita Campbell-Green", "title" => "Designer", "company" => { "name" => "House of de Vil", "supervisor" => { "name" => "Cruella de Vil", "rating" => [ { "support" => -9, "guidance" => -9 } ] }, "tags" => [ "evil", "cruelty", "dogs" ] }, }; my $spec = { 'id' => { max_length => 2 }, 'name' => { mixin => ':str' }, 'company.name' => { mixin => ':str' }, 'company.supervisor.name' => { mixin => ':str' }, 'company.supervisor.rating.@.*' => { pattern => qr/^(?!evil)\w+/ }, 'company.tags.@' => { max_length => 20 }, }; my $person = MyApp::Person->new; unless ($person->validate_document($spec => $data)) { warn $person->errors_to_string if $person->error_count; } 1; ## ensure The ensure keyword (or ens) is used to convert a pre-existing method into an auto-validating method. The auto-validating method will be registered and function as if it was created using the method keyword. The original pre-existing method will be overridden with a modified version which performs the pre and/or post validation routines. package MyApp::Person; use Validation::Class; sub register { ... } ensure register => { input => ['name', '+email', 'username', '+password', '+password2'], output => ['+id'], # optional output validation, dies on failure }; package main; my $person = MyApp::Person->new(params => $params); if ($person->register) { # handle the successful registration } 1; The ensure keyword takes two arguments, the name of the method to be overridden and a hashref of required key/value pairs. The hashref may have an input key (e.g. input, input\_document, input\_profile, or input\_method). The \`input\` key (specifically) must have a value which must be either an arrayref of fields to be validated, or a scalar value which matches (a validation profile or auto-validating method name). The hashref may also have an output key (e.g. output, output\_document, output\_profile, or output\_method). The \`output\` key (specifically) must have a value which must be either an arrayref of fields to be validated, or a scalar value which matches (a validation profile or auto-validating method name). Whether and what the method returns is yours to decide. The method will return undefined if validation fails. The ensure keyword wraps and functions much in the same way as the method keyword. ## field The field keyword (or fld) registers a data validation rule for reuse and validation in code. The field name should correspond with the parameter name expected to be passed to your validation class or validated against. package MyApp::Person; use Validation::Class; field 'username' => { required => 1, min_length => 1, max_length => 255 }; The field keyword takes two arguments, the field name and a hashref of key/values pairs known as directives. For more information on pre-defined directives, please review the ["list of core directives"](https://metacpan.org/pod/Validation%3A%3AClass%3A%3ADirectives#DIRECTIVES). The field keyword also creates accessors which provide easy access to the field's corresponding parameter value(s). Accessors will be created using the field's name as a label having any special characters replaced with an underscore. # accessor will be created as send_reminders field 'send-reminders' => { length => 1 }; Please note that prefixing field names with a double plus-symbol instructs the register to merge your declaration with any pre-existing declarations within the same scope (e.g. fields imported via loading roles), whereas prefixing field names with a single plus-symbol instructs the register to overwrite any pre-existing declarations. package MyApp::Person; use Validation::Class; set role => 'MyApp::User'; # append existing field and overwrite directives field '++email_address' => { required => 1 }; # redefine existing field field '+login' => { required => 1 }; 1; ## filter The filter keyword (or flt) registers custom filters to be used in your field definitions. It is a means of extending the pre-existing filters declared by the ["filters directive"](https://metacpan.org/pod/Validation%3A%3AClass%3A%3ADirective%3A%3AFilters) before instantiation. package MyApp::Person; use Validate::Class; filter 'flatten' => sub { $_[0] =~ s/[\t\r\n]+/ /g; return $_[0]; }; field 'biography' => { filters => ['trim', 'strip', 'flatten'] }; 1; The filter keyword takes two arguments, the name of the filter and a coderef which will be used to filter the value the associated field. The coderef is passed the value of the field and that value MUST be operated on directly. The coderef should also return the transformed value. ## load The load keyword (or set), which can also be used as a class method, provides options for extending the current class by declaring roles, requirements, etc. The process of applying roles, requirement, and other settings to the current class mainly involves introspecting the namespace's methods and merging relevant parts of the prototype configuration. ## load-classes The \`classes\` (or class) option uses [Module::Find](https://metacpan.org/pod/Module%3A%3AFind) to load all child classes (in-all-subdirectories) for convenient access through the ["class" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#class) method, and when introspecting a larger application. This option accepts an arrayref or single argument. package MyApp; use Validation::Class; load classes => ['MyApp::Domain1', 'MyApp::Domain2']; package main; my $app = MyApp->new; my $person = $app->class('person'); # return a new MyApp::Person object 1; ## load-requirements package MyApp::User; use Validate::Class; load requirements => 'activate'; package MyApp::Person; use Validation::Class; load role => 'MyApp::User'; sub activate {} 1; The \`requirements\` (or required) option is used to ensure that if/when the class is used as a role the calling class has specific pre-existing methods. This option accepts an arrayref or single argument. package MyApp::User; use Validate::Class; load requirements => ['activate', 'deactivate']; 1; ## load-roles package MyApp::Person; use Validation::Class; load role => 'MyApp::User'; 1; The \`roles\` (or role) option is used to load and inherit functionality from other validation classes. These classes should be used and thought-of as roles although they can also be fully-functioning validation classes. This option accepts an arrayref or single argument. package MyApp::Person; use Validation::Class; load roles => ['MyApp::User', 'MyApp::Visitor']; 1; ## message The message keyword (or msg) registers a class-level error message template that will be used in place of the error message defined in the corresponding directive class if defined. Error messages can also be overridden at the individual field-level as well. See the [Validation::Class::Directive::Messages](https://metacpan.org/pod/Validation%3A%3AClass%3A%3ADirective%3A%3AMessages) for instructions on how to override error messages at the field-level. package MyApp::Person; use Validation::Class; field email_address => { required => 1, min_length => 3, messages => { # field-level error message override min_length => '%s is not even close to being a valid email address' } }; # class-level error message overrides message required => '%s is needed to proceed'; message min_length => '%s needs more characters'; 1; The message keyword takes two arguments, the name of the directive whose error message you wish to override and a string which will be used to as a template which is feed to sprintf to format the message. ## method The method keyword (or mth) is used to register an auto-validating method. Similar to method signatures, an auto-validating method can leverage pre-existing validation rules and profiles to ensure a method has the required pre/post-conditions and data necessary for execution. package MyApp::Person; use Validation::Class; method 'register' => { input => ['name', '+email', 'username', '+password', '+password2'], output => ['+id'], # optional output validation, dies on failure using => sub { my ($self, @args) = @_; # do something registrationy $self->id(...); # set the ID field for output validation return $self; } }; package main; my $person = MyApp::Person->new(params => $params); if ($person->register) { # handle the successful registration } 1; The method keyword takes two arguments, the name of the method to be created and a hashref of required key/value pairs. The hashref may have a \`using\` key whose value is the coderef to be executed upon successful validation. The \`using\` key is only optional when a pre-existing subroutine has the same name or the method being declared prefixed with a dash or dash-process-dash. The following are valid subroutine names to be called by the method declaration in absence of a \`using\` key. Please note, unlike the ensure keyword, any pre-existing subroutines will not be wrapped-and-replaced and can be executed without validation if called directly. sub _name { ... } sub _process_name { ... } The hashref may have an input key (e.g. input, input\_document, input\_profile, or input\_method). The \`input\` key (specifically) must have a value which must be either an arrayref of fields to be validated, or a scalar value which matches (a validation profile or auto-validating method name), which will be used to perform data validation **before** the aforementioned coderef has been executed. Whether and what the method returns is yours to decide. The method will return undefined if validation fails. # alternate usage method 'registration' => { input => ['name', '+email', 'username', '+password', '+password2'], output => ['+id'], # optional output validation, dies on failure }; sub _process_registration { my ($self, @args) = @_; $self->id(...); # set the ID field for output validation return $self; } Optionally the hashref may also have an output key (e.g. output, output\_document, output\_profile, or output\_method). The \`output\` key (specifically) must have a value which must be either an arrayref of fields to be validated, or a scalar value which matches (a validation profile or auto-validating method name), which will be used to perform data validation **after** the aforementioned coderef has been executed. Please note that output validation failure will cause the program to die, the premise behind this decision is based on the assumption that given successfully validated input a routine's output should be predictable and if an error occurs it is most-likely a program error as opposed to a user error. See the ignore\_failure and report\_failure attributes on the prototype to control how method validation failures are handled. ## mixin The mixin keyword (or mxn) registers a validation rule template that can be applied (or "mixed-in") to any field by specifying the mixin directive. Mixin directives are processed first so existing field directives will override any directives created by the mixin directive. package MyApp::Person; use Validation::Class; mixin 'boilerplate' => { required => 1, min_length => 1, max_length => 255 }; field 'username' => { # min_length, max_length, .. required will be overridden mixin => 'boilerplate', required => 0 }; Since version 7.900015, all classes are automatically configured with the following default mixins for the sake of convenience: mixin ':flg' => { required => 1, min_length => 1, filters => [qw/trim strip numeric/], between => [0, 1] }; mixin ':num' => { required => 1, min_length => 1, filters => [qw/trim strip numeric/] }; mixin ':str' => { required => 1, min_length => 1, filters => [qw/trim strip/] }; Please note that the aforementioned mixin names are prefixed with a semi-colon but are treated as an exception to the rule. Prefixing mixin names with a double plus-symbol instructs the register to merge your declaration with any pre-existing declarations within the same scope (e.g. mixins imported via loading roles), whereas prefixing mixin names with a single plus-symbol instructs the register to overwrite any pre-existing declarations. package MyApp::Moderator; use Validation::Class; set role => 'MyApp::Person'; # overwrite and append existing mixin mixin '++boilerplate' => { min_symbols => 1 }; # redefine existing mixin mixin '+username' => { required => 1 }; 1; The mixin keyword takes two arguments, the mixin name and a hashref of key/values pairs known as directives. ## profile The profile keyword (or pro) registers a validation profile (coderef) which as in the traditional use of the term is a sequence of validation routines that validates data relevant to a specific action. package MyApp::Person; use Validation::Class; profile 'check_email' => sub { my ($self, @args) = @_; if ($self->email_exists) { my $email = $self->fields->get('email'); $email->errors->add('Email already exists'); return 0; } return 1; }; package main; my $user = MyApp::Person->new(params => $params); unless ($user->validate_profile('check_email')) { # handle failures } 1; The profile keyword takes two arguments, a profile name and coderef which will be used to execute a sequence of actions for validation purposes. # METHODS ## new The new method instantiates a new class object, it performs a series of actions (magic) required for the class to function properly, and for that reason, this method should never be overridden. Use the build keyword for hooking into the instantiation process. In the event a foreign (pre-existing) \`new\` method is detected, an \`initialize\_validator\` method will be injected into the class containing the code (magic) necessary to normalize your environment. package MyApp::Person; use Validation::Class; # hook build sub { my ($self, @args) = @_; # on instantiation }; sub new { # rolled my own my $self = bless {}, shift; # execute magic $self->initialize_validator; } 1; ## prototype The prototype method (or proto) returns an instance of the associated class prototype. The class prototype is responsible for manipulating and validating the data model (the class). It is not likely that you'll need to access this method directly, see [Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype). package MyApp::Person; use Validation::Class; package main; my $person = MyApp::Person->new; my $prototype = $person->prototype; 1; # PROXY METHODS Validation::Class mostly provides sugar functions for modeling your data validation requirements. Each class you create is associated with a prototype class which provides the data validation engine and keeps your class namespace free from pollution, please see [Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype) for more information on specific methods and attributes. Validation::Class injects a few proxy methods into your class which are basically aliases to the corresponding prototype class methods, however it is possible to access the prototype directly using the proto/prototype methods. ## class $self->class; See ["class" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#class) for full documentation. ## clear\_queue $self->clear_queue; See ["clear\_queue" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#clear_queue) for full documentation. ## error\_count $self->error_count; See ["error\_count" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#error_count) for full documentation. ## error\_fields $self->error_fields; See ["error\_fields" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#error_fields) for full documentation. ## errors $self->errors; See ["errors" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#errors) for full documentation. ## errors\_to\_string $self->errors_to_string; See ["errors\_to\_string" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#errors_to_string) for full documentation. ## get\_errors $self->get_errors; See ["get\_errors" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#get_errors) for full documentation. ## get\_fields $self->get_fields; See ["get\_fields" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#get_fields) for full documentation. ## get\_hash $self->get_hash; See ["get\_hash" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#get_hash) for full documentation. ## get\_params $self->get_params; See ["get\_params" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#get_params) for full documentation. ## get\_values $self->get_values; See ["get\_values" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#get_values) for full documentation. ## fields $self->fields; See ["fields" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#fields) for full documentation. ## filtering $self->filtering; See ["filtering" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#filtering) for full documentation. ## ignore\_failure $self->ignore_failure; See ["ignore\_failure" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#ignore_failure) for full documentation. ## ignore\_intervention $self->ignore_intervention; See ["ignore\_intervention" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#ignore_intervention) for full documentation. ## ignore\_unknown $self->ignore_unknown; See ["ignore\_unknown" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#ignore_unknown) for full documentation. ## is\_valid $self->is_valid; See ["is\_valid" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#is_valid) for full documentation. ## param $self->param; See ["param" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#param) for full documentation. ## params $self->params; See ["params" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#params) for full documentation. ## plugin $self->plugin; See ["plugin" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#plugin) for full documentation. ## queue $self->queue; See ["queue" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#queue) for full documentation. ## report\_failure $self->report_failure; See ["report\_failure" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#report_failure) for full documentation. ## report\_unknown $self->report_unknown; See ["report\_unknown" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#report_unknown) for full documentation. ## reset\_errors $self->reset_errors; See ["reset\_errors" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#reset_errors) for full documentation. ## reset\_fields $self->reset_fields; See ["reset\_fields" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#reset_fields) for full documentation. ## reset\_params $self->reset_params; See ["reset\_params" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#reset_params) for full documentation. ## set\_errors $self->set_errors; See ["set\_errors" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#set_errors) for full documentation. ## set\_fields $self->set_fields; See ["set\_fields" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#set_fields) for full documentation. ## set\_params $self->set_params; See ["set\_params" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#set_params) for full documentation. ## set\_method $self->set_method; See ["set\_method" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#set_method) for full documentation. ## stash $self->stash; See ["stash" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#stash) for full documentation. ## validate $self->validate; See ["validate" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#validate) for full documentation. ## validate\_document $self->validate_document; See ["validate\_document" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#validate_document) for full documentation. ## validate\_method $self->validate_method; See ["validate\_method" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#validate_method) for full documentation. ## validate\_profile $self->validate_profile; See ["validate\_profile" in Validation::Class::Prototype](https://metacpan.org/pod/Validation%3A%3AClass%3A%3APrototype#validate_profile) for full documentation. # UPGRADE Validation::Class is stable, its feature-set is complete, and is currently in maintenance-only mode, i.e. Validation::Class will only be updated with minor enhancements and bug fixes. However, the lessons learned will be incorporated into a compelete rewrite uploaded under the namespace [Validation::Interface](https://metacpan.org/pod/Validation%3A%3AInterface). The Validation::Interface fork is designed to have a much simpler API with less options and better execution, focused on validating hierarchical data as its primarily objective. # EXTENSIBILITY Validation::Class does NOT provide method modifiers but can be easily extended with [Class::Method::Modifiers](https://metacpan.org/pod/Class%3A%3AMethod%3A%3AModifiers). ## before before foo => sub { ... }; See ["before method(s) => sub { ... }" in Class::Method::Modifiers](https://metacpan.org/pod/Class%3A%3AMethod%3A%3AModifiers#before-method-s-sub) for full documentation. ## around around foo => sub { ... }; See ["around method(s) => sub { ... }" in Class::Method::Modifiers](https://metacpan.org/pod/Class%3A%3AMethod%3A%3AModifiers#around-method-s-sub) for full documentation. ## after after foo => sub { ... }; See ["after method(s) => sub { ... }" in Class::Method::Modifiers](https://metacpan.org/pod/Class%3A%3AMethod%3A%3AModifiers#after-method-s-sub) for full documentation. # SEE ALSO Validation::Class does not validate blessed objects. If you need a means for validating object types you should use a modern object system like [Moo](https://metacpan.org/pod/Moo), [Mouse](https://metacpan.org/pod/Mouse), or [Moose](https://metacpan.org/pod/Moose). Alternatively, you could use decoupled object validators like [Type::Tiny](https://metacpan.org/pod/Type%3A%3ATiny), [Params::Validate](https://metacpan.org/pod/Params%3A%3AValidate) or [Specio](https://metacpan.org/pod/Specio). # AUTHOR Al Newkirk # COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. 01-access.t100644000765000024 717614410403624 17736 0ustar00christiaanstaff000000000000Validation-Class-7.900059/tuse FindBin; use Test::More; use utf8; use strict; use warnings; use Data::Dumper; { package TestClass::CheckParameters; use Validation::Class; fld name => {required => 1}; package main; my $class = "TestClass::CheckParameters"; my $self = $class->new; ok $class eq ref $self, "$class instantiated"; my @vals = qw( Kathy Joe John O 1 234 Ricky ~ ' Lady §§ ♠♣♥♦♠♣♥♦♠♣♥♦ ); for my $v (@vals) { ok $v eq $self->name($v), "$class name accessor set to `$v` with expected return value" } for my $v (@vals) { my $name_param = $self->name($v); ok $self->params->{name} eq $name_param, "$class name parameter set to `$v` using the name accessor" } } { package TestClass::ArrayParameters; use Validation::Class; bld sub { shift->name([1 .. 5]); }; fld name => {required => 1}; package main; my $class = "TestClass::ArrayParameters"; my $self = $class->new; ok $class eq ref $self, "$class instantiated"; ok "ARRAY" eq ref $self->name, "$class name accessor returns an array"; ok !ref $self->name(''), "$class name accessor returns nothing"; ok !eval { $self->name({1 .. 4}) }, "$class name accessor cant set a hash"; ok "ARRAY" eq ref $self->name([1 .. 5]), "$class name accessor returns an array"; ok "ARRAY" eq ref $self->params->{name}, "$class name param is an array"; ok "ARRAY" eq ref $self->name, "$class name accessor returns the array"; } { package TestClass::FieldAccessors; use Validation::Class; fld 'name.first' => {required => 1}; fld 'name.last' => {required => 1}; fld 'name.phone:0' => {required => 0}; fld 'name.phone:1' => {required => 0}; fld 'name.phone:2' => {required => 0}; package main; my $class = "TestClass::FieldAccessors"; my $self = $class->new; ok $class eq ref $self, "$class instantiated"; my @accessors = (); { no strict 'refs'; @accessors = sort grep { defined &{"$class\::$_"} && $_ =~ /^name/ } %{"$class\::"}; ok 5 == @accessors, "$class has 5 name* accessors"; } ok $accessors[0] eq 'name_first', "$class has the name_first accessor"; ok $accessors[1] eq 'name_last', "$class has the name_last accessor"; ok $accessors[2] eq 'name_phone_0', "$class has the name_phone_0 accessor"; ok $accessors[3] eq 'name_phone_1', "$class has the name_phone_1 accessor"; ok $accessors[4] eq 'name_phone_2', "$class has the name_phone_2 accessor"; } { package TestClass::FieldAppend::Role; use Validation::Class; fld 'title' => {length => 1}; fld 'surname' => {min_length => 1}; package TestClass::FieldAppend; use Validation::Class; set role => 'TestClass::FieldAppend::Role'; fld '+title' => {required => 0, min_length => 1}; fld '++surname' => {max_length => 1}; package main; my $class = "TestClass::FieldAppend"; my $self = $class->new; my $title = $self->fields->get('title'); my $surname = $self->fields->get('surname'); ok $class eq ref $self, "$class instantiated"; ok(((!defined $title->{length} && defined $title->{required} && defined $title->{min_length}) and ($title->{required} == 0 && $title->{min_length} == 1)), "$class title field was overriden"); ok(((defined $surname->{min_length} && defined $surname->{max_length}) and ($surname->{min_length} == 1 && $surname->{max_length} == 1)), "$class surname field was appended"); } done_testing; T000755000765000024 014410403624 16670 5ustar00christiaanstaff000000000000Validation-Class-7.900059/t/libUser.pm100644000765000024 51114410403624 20261 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/lib/Tpackage T::User; use Validation::Class; field 'string' => { mixin => ':str' }; document 'user' => { 'id' => 'string', 'type' => 'string', 'name' => 'string', 'company' => 'string', 'login' => 'string', 'email' => 'string', 'locations.@' => 'location' }; 1; 02-integrity.t100644000765000024 204414410403624 20501 0ustar00christiaanstaff000000000000Validation-Class-7.900059/tuse FindBin; use Test::More; use utf8; use strict; use warnings; SKIP: { eval { require 'Perl/Critic.pm'; }; plan skip_all => 'Perl::Critic is not installed and/or DEVELOPMENT_TESTS is not set.' if $@ || ! $ENV{'DEVELOPMENT_TESTS'} ; my $lib = $FindBin::RealBin . "/../lib/"; my @profile = qw( -5 --severity 4 --exclude Modules::RequireVersionVar --exclude Subroutines::RequireArgUnpacking --exclude BuiltinFunctions::RequireBlockGrep --exclude Subroutines::ProhibitBuiltinHomonyms --exclude Modules::ProhibitAutomaticExportation --exclude TestingAndDebugging::ProhibitNoStrict --exclude TestingAndDebugging::ProhibitNoWarnings --exclude Variables::ProhibitConditionalDeclarations --exclude ValuesAndExpressions::ProhibitAccessOfPrivateData --exclude TestingAndDebugging::ProhibitProlongedStrictureOverride ); ok ! system("perlcritic", @profile, $lib), "library passes critique"; } done_testing; 03-streaming.t100644000765000024 314114410403624 20454 0ustar00christiaanstaff000000000000Validation-Class-7.900059/tuse FindBin; use Data::Dumper; use Test::More; use utf8; use strict; use warnings; { use_ok 'Validation::Class::Simple::Streamer'; # passable my $params = { user => 'admin', # arbitrary pass => 's3cret', # arbitrary email_1 => 'admin@cpan.org', # dynamic created email_2 => 'root@cpan.org', # dynamic created email_3 => 'sa@cpan.org', # dynamic created }; my $p1 = Validation::Class::Simple::Streamer->new(params => $params); if ($p1->check('user')->min_length(5)) { if ($p1->max_length(50)) { $p1->filters(['alpha', 'trim', 'strip']); ok $p1, "p1 validated"; ok $p1, "p1 still validated"; } } ok !$p1->min_symbols(1), "p1 fails to validate min_symbols:1"; ok $p1->min_symbols(0), "p1 passes to validate min_symbols:0"; $p1->check('arbitrary')->required; $p1->validate; ok "$p1" eq "arbitrary is required", "p1 error message is accurate"; $p1->fields->delete('user'); $p1->alias(['user'])->validate; ok "$p1" eq "", "p1 has no error messages"; $p1->clear; $p1->params->add(telephone => 11111); ok !$p1->check('telephone')->telephone, "p1 telephone number is invalid"; $p1->params->add(telephone => 2155551212); ok $p1->validate, "p1 telephone number is now valid"; $p1 = $p1->new(params => $params); $p1->check($_)->min_length(3)->required->email for qw(email_1 email_2 email_3) ; # we don't like @localhost ok $p1->validate, "all email addresses valid"; } done_testing; 00-load-simple.t100644000765000024 16514410403624 20651 0ustar00christiaanstaff000000000000Validation-Class-7.900059/tuse FindBin; use Test::More; use utf8; use strict; use warnings; use_ok 'Validation::Class::Simple'; done_testing; 99-override-bug.t100644000765000024 114714410403624 21100 0ustar00christiaanstaff000000000000Validation-Class-7.900059/tpackage TestBase; use Validation::Class; field foo => {required => 0,}; package TestDerived; use Validation::Class; set 'role' => 'TestBase'; field '++foo' => {required => 1,}; package main; use Test::More; use strict; use warnings; my $base = TestBase->new(params => {foo => undef}); ok($base->validate('foo'), 'base: foo not required'); my $derived = TestDerived->new(params => {foo => undef}); ok(!$derived->validate('foo'), 'derived: foo is required'); $derived->foo('bar'); ok($derived->validate('foo'), 'derived: foo is required'); ok($base->validate('foo'), 'base: foo not required'); done_testing(); 04-dot-notation.t100644000765000024 331414410403624 21105 0ustar00christiaanstaff000000000000Validation-Class-7.900059/tuse FindBin; use Test::More; use utf8; use strict; use warnings; { package TestClass::DotNoation; use Validation::Class; has update => 0; field 'public.fullname' => { mixin => [':str', ':full_name'], filters => ['autocase'], required => 1, }; field 'private.fullname' => { mixin => ':str', required => 1, }; field 'private.emailaddress' => { mixin => ':str', required => 1, email => 1 }; method 'dienice' => { input => ['private.emailaddress', 'private.fullname'], using => sub { my $self = shift; $self->update(1); } }; package main; my $class = "TestClass::DotNoation"; my $self = $class->new( params => { 'public.fullname' => 'Al Newkirk', 'private.fullname' => 'Al Newkirk', 'private.emailaddress' => 'awncorp@cpan.org', } ); ok $class eq ref $self, "$class instantiated"; ok $self->can('public_fullname'), "$class has public_fullname"; ok $self->can('private_emailaddress'), "$class has private_emailaddress"; ok $self->can('private_fullname'), "$class has private_fullname"; ok $self->can('dienice'), "$class has method dienice"; ok $self->validate('private.emailaddress', 'private.fullname'), "$class validated private.emailaddress and private.fullname directly" ; ok $self->dienice, "$class validated private.emailaddress and private.fullname via dienice" ; ok $self->update, "$class set the 'updated' attr from the dienice self-validating method" ; } done_testing; 07-adopt-syntax.t100644000765000024 161714410403624 21130 0ustar00christiaanstaff000000000000Validation-Class-7.900059/tuse FindBin; use Test::More; use utf8; use strict; use warnings; { use_ok 'Validation::Class'; } { package TestClass::A; use Validation::Class; field name => {mixin => ':str'}; field color => {mixin => ':str'}; field year => {mixin => ':str'}; method redish_brown => { input => ['color'], using => sub { 1 } }; package TestClass::B; use Validation::Class; adopt 'TestClass::A', 'field', 'name'; adopt 'TestClass::A', 'field', 'color'; adopt 'TestClass::A', 'method', 'redish_brown'; package main; my $b = TestClass::B->new(color => 'red'); ok "TestClass::B" eq ref $b, "TestClass::B instantiated"; ok $b->proto->fields->has($_) => "TestClass::B has $_" for qw(name color); can_ok $b, qw(name color redish_brown); ok $b->redish_brown() => "TestClass::B redish_brown executed and valid"; } done_testing(); Location.pm100644000765000024 62414410403624 21120 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/lib/Tpackage T::Location; use Validation::Class; field 'state' => { state => 1 }; field 'string' => { mixin => ':str' }; document 'location' => { 'id' => 'string', 'type' => 'string', 'name' => 'string', 'company' => 'string', 'address1' => 'string', 'address2' => 'string', 'city' => 'string', 'state' => 'state', 'zip' => 'string' }; 1; 08-ensure-syntax.t100644000765000024 275114410403624 21323 0ustar00christiaanstaff000000000000Validation-Class-7.900059/tuse FindBin; use Test::More; use utf8; use strict; use warnings; { package TestClass::EnsureMethod1; use Validation::Class; field name => { required => 1, min_length => 2 }; sub append_name { my ($self, $text) = @_; $text ||= 'is a genius'; $self->name($self->name . ' ' . $text); return $self->name; } ensure append_name => { input => ['name'], output => ['name'] }; package main; my $class = "TestClass::EnsureMethod1"; my $self = $class->new; ok $class eq ref $self, "$class instantiated"; $self->name('i'); ok ! $self->append_name('is a fool'), 'validation failed'; like $self->errors_to_string => qr/2 char/, 'has error message'; $self->name('me'); ok $self->append_name('is a fool'), 'routine executed'; like $self->name => qr/is a fool/, 'name appended as expected'; ok ! $self->errors_to_string, 'no errors exist'; } { package TestClass::EnsureMethod2; use Validation::Class; field name => { required => 1, min_length => 2 }; ensure name => { output => ['+name'] }; package main; my $class = "TestClass::EnsureMethod2"; my $self = $class->new; ok $class eq ref $self, "$class instantiated"; eval { $self->name('i') }; like $@ => qr/less.*2 char/, "post-field update failed validation"; eval { $self->name('me') }; die $@ if $@; ok !$@ && $self->is_valid, "post field update passed validation"; } done_testing; 05-method-syntax.t100644000765000024 275614410403624 21304 0ustar00christiaanstaff000000000000Validation-Class-7.900059/tuse FindBin; use Test::More; use utf8; use strict; use warnings; { package TestClass::MethodCalling; use Validation::Class; field constraint => {required => 1}; method check_a => {input => ['constraint']}; sub _check_a {'check_a OK'} method a_check => {input => ['constraint']}; sub _process_a_check {'check_a OK'} package main; my $class = "TestClass::MethodCalling"; my $self = $class->new; ok $class eq ref $self, "$class instantiated"; $self->constraint('h@ck'); ok 'check_a OK' eq $self->check_a, "$class check_a method spec'd and validated"; for (1..5) { ok 'check_a OK' eq $self->a_check, "$_: $class a_check method spec'd and validated"; ok 1 == $self->validate_method('a_check'), "$_: $class a_check method validated but NOT executed"; ok 'check_a OK' eq $self->a_check, "$_: $class a_check method spec'd and validated (again)"; } $self->constraint(undef); ok !defined $self->a_check, "$class a_check method failed to validate"; $self->constraint('stuff'); ok 'check_a OK' eq $self->a_check, "$class a_check method spec'd and validated"; $self->constraint(undef); ok 0 == $self->validate_method('a_check'), "$class a_check method does NOT validate and is NOT executed"; $self->constraint('stuff'); ok 'check_a OK' eq $self->a_check, "$class a_check method spec'd and validated (again)"; } done_testing; 06-load-settings.t100644000765000024 311314410403624 21242 0ustar00christiaanstaff000000000000Validation-Class-7.900059/tuse FindBin; use Test::More; use utf8; use strict; use warnings; { use_ok 'Validation::Class'; use_ok 'Validation::Class::Prototype'; use_ok 'Validation::Class::Mapping'; } { { package TestClass::A; use Validation::Class; field 'test_a'; my $set = Validation::Class->prototype(__PACKAGE__)->configuration->settings; $set->{unit} ||= {}; $set->{unit}->{'test_a'} = { test => 'ok' }; } { package TestClass::B; use Validation::Class; field 'test_b'; my $set = Validation::Class->prototype(__PACKAGE__)->configuration->settings; $set->{unit} ||= {}; $set->{unit}->{'test_b'} = { test => 'ok' }; } { package TestClass; use Validation::Class 'set'; set roles => ['TestClass::A', 'TestClass::B']; my $set = Validation::Class->prototype(__PACKAGE__)->configuration->settings; $set->{unit} ||= {}; $set->{unit}->{'test'} = { test => 'ok' }; } package main; my $t = TestClass->new; ok "TestClass" eq ref $t, "TestClass instantiated"; my $settings = $t->proto->settings; ok "Validation::Class::Mapping" eq ref $settings, "TestClass settings initialized"; my $unit = $settings->{unit}; ok "HASH" eq ref $unit, "TestClass settings/unit initialized"; my $data = { test => { test => 'ok' }, test_a => { test => 'ok' }, test_b => { test => 'ok' }, }; is_deeply $unit, $data, "TestClass settings/unit deeply okay"; } done_testing(); 05-filters-usage.t100644000765000024 672214410403624 21247 0ustar00christiaanstaff000000000000Validation-Class-7.900059/tuse FindBin; use Test::More; use utf8; use strict; use warnings; { package TestClass::FiltersUsage; use Validation::Class; filter 'flatten' => sub { $_[0] =~ s/[\t\r\n]+/ /g; return $_[0]; }; field 'biography' => { filters => ['trim', 'strip', 'flatten'], alias => ['bio'] }; 1; package main; my $biography = <<'TEXT'; 1. In arcu mi, sagittis vel pretium sit amet, tempor ac risus. 2. Integer facilisis, ante ac tincidunt euismod, metus tortor. 3. Suscipit erat, nec porta arcu urna eu nisl. TEXT my $self; my $class = "TestClass::FiltersUsage"; $self = $class->new(biography => $biography); ok $class eq ref $self, "$class instantiated"; is_deeply $self->fields->biography->filters, ['trim', 'strip', 'flatten'], "$class has biography field with filters trim, strip and flatten"; ok $self->params->get('biography') =~ /^[^\n]+$/, "$class biography filter executed as expected"; $self = $class->new(bio => $biography); ok $class eq ref $self, "$class instantiated"; is_deeply $self->fields->biography->filters, ['trim', 'strip', 'flatten'], "$class has biography field with filters trim, strip and flatten"; ok $self->params->get('biography') =~ /^[^\n]+$/, "$class biography filter executed as expected"; } { package TestClass::FiltersAliasUsage::A; use Validation::Class; field 'full_name' => { filters => ['trim', 'strip', 'titlecase'], alias => ['name'] }; 1; package main; my $self; my $class = "TestClass::FiltersAliasUsage::A"; $self = $class->new(full_name => 'elliot '); ok $class eq ref $self, "$class instantiated"; is_deeply $self->fields->full_name->filters, ['trim', 'strip', 'titlecase'], "$class has full_name field with filters trim, strip and titlecase"; ok $self->param('full_name') =~ /^Elliot$/, "$class full_name filter executed as expected"; $self = $class->new(name => ' elliot '); ok $class eq ref $self, "$class instantiated"; is_deeply $self->fields->full_name->filters, ['trim', 'strip', 'titlecase'], "$class has full_name field with filters trim, strip and titlecase"; ok $self->param('full_name') =~ /^Elliot$/, "$class full_name filter executed as expected"; } { package TestClass::FiltersAliasUsage::B; use Validation::Class; field 'full_name' => { filters => ['trim', 'strip', 'titlecase'], alias => ['name'] }; 1; package main; my $self; my $class = "TestClass::FiltersAliasUsage::B"; $self = $class->new; $self->params->add({name => 'elliot '}); $self->prototype->normalize($self); ok $class eq ref $self, "$class instantiated"; is_deeply $self->fields->full_name->filters, ['trim', 'strip', 'titlecase'], "$class has full_name field with filters trim, strip and titlecase"; ok $self->full_name =~ /^Elliot$/, "$class full_name filter executed as expected"; $self = $class->new; $self->params->add({name => ' elliot '}); $self->prototype->normalize($self); ok $class eq ref $self, "$class instantiated"; is_deeply $self->fields->full_name->filters, ['trim', 'strip', 'titlecase'], "$class has full_name field with filters trim, strip and titlecase"; ok $self->full_name =~ /^Elliot$/, "$class full_name filter executed as expected"; } done_testing; 04-proxy-methods.t100644000765000024 221114410403624 21303 0ustar00christiaanstaff000000000000Validation-Class-7.900059/tuse FindBin; use Test::More; use utf8; use strict; use warnings; { package TestClass::ProxyMethods; use Validation::Class; package main; my $class = "TestClass::ProxyMethods"; my $self = $class->new; ok $class eq ref $self, "$class instantiated"; my @meths = (qw( class clear_queue error error_count error_fields errors errors_to_string get_errors get_fields get_hash get_params get_values fields filtering ignore_failure ignore_unknown param params plugin queue report_failure report_unknown reset_errors reset_fields reset_params set_errors set_fields set_params stash ), # wrapped qw( validate validates validate_method method_validates validate_profile profile_validates )); for my $m (@meths) { ok $self->can($m), "$class can access the prototype method $m directly by proxy" } } done_testing; Validation000755000765000024 014410403624 20314 5ustar00christiaanstaff000000000000Validation-Class-7.900059/libClass.pm100644000765000024 12420714410403624 22125 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation# ABSTRACT: Powerful Data Validation Framework package Validation::Class; use 5.10.0; use strict; use warnings; use Module::Find; use Validation::Class::Util '!has'; use Clone 'clone'; use Exporter (); use Validation::Class::Prototype; our $VERSION = '7.900059'; # VERSION our @ISA = qw(Exporter); our @EXPORT = qw( adopt adt attribute bld build dir directive doc document ens ensure fld field flt filter has load msg message mth method mxn mixin pro profile set ); sub return_class_proto { my $class = shift || caller(2); return prototype_registry->get($class) || do { # build new prototype class my $proto = Validation::Class::Prototype->new( package => $class ); no strict 'refs'; no warnings 'redefine'; # respect foreign constructors (such as $class->new) if found my $new = $class->can("new") ? "initialize_validator" : "new" ; # injected into every derived class (override if necessary) *{"$class\::$new"} = sub { goto \&$new }; *{"$class\::proto"} = sub { goto \&prototype }; *{"$class\::prototype"} = sub { goto \&prototype }; # inject prototype class aliases unless exist my @aliases = $proto->proxy_methods; foreach my $alias (@aliases) { next if $class->can($alias); # slight-of-hand $proto->set_method($alias, sub { shift @_; $proto->$alias(@_); }); } # inject wrapped prototype class aliases unless exist my @wrapped_aliases = $proto->proxy_methods_wrapped; foreach my $alias (@wrapped_aliases) { next if $class->can($alias); # slight-of-hand $proto->set_method($alias, sub { my $self = shift @_; $proto->$alias($self, @_); }); } # cache prototype prototype_registry->add($class => $proto); $proto; # return-once }; } sub configure_class_proto { my $configuration_routine = pop; return unless "CODE" eq ref $configuration_routine; no strict 'refs'; my $proto = return_class_proto shift; $configuration_routine->($proto); return $proto; } sub import { my $caller = caller(0) || caller(1); strict->import; warnings->import; __PACKAGE__->export_to_level(1, @_); return return_class_proto $caller # provision prototype when used } sub initialize_validator { my $self = shift; my $proto = $self->prototype; my $arguments = $proto->build_args(@_); # provision a validation class configuration $proto->snapshot; # override prototype attributes if requested if (defined($arguments->{fields})) { my $fields = delete $arguments->{fields}; $proto->fields->clear->add($fields); } if (defined($arguments->{params})) { my $params = delete $arguments->{params}; $proto->params->clear->add(clone $params); } # process attribute assignments my $proxy_methods = { map { $_ => 1 } ($proto->proxy_methods) } ; while (my($name, $value) = each (%{$arguments})) { $self->$name($value) if $self->can($name) && $proto->fields->has($name) || $proto->attributes->has($name) || $proxy_methods->{$name} ; } # process builders foreach my $builder ($proto->builders->list) { $builder->($self, $arguments); } # initialize prototype $proto->normalize($self); # ready-set-go !!! return $self; } sub adt { goto &adopt } sub adopt { my $package = shift if @_ == 4; my ($class, $type, $name) = @_; my $aliases = { has => 'attribute', dir => 'directive', doc => 'document', fld => 'field', flt => 'filter', msg => 'message', mth => 'method', mxn => 'mixin', pro => 'profile' }; my $keywords = { map { $_ => $_ } values %{$aliases} }; $type = $keywords->{$type} || $aliases->{$type}; return unless $class && $name && $type; my $store = "${type}s"; my $config = prototype_registry->get($class)->configuration; my $data = clone $config->$store->get($name); @_ = ($name => $data) and goto &$type; return; } sub has { goto &attribute } sub attribute { my $package = shift if @_ == 3; my ($attributes, $default) = @_; return unless $attributes; $attributes = [$attributes] unless isa_arrayref $attributes; return configure_class_proto $package => sub { my ($proto) = @_; $proto->register_attribute($_ => $default) for @{$attributes}; return $proto; }; } sub bld { goto &build } sub build { my $package = shift if @_ == 2; my ($code) = @_; return unless ("CODE" eq ref $code); return configure_class_proto $package => sub { my ($proto) = @_; $proto->register_builder($code); return $proto; }; } sub dir { goto &directive } sub directive { my $package = shift if @_ == 3; my ($name, $code) = @_; return unless ($name && $code); return configure_class_proto $package => sub { my ($proto) = @_; $proto->register_directive($name, $code); return $proto; }; } sub doc { goto &document } sub document { my $package = shift if @_ == 3; my ($name, $data) = @_; $data ||= {}; return unless ($name && $data); return configure_class_proto $package => sub { my ($proto) = @_; $proto->register_document($name, $data); return $proto; }; }; sub ens { goto &ensure } sub ensure { my $package = shift if @_ == 3; my ($name, $data) = @_; $data ||= {}; return unless ($name && $data); return configure_class_proto $package => sub { my ($proto) = @_; $proto->register_ensure($name, $data); return $proto; }; } sub fld { goto &field } sub field { my $package = shift if @_ == 3; my ($name, $data) = @_; $data ||= {}; return unless ($name && $data); return configure_class_proto $package => sub { my ($proto) = @_; $proto->register_field($name, $data); return $proto; }; } sub flt { goto &filter } sub filter { my $package = shift if @_ == 3; my ($name, $code) = @_; return unless ($name && $code); return configure_class_proto $package => sub { my ($proto) = @_; $proto->register_filter($name, $code); return $proto; }; } sub set { goto &load } sub load { my $package; my $data; # handle different types of invocations # 1 - load({}) # 2+ - load(a => b) # 2+ - package->load({}) # 3+ - package->load(a => b) # -- # load({}) if (@_ == 1) { if ("HASH" eq ref $_[0]) { $data = shift; } } # load(a => b) # package->load({}) elsif (@_ == 2) { if ("HASH" eq ref $_[-1]) { $package = shift; $data = shift; } else { $data = {@_}; } } # load(a => b) # package->load(a => b) elsif (@_ >= 3) { if (@_ % 2) { $package = shift; $data = {@_}; } else { $data = {@_}; } } return configure_class_proto $package => sub { my ($proto) = @_; $proto->register_settings($data); return $proto; }; } sub msg { goto &message } sub message { my $package = shift if @_ == 3; my ($name, $template) = @_; return unless ($name && $template); return configure_class_proto $package => sub { my ($proto) = @_; $proto->register_message($name, $template); return $proto; }; } sub mth { goto &method } sub method { my $package = shift if @_ == 3; my ($name, $data) = @_; return unless ($name && $data); return configure_class_proto $package => sub { my ($proto) = @_; $proto->register_method($name, $data); return $proto; }; } sub mxn { goto &mixin } sub mixin { my $package = shift if @_ == 3; my ($name, $data) = @_; $data ||= {}; return unless ($name && $data); return configure_class_proto $package => sub { my ($proto) = @_; $proto->register_mixin($name, $data); return $proto; }; } sub new { my $class = shift; $class = ref $class || $class; my $proto = return_class_proto $class; my $self = bless {}, $class; initialize_validator $self, @_; return $self; } sub pro { goto &profile } sub profile { my $package = shift if @_ == 3; my ($name, $code) = @_; return unless ($name && $code); return configure_class_proto $package => sub { my ($proto) = @_; $proto->register_profile($name, $code); return $proto; }; } sub proto { goto &prototype } sub prototype { my ($self) = pop @_; return return_class_proto ref $self || $self; } 1; __END__ =pod =head1 NAME Validation::Class - Powerful Data Validation Framework =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple::Streamer; my $params = {username => 'admin', password => 's3cret'}; my $input = Validation::Class::Simple::Streamer->new(params => $params); # check username parameter $input->check('username')->required->between('5-255'); $input->filters([qw/trim strip/]); # check password parameter $input->check('password')->required->between('5-255')->min_symbols(1); $input->filters([qw/trim strip/]); # run validate $input->validate or die $input->errors_to_string; =head1 DESCRIPTION Validation::Class is a scalable data validation library with interfaces for applications of all sizes. The most common usage of Validation::Class is to transform class namespaces into data validation domains where consistency and reuse are primary concerns. Validation::Class provides an extensible framework for defining reusable data validation rules. It ships with a complete set of pre-defined validations and filters referred to as L<"directives"|Validation::Class::Directives/DIRECTIVES>. The core feature-set consist of self-validating methods, validation profiles, reusable validation rules and templates, pre and post input filtering, class inheritance, automatic array handling, and extensibility (e.g. overriding default error messages, creating custom validators, creating custom input filters and much more). Validation::Class promotes DRY (don't repeat yourself) code. The main benefit in using Validation::Class is that the architecture is designed to increase the consistency of data input handling. The following is a more traditional usage of Validation::Class, using the DSL to construct a validator class: package MyApp::Person; use Validation::Class; # data validation template mixin basic => { required => 1, max_length => 255, filters => [qw/trim strip/] }; # data validation rules for the username parameter field username => { mixin => 'basic', min_length => 5 }; # data validation rules for the password parameter field password => { mixin => 'basic', min_length => 5, min_symbols => 1 }; package main; my $person = MyApp::Person->new(username => 'admin', password => 'secr3t'); # validate rules on the person object unless ($person->validates) { # handle the failures warn $person->errors_to_string; } 1; =head1 QUICKSTART If you are looking for a simple in-line data validation module built using the same tenets and principles as Validation::Class, please review L or L. If you are new to Validation::Class, or would like more information on the underpinnings of this library and how it views and approaches data validation, please review L. Please review the L for a detailed step-by-step look into how Validation::Class works. =head1 KEYWORDS =head2 adopt The adopt keyword (or adt) copies configuration and functionality from other Validation::Class classes. The adopt keyword takes three arguments, the name of the class to be introspected, and the configuration type and name to be recreated. Basically, anything you can configure using a Validation::Class keyword can be adopted into other classes using this keyword with the exception of coderefs registered using the build keyword. Please note! If you are adopting a field declaration which has an associated mixin directive defined on the target class, you must adopt the mixin explicitly if you wish it's values to be interpolated. package MyApp::Exployee; use Validate::Class; use MyApp::Person; adopt MyApp::Person, mixin => 'basic'; adopt MyApp::Person, field => 'first_name'; adopt MyApp::Person, field => 'last_name'; adopt MyApp::Person, profile => 'has_fullname'; 1; =head2 attribute The attribute keyword (or has) registers a class attribute, i.e. it creates an accessor (getter and setter) on the class. Attribute declaration is flexible and only requires an attribute name to be configured. Additionally, the attribute keyword can takes two arguments, the attribute's name and a scalar or coderef to be used as it's default value. package MyApp::Person; use Validate::Class; attribute 'first_name' => 'Peter'; attribute 'last_name' => 'Venkman'; attribute 'full_name' => sub { join ', ', $_[0]->last_name, $_[0]->first_name }; attribute 'email_address'; 1; =head2 build The build keyword (or bld) registers a coderef to be run at instantiation much in the same way the common BUILD routine is used in modern OO frameworks. package MyApp::Person; use Validation::Class; build sub { my ($self, $args) = @_; # run after instantiation in the order defined }; 1; The build keyword takes one argument, a coderef which is passed the instantiated class object. =head2 directive The directive keyword (or dir) registers custom validator directives to be used in your field definitions. Please note that custom directives can only be used with field definitions. This is a means of extending the list of directives per instance. See the list of core directives, L, or review L for insight into creating your own CPAN installable directives. package MyApp::Person; use Validate::Class; # define a custom class-level directive directive 'blacklisted' => sub { my ($self, $field, $param) = @_; if (defined $field->{blacklisted} && defined $param) { if ($field->{required} || $param) { if (exists_in_blacklist($field->{blacklisted}, $param)) { my $handle = $field->label || $field->name; $field->errors->add("$handle has been blacklisted"); return 0; } } } return 1; }; field 'email_address' => { blacklisted => '/path/to/blacklist' email => 1, }; 1; The directive keyword takes two arguments, the name of the directive and a coderef which will be used to validate the associated field. The coderef is passed four ordered parameters; a directive object, the class prototype object, the current field object, and the matching parameter's value. The validator (coderef) is evaluated by its return value as well as whether it altered any error containers. =head2 document The document keyword (or doc) registers a data matching profile which can be used to validate heiarchal data. It will store a hashref with pre-define path matching rules for the data structures you wish to validate. The "path matching rules", which use a specialized object notation, referred to as the document notation, can be thought of as a kind-of simplified regular expression which is executed against the flattened data structure. The following are a few general use-cases: package MyApp::Person; use Validation::Class; field 'string' => { mixin => [':str'] }; # given this JSON data structure { "id": "1234-A", "name": { "first_name" : "Bob", "last_name" : "Smith", }, "title": "CIO", "friends" : [], } # select id to validate against the string rule document 'foobar' => { 'id' => 'string' }; # select name -> first_name/last_name to validate against the string rule document 'foobar' => {'name.first_name' => 'string', 'name.last_name' => 'string'}; # or document 'foobar' => {'name.*_name' => 'string'}; # select each element in friends to validate against the string rule document 'foobar' => { 'friends.@' => 'string' }; # or select an element of a hashref in each element in friends to validate # against the string rule document 'foobar' => { 'friends.@.name' => 'string' }; The document declaration's keys should follow the aforementioned document notation schema and it's values should be strings which correspond to the names of fields (or other document declarations) that will be used to preform the data validation. It is possible to combine document declarations to validate hierarchical data that contains data structures matching one or more document patterns. The following is an example of what that might look like. package MyApp::Person; use Validation::Class; # data validation rule field 'name' => { mixin => [':str'], pattern => qr/^[A-Za-z ]+$/, max_length => 20, }; # data validation map / document notation schema document 'friend' => { 'name' => 'name' }; # data validation map / document notation schema document 'person' => { 'name' => 'name', 'friends.@' => 'friend' }; package main; my $data = { "name" => "Anita Campbell-Green", "friends" => [ { "name" => "Horace" }, { "name" => "Skinner" }, { "name" => "Alonzo" }, { "name" => "Frederick" }, ], }; my $person = MyApp::Person->new; unless ($person->validate_document(person => $data)) { warn $person->errors_to_string if $person->error_count; } 1; Alternatively, the following is a more verbose data validation class using traditional styling and configuration. package MyApp::Person; use Validation::Class; field 'id' => { mixin => [':str'], filters => ['numeric'], max_length => 2, }; field 'name' => { mixin => [':str'], pattern => qr/^[A-Za-z ]+$/, max_length => 20, }; field 'rating' => { mixin => [':str'], pattern => qr/^\-?\d+$/, }; field 'tag' => { mixin => [':str'], pattern => qr/^(?!evil)\w+/, max_length => 20, }; document 'person' => { 'id' => 'id', 'name' => 'name', 'company.name' => 'name', 'company.supervisor.name' => 'name', 'company.supervisor.rating.@.*' => 'rating', 'company.tags.@' => 'name' }; package main; my $data = { "id" => "1234-ABC", "name" => "Anita Campbell-Green", "title" => "Designer", "company" => { "name" => "House of de Vil", "supervisor" => { "name" => "Cruella de Vil", "rating" => [ { "support" => -9, "guidance" => -9 } ] }, "tags" => [ "evil", "cruelty", "dogs" ] }, }; my $person = MyApp::Person->new; unless ($person->validate_document(person => $data)) { warn $person->errors_to_string if $person->error_count; } 1; Additionally, the following is yet another way to validate a document by passing the document specification directly instead of by name. package MyApp::Person; use Validation::Class; package main; my $data = { "id" => "1234-ABC", "name" => "Anita Campbell-Green", "title" => "Designer", "company" => { "name" => "House of de Vil", "supervisor" => { "name" => "Cruella de Vil", "rating" => [ { "support" => -9, "guidance" => -9 } ] }, "tags" => [ "evil", "cruelty", "dogs" ] }, }; my $spec = { 'id' => { max_length => 2 }, 'name' => { mixin => ':str' }, 'company.name' => { mixin => ':str' }, 'company.supervisor.name' => { mixin => ':str' }, 'company.supervisor.rating.@.*' => { pattern => qr/^(?!evil)\w+/ }, 'company.tags.@' => { max_length => 20 }, }; my $person = MyApp::Person->new; unless ($person->validate_document($spec => $data)) { warn $person->errors_to_string if $person->error_count; } 1; =head2 ensure The ensure keyword (or ens) is used to convert a pre-existing method into an auto-validating method. The auto-validating method will be registered and function as if it was created using the method keyword. The original pre-existing method will be overridden with a modified version which performs the pre and/or post validation routines. package MyApp::Person; use Validation::Class; sub register { ... } ensure register => { input => ['name', '+email', 'username', '+password', '+password2'], output => ['+id'], # optional output validation, dies on failure }; package main; my $person = MyApp::Person->new(params => $params); if ($person->register) { # handle the successful registration } 1; The ensure keyword takes two arguments, the name of the method to be overridden and a hashref of required key/value pairs. The hashref may have an input key (e.g. input, input_document, input_profile, or input_method). The `input` key (specifically) must have a value which must be either an arrayref of fields to be validated, or a scalar value which matches (a validation profile or auto-validating method name). The hashref may also have an output key (e.g. output, output_document, output_profile, or output_method). The `output` key (specifically) must have a value which must be either an arrayref of fields to be validated, or a scalar value which matches (a validation profile or auto-validating method name). Whether and what the method returns is yours to decide. The method will return undefined if validation fails. The ensure keyword wraps and functions much in the same way as the method keyword. =head2 field The field keyword (or fld) registers a data validation rule for reuse and validation in code. The field name should correspond with the parameter name expected to be passed to your validation class or validated against. package MyApp::Person; use Validation::Class; field 'username' => { required => 1, min_length => 1, max_length => 255 }; The field keyword takes two arguments, the field name and a hashref of key/values pairs known as directives. For more information on pre-defined directives, please review the L<"list of core directives"|Validation::Class::Directives/DIRECTIVES>. The field keyword also creates accessors which provide easy access to the field's corresponding parameter value(s). Accessors will be created using the field's name as a label having any special characters replaced with an underscore. # accessor will be created as send_reminders field 'send-reminders' => { length => 1 }; Please note that prefixing field names with a double plus-symbol instructs the register to merge your declaration with any pre-existing declarations within the same scope (e.g. fields imported via loading roles), whereas prefixing field names with a single plus-symbol instructs the register to overwrite any pre-existing declarations. package MyApp::Person; use Validation::Class; set role => 'MyApp::User'; # append existing field and overwrite directives field '++email_address' => { required => 1 }; # redefine existing field field '+login' => { required => 1 }; 1; =head2 filter The filter keyword (or flt) registers custom filters to be used in your field definitions. It is a means of extending the pre-existing filters declared by the L<"filters directive"|Validation::Class::Directive::Filters> before instantiation. package MyApp::Person; use Validate::Class; filter 'flatten' => sub { $_[0] =~ s/[\t\r\n]+/ /g; return $_[0]; }; field 'biography' => { filters => ['trim', 'strip', 'flatten'] }; 1; The filter keyword takes two arguments, the name of the filter and a coderef which will be used to filter the value the associated field. The coderef is passed the value of the field and that value MUST be operated on directly. The coderef should also return the transformed value. =head2 load The load keyword (or set), which can also be used as a class method, provides options for extending the current class by declaring roles, requirements, etc. The process of applying roles, requirement, and other settings to the current class mainly involves introspecting the namespace's methods and merging relevant parts of the prototype configuration. =head2 load-classes The `classes` (or class) option uses L to load all child classes (in-all-subdirectories) for convenient access through the L method, and when introspecting a larger application. This option accepts an arrayref or single argument. package MyApp; use Validation::Class; load classes => ['MyApp::Domain1', 'MyApp::Domain2']; package main; my $app = MyApp->new; my $person = $app->class('person'); # return a new MyApp::Person object 1; =head2 load-requirements package MyApp::User; use Validate::Class; load requirements => 'activate'; package MyApp::Person; use Validation::Class; load role => 'MyApp::User'; sub activate {} 1; The `requirements` (or required) option is used to ensure that if/when the class is used as a role the calling class has specific pre-existing methods. This option accepts an arrayref or single argument. package MyApp::User; use Validate::Class; load requirements => ['activate', 'deactivate']; 1; =head2 load-roles package MyApp::Person; use Validation::Class; load role => 'MyApp::User'; 1; The `roles` (or role) option is used to load and inherit functionality from other validation classes. These classes should be used and thought-of as roles although they can also be fully-functioning validation classes. This option accepts an arrayref or single argument. package MyApp::Person; use Validation::Class; load roles => ['MyApp::User', 'MyApp::Visitor']; 1; =head2 message The message keyword (or msg) registers a class-level error message template that will be used in place of the error message defined in the corresponding directive class if defined. Error messages can also be overridden at the individual field-level as well. See the L for instructions on how to override error messages at the field-level. package MyApp::Person; use Validation::Class; field email_address => { required => 1, min_length => 3, messages => { # field-level error message override min_length => '%s is not even close to being a valid email address' } }; # class-level error message overrides message required => '%s is needed to proceed'; message min_length => '%s needs more characters'; 1; The message keyword takes two arguments, the name of the directive whose error message you wish to override and a string which will be used to as a template which is feed to sprintf to format the message. =head2 method The method keyword (or mth) is used to register an auto-validating method. Similar to method signatures, an auto-validating method can leverage pre-existing validation rules and profiles to ensure a method has the required pre/post-conditions and data necessary for execution. package MyApp::Person; use Validation::Class; method 'register' => { input => ['name', '+email', 'username', '+password', '+password2'], output => ['+id'], # optional output validation, dies on failure using => sub { my ($self, @args) = @_; # do something registrationy $self->id(...); # set the ID field for output validation return $self; } }; package main; my $person = MyApp::Person->new(params => $params); if ($person->register) { # handle the successful registration } 1; The method keyword takes two arguments, the name of the method to be created and a hashref of required key/value pairs. The hashref may have a `using` key whose value is the coderef to be executed upon successful validation. The `using` key is only optional when a pre-existing subroutine has the same name or the method being declared prefixed with a dash or dash-process-dash. The following are valid subroutine names to be called by the method declaration in absence of a `using` key. Please note, unlike the ensure keyword, any pre-existing subroutines will not be wrapped-and-replaced and can be executed without validation if called directly. sub _name { ... } sub _process_name { ... } The hashref may have an input key (e.g. input, input_document, input_profile, or input_method). The `input` key (specifically) must have a value which must be either an arrayref of fields to be validated, or a scalar value which matches (a validation profile or auto-validating method name), which will be used to perform data validation B the aforementioned coderef has been executed. Whether and what the method returns is yours to decide. The method will return undefined if validation fails. # alternate usage method 'registration' => { input => ['name', '+email', 'username', '+password', '+password2'], output => ['+id'], # optional output validation, dies on failure }; sub _process_registration { my ($self, @args) = @_; $self->id(...); # set the ID field for output validation return $self; } Optionally the hashref may also have an output key (e.g. output, output_document, output_profile, or output_method). The `output` key (specifically) must have a value which must be either an arrayref of fields to be validated, or a scalar value which matches (a validation profile or auto-validating method name), which will be used to perform data validation B the aforementioned coderef has been executed. Please note that output validation failure will cause the program to die, the premise behind this decision is based on the assumption that given successfully validated input a routine's output should be predictable and if an error occurs it is most-likely a program error as opposed to a user error. See the ignore_failure and report_failure attributes on the prototype to control how method validation failures are handled. =head2 mixin The mixin keyword (or mxn) registers a validation rule template that can be applied (or "mixed-in") to any field by specifying the mixin directive. Mixin directives are processed first so existing field directives will override any directives created by the mixin directive. package MyApp::Person; use Validation::Class; mixin 'boilerplate' => { required => 1, min_length => 1, max_length => 255 }; field 'username' => { # min_length, max_length, .. required will be overridden mixin => 'boilerplate', required => 0 }; Since version 7.900015, all classes are automatically configured with the following default mixins for the sake of convenience: mixin ':flg' => { required => 1, min_length => 1, filters => [qw/trim strip numeric/], between => [0, 1] }; mixin ':num' => { required => 1, min_length => 1, filters => [qw/trim strip numeric/] }; mixin ':str' => { required => 1, min_length => 1, filters => [qw/trim strip/] }; Please note that the aforementioned mixin names are prefixed with a semi-colon but are treated as an exception to the rule. Prefixing mixin names with a double plus-symbol instructs the register to merge your declaration with any pre-existing declarations within the same scope (e.g. mixins imported via loading roles), whereas prefixing mixin names with a single plus-symbol instructs the register to overwrite any pre-existing declarations. package MyApp::Moderator; use Validation::Class; set role => 'MyApp::Person'; # overwrite and append existing mixin mixin '++boilerplate' => { min_symbols => 1 }; # redefine existing mixin mixin '+username' => { required => 1 }; 1; The mixin keyword takes two arguments, the mixin name and a hashref of key/values pairs known as directives. =head2 profile The profile keyword (or pro) registers a validation profile (coderef) which as in the traditional use of the term is a sequence of validation routines that validates data relevant to a specific action. package MyApp::Person; use Validation::Class; profile 'check_email' => sub { my ($self, @args) = @_; if ($self->email_exists) { my $email = $self->fields->get('email'); $email->errors->add('Email already exists'); return 0; } return 1; }; package main; my $user = MyApp::Person->new(params => $params); unless ($user->validate_profile('check_email')) { # handle failures } 1; The profile keyword takes two arguments, a profile name and coderef which will be used to execute a sequence of actions for validation purposes. =head1 METHODS =head2 new The new method instantiates a new class object, it performs a series of actions (magic) required for the class to function properly, and for that reason, this method should never be overridden. Use the build keyword for hooking into the instantiation process. In the event a foreign (pre-existing) `new` method is detected, an `initialize_validator` method will be injected into the class containing the code (magic) necessary to normalize your environment. package MyApp::Person; use Validation::Class; # hook build sub { my ($self, @args) = @_; # on instantiation }; sub new { # rolled my own my $self = bless {}, shift; # execute magic $self->initialize_validator; } 1; =head2 prototype The prototype method (or proto) returns an instance of the associated class prototype. The class prototype is responsible for manipulating and validating the data model (the class). It is not likely that you'll need to access this method directly, see L. package MyApp::Person; use Validation::Class; package main; my $person = MyApp::Person->new; my $prototype = $person->prototype; 1; =head1 PROXY METHODS Validation::Class mostly provides sugar functions for modeling your data validation requirements. Each class you create is associated with a prototype class which provides the data validation engine and keeps your class namespace free from pollution, please see L for more information on specific methods and attributes. Validation::Class injects a few proxy methods into your class which are basically aliases to the corresponding prototype class methods, however it is possible to access the prototype directly using the proto/prototype methods. =head2 class $self->class; See L for full documentation. =head2 clear_queue $self->clear_queue; See L for full documentation. =head2 error_count $self->error_count; See L for full documentation. =head2 error_fields $self->error_fields; See L for full documentation. =head2 errors $self->errors; See L for full documentation. =head2 errors_to_string $self->errors_to_string; See L for full documentation. =head2 get_errors $self->get_errors; See L for full documentation. =head2 get_fields $self->get_fields; See L for full documentation. =head2 get_hash $self->get_hash; See L for full documentation. =head2 get_params $self->get_params; See L for full documentation. =head2 get_values $self->get_values; See L for full documentation. =head2 fields $self->fields; See L for full documentation. =head2 filtering $self->filtering; See L for full documentation. =head2 ignore_failure $self->ignore_failure; See L for full documentation. =head2 ignore_intervention $self->ignore_intervention; See L for full documentation. =head2 ignore_unknown $self->ignore_unknown; See L for full documentation. =head2 is_valid $self->is_valid; See L for full documentation. =head2 param $self->param; See L for full documentation. =head2 params $self->params; See L for full documentation. =head2 plugin $self->plugin; See L for full documentation. =head2 queue $self->queue; See L for full documentation. =head2 report_failure $self->report_failure; See L for full documentation. =head2 report_unknown $self->report_unknown; See L for full documentation. =head2 reset_errors $self->reset_errors; See L for full documentation. =head2 reset_fields $self->reset_fields; See L for full documentation. =head2 reset_params $self->reset_params; See L for full documentation. =head2 set_errors $self->set_errors; See L for full documentation. =head2 set_fields $self->set_fields; See L for full documentation. =head2 set_params $self->set_params; See L for full documentation. =head2 set_method $self->set_method; See L for full documentation. =head2 stash $self->stash; See L for full documentation. =head2 validate $self->validate; See L for full documentation. =head2 validate_document $self->validate_document; See L for full documentation. =head2 validate_method $self->validate_method; See L for full documentation. =head2 validate_profile $self->validate_profile; See L for full documentation. =head1 UPGRADE Validation::Class is stable, its feature-set is complete, and is currently in maintenance-only mode, i.e. Validation::Class will only be updated with minor enhancements and bug fixes. However, the lessons learned will be incorporated into a compelete rewrite uploaded under the namespace L. The Validation::Interface fork is designed to have a much simpler API with less options and better execution, focused on validating hierarchical data as its primarily objective. =head1 EXTENSIBILITY Validation::Class does NOT provide method modifiers but can be easily extended with L. =head2 before before foo => sub { ... }; See L<< Class::Method::Modifiers/before method(s) => sub { ... } >> for full documentation. =head2 around around foo => sub { ... }; See L<< Class::Method::Modifiers/around method(s) => sub { ... } >> for full documentation. =head2 after after foo => sub { ... }; See L<< Class::Method::Modifiers/after method(s) => sub { ... } >> for full documentation. =head1 SEE ALSO Validation::Class does not validate blessed objects. If you need a means for validating object types you should use a modern object system like L, L, or L. Alternatively, you could use decoupled object validators like L, L or L. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut 05-role-requirements.t100644000765000024 300114410403624 22142 0ustar00christiaanstaff000000000000Validation-Class-7.900059/tuse FindBin; use Test::More; use utf8; use strict; use warnings; { package TestClass::Test1::RoleRequirements::Role::A; use Validation::Class; set required => 'awesome'; package TestClass::Test1::RoleRequirements; use Validation::Class; eval { set role => 'TestClass::Test1::RoleRequirements::Role::A' }; package main; ok(($@ and $@ =~ /missing method/), "role requirement failure"); } { package TestClass::Test2::RoleRequirements::Role::A; use Validation::Class; set required => 'awesome'; package TestClass::Test2::RoleRequirements; use Validation::Class; set role => 'TestClass::Test2::RoleRequirements::Role::A'; sub awesome {1} package main; my $class = "TestClass::Test2::RoleRequirements"; my $self = $class->new; ok $class eq ref $self, "$class instantiated, role requirement successful"; } { package TestClass::Test3::Define; use Validation::Class; package TestClass::Test3::Consume; use Validation::Class; set role => 'TestClass::Test3::Define'; package main; my $class = "TestClass::Test3::Consume"; my $self = $class->new; ok $class eq ref $self, "$class instantiated"; ok $self->proto->can('does'), "$class prototype has does method"; ok $self->proto->does('TestClass::Test3::Define'), "$class prototype has role TestClass::Test3::Define"; ok !$self->proto->does('TestClass::Test3::Gumby'), "$class prototype does not have role TestClass::Test3::Gumby"; } done_testing; 05-foreign-directive.t100644000765000024 430514410403624 22075 0ustar00christiaanstaff000000000000Validation-Class-7.900059/tuse FindBin; use Test::More; use Data::Dumper; use utf8; use strict; use warnings; { package TestClass::A; use Validation::Class; field word => { all_caps => 1 }; directive all_caps => sub { my ($self, $field, $param) = @_; if (defined $field->{all_caps} && defined $param) { my $length = $field->{all_caps}; if ($field->{required} || $param) { unless ($param =~ /^[A-Z]+$/) { $field->errors->add("This is all wrong"); } } } return $self; }; package main; my $class = "TestClass::A"; my $self = $class->new(word => 'blah blah'); ok $class eq ref $self, "$class instantiated"; ok $self->proto->directives->has('all_caps'), "$class has foreign all_caps directives"; ok !$self->validate('word'), 'word is not in all caps'; ok $self->error_count, 'an error was registered'; } # NO SUPPORT FOR FOREIGN DIRECTIVES ATM, COMING SOON #{ # # package AllCaps; # # use base 'Validation::Class::Directive'; # # use Validation::Class::Directives; # use Validation::Class::Util; # # has 'mixin' => 1; # has 'field' => 1; # has 'multi' => 0; # has 'message' => '%s should be exactly %s characters'; # # sub validate { # # my $self = shift; # # my ($proto, $field, $param) = @_; # # if (defined $field->{all_caps} && defined $param) { # # my $length = $field->{all_caps}; # # if ($field->{required} || $param) { # # unless ($param =~ /^[A-Z]+$/) { # # $self->error(@_, $length); # # } # # } # # } # # return $self; # # } # # package TestClass::B; # # use Validation::Class; # # field word => { # all_caps => 1 # }; # # package main; # # my $class = "TestClass::B"; # my $self = $class->new(word => 'blah blah'); # # ok $class eq ref $self, "$class instantiated"; # ok $self->proto->directives->has('all_caps'), "$class has foreign all_caps directives"; # ok !$self->validate('word'), 'word is not in all caps'; # # warn $self->errors_to_string; # #} done_testing; legacy000755000765000024 014410403624 17163 5ustar00christiaanstaff000000000000Validation-Class-7.900059/t10-load-method.t100644000765000024 142114410403624 22121 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacyBEGIN { use FindBin; use lib $FindBin::Bin . "/myapp/lib"; } use utf8; use Test::More; { # github issue 20 # https://github.com/alnewkirk/Validation-Class/issues/20 # test that the Validation::Class::Field object has the desired accessors package MyApp; use Validation::Class; load classes => 1; field name => { required => 1 }; package main; my $class = "MyApp"; my $self = $class->new(name => "don johnson"); ok $class eq ref $self, "$class instantiated"; my $test = $self->class('test'); ok "MyApp::Test" eq ref $test, ref($test) . " instantiated"; # depreciated - $test = $self->class(-name => 'test'); #ok "MyApp::Test" eq ref $test, ref($test) . " instantiated"; } done_testing; 10-mixin-method.t100644000765000024 65314410403624 22314 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacyBEGIN { use FindBin; use lib $FindBin::Bin . "/myapp/lib"; } use utf8; use Test::More; { # testing the mixin method # this method is designed to .... package MyApp; use Validation::Class; fld name => { required => 1 }; package main; my $class = "MyApp"; my $self = $class->new(name => "..."); ok $class eq ref $self, "$class instantiated"; } done_testing; 10-field-method.t100644000765000024 161714410403624 22274 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacyBEGIN { use FindBin; use lib $FindBin::Bin . "/myapp/lib"; } use utf8; use Test::More; { # github issue 20 # https://github.com/alnewkirk/Validation-Class/issues/20 # test that the Validation::Class::Field object has the desired accessors package TestClass::FieldObjectTest; use Validation::Class; fld name => {required => 1}; package main; my $class = "TestClass::FieldObjectTest"; my $self = $class->new(name => "don johnson"); $self->validate; # assures we have a value in our field obj ok $class eq ref $self, "$class instantiated"; my $proto = $self->proto; my $name = $proto->fields->get('name'); ok "Validation::Class::Field" eq ref $name, "$class has field name which is a V::C::Field object"; ok $name->name, "name field has name method"; ok $name->value, "name field has value method"; } done_testing; 10-build-method.t100644000765000024 124214410403624 22302 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacyBEGIN { use FindBin; use lib $FindBin::Bin . "/myapp/lib"; } use utf8; use Test::More; { # testing the build method # this method is designed to hook into the class instantiation processs package MyApp; use Validation::Class; has number => 0; my $incrementer = sub { my ($self) = @_; $self->number($self->number + 1); }; build $incrementer; __PACKAGE__->bld($incrementer); package main; my $class = "MyApp"; my $self = $class->new(); ok $class eq ref $self, "$class instantiated"; ok 2 == $self->number, 'the number attribute has been incremented on init'; } done_testing; 98-02-document-synopsis.t100644000765000024 520414410403624 22425 0ustar00christiaanstaff000000000000Validation-Class-7.900059/tuse utf8; use strict; use warnings; use Test::More; { package T1; use Validation::Class; field 'title'; field 'rating'; field 'name'; field 'id'; document 'company' => { 'company.name' => 'name', 'company.supervisor.name' => 'name', 'company.supervisor.rating.@.*' => 'rating', 'company.tags.@' => 'name' }; package main; my $class; eval { $class = T1->new; }; ok "T1" eq ref $class, "T1 instantiated"; my $person = { "id" => "1234-ABC", "name" => "Anita Campbell-Green", "title" => "Designer", "company" => { "name" => "House of de Vil", "supervisor" => { "name" => "Cruella de Vil", "rating" => [ { "support" => -9, "guidance" => -9 } ] }, "tags" => [ "evil", "cruelty", "dogs" ] }, }; ok $class->validate_document(company => $person), "T1 document (company) validated"; } { package T2; use Validation::Class; field 'id' => { mixin => [':str'], filters => ['numeric'], max_length => 2, }; field 'name' => { mixin => [':str'], pattern => qr/^[A-Za-z ]+$/, max_length => 20, }; field 'tag' => { mixin => [':str'], pattern => qr/^(?!evil)\w+/, max_length => 20, }; document 'company' => { 'id' => 'id', 'company.name' => 'name', 'company.supervisor.name' => 'name', 'company.tags.@' => 'tag' }; package main; my $class; eval { $class = T2->new(ignore_unknown => 1); }; ok "T2" eq ref $class, "T2 instantiated"; my $person = { "id" => "1234-ABC", "name" => "Anita Campbell-Green", "title" => "Designer", "company" => { "name" => "House of de Vil", "supervisor" => { "name" => "Cruella de Vil", "rating" => [ { "support" => -9, "guidance" => -9 } ] }, "tags" => [ "evil", "cruelty", "dogs" ] }, }; ok ! $class->validate_document(company => $person), "T2 document (company) did not validate"; } done_testing; 99-ignore-intervention.tt100644000765000024 210214410403624 22667 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t#!/usr/bin/perl use utf8; use strict; use warnings; use Test::More; package T; use Validation::Class; field email => { required => 1, pattern => qr/\@localhost$/, max_length => 15 }; field login => { required => 1, min_length => 5, alias => ['user'] }; field password => { required => 1, min_length => 5, min_digits => 1, alias => ['pass'] }; package main; my $params = { user => '', pass => '', email => '', }; my $t0 = T->new(params => $params); ok !$t0->validate; is $t0->error_count, 3; for (sort $t0->get_errors) { like $_, qr/required/; } my $t1 = T->new(params => $params, ignore_intervention => 0); ok !$t1->validate; is $t1->error_count, 3; for (sort $t1->get_errors) { like $_, qr/required/; } my $t2 = T->new(params => $params, ignore_intervention => 1); ok !$t2->validate; is $t2->error_count, 7; is $t2->fields->get('email')->errors->count, 2; is $t2->fields->get('login')->errors->count, 2; is $t2->fields->get('password')->errors->count, 3; done_testing(); 10-method-method.t100644000765000024 711014410403624 22463 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacyBEGIN { use FindBin; use lib $FindBin::Bin . "/myapp/lib"; } use utf8; use Test::More; { package MyApp; use Validation::Class; fld name => { required => 1 }; mth print_name => { input => ['name'], using => sub { my ($self) = @_; return "my name is " . $self->name; } }; package main; my $class = "MyApp"; my $self = $class->new(); ok $class eq ref $self, "$class instantiated"; ok !$self->print_name, "no name printed because the name field is null"; $self->name("echo"); ok "my name is echo" eq $self->print_name, "name printed as intended"; } { package MyApp2; use Validation::Class; fld name => { required => 1 }; pro has_name => sub { shift->validate('name') }; mth print_name => { input => 'has_name', using => sub { my ($self) = @_; return "my name is " . $self->name; } }; package main; my $class = "MyApp2"; my $self = $class->new(); ok $class eq ref $self, "$class instantiated"; ok !$self->print_name, "no name printed because the name field is null"; $self->name("echo"); ok "my name is echo" eq $self->print_name, "name printed as intended"; } { package MyApp3; use Validation::Class; fld name => { required => 1 }; pro has_name => sub { shift->validate('name') }; mth print_name => { input => 'has_name', output => 'has_name', using => sub { my ($self) = @_; return "my name is " . $self->name; } }; mth die_name => { input => 'has_name', output => 'has_name', using => sub { shift->name(undef) } }; package main; my $class = "MyApp3"; my $self = $class->new(); ok $class eq ref $self, "$class instantiated"; ok !$self->print_name, "no name printed because the name field is null"; $self->name("echo"); ok "my name is echo" eq $self->print_name, "name printed as intended"; eval { $self->die_name }; ok $@, "die_name method died as expected because name could not be validated on output"; } { package MyApp4; use Validation::Class; fld name => { required => 1 }; mth print_name => { input => ['name'], output => ['name'], using => sub { my ($self) = @_; return "my name is " . $self->name; } }; mth build_name => { input => 'print_name', using => sub { shift->print_name . ", the 2nd" } }; package main; my $class = "MyApp4"; my $self = $class->new(); ok $class eq ref $self, "$class instantiated"; ok !$self->build_name, "no name printed because the name field is null"; $self->name("echo"); ok "my name is echo, the 2nd" eq $self->build_name, "name printed as intended"; } { package MyApp5; use Validation::Class; fld name => { required => 1 }; mth print_name => { input => ['name'], output => ['name'] }; sub _print_name { my ($self) = @_; return "my name is " . $self->name; } package main; my $class = "MyApp5"; my $self = $class->new(); ok $class eq ref $self, "$class instantiated"; ok !$self->print_name, "no name printed because the name field is null"; $self->name("echo"); ok "my name is echo" eq $self->print_name, "name printed as intended"; } done_testing; 01-fields-access.t100644000765000024 133114410403624 22431 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacyuse utf8; use Test::More; use Data::Dumper; use FindBin; { package TestClass::FieldsAccess; use Validation::Class; fld name => {required => 1}; package main; my $class = "TestClass::FieldsAccess"; my $self = $class->new(name => undef); my $proto = $self->proto; my $name = $proto->fields->name; ok "Validation::Class::Field" eq ref $name, "$class has field name which is a V::C::Field object"; eval { $proto->fields->something }; ok $@, "error occurred trying to execute a method named something, which doesn't exist, as expected"; ok $name->has('name'), "name field has name method"; ok $name->has('value'), "name field has value method"; } done_testing; 10-filter-method.t100644000765000024 65414410403624 22456 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacyBEGIN { use FindBin; use lib $FindBin::Bin . "/myapp/lib"; } use utf8; use Test::More; { # testing the filter method # this method is designed to .... package MyApp; use Validation::Class; fld name => { required => 1 }; package main; my $class = "MyApp"; my $self = $class->new(name => "..."); ok $class eq ref $self, "$class instantiated"; } done_testing; 90-rand-bugfixes.t100644000765000024 126514410403624 22500 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacyBEGIN { use FindBin; use lib $FindBin::Bin . "/myapp/lib"; } use utf8; use Test::More; { package TestClass::GithubIssue16; use Validation::Class; fld name => {required => 1}; package main; my $class = "TestClass::GithubIssue16"; my $self = $class->new(ignore_unknown => 1, report_unknown => 1); ok $class eq ref $self, "$class instantiated"; ok !$self->validate('+name'), 'name exists and is invalid'; ok !$self->validate('+abcd'), 'abcd does not exist and is invalid'; $self->ignore_unknown(0); $self->report_unknown(0); eval { $self->validate('+abcd') }; ok $@, 'abcd does not exist and terminates'; } done_testing; 04-attribute-assignments.t100644000765000024 165414410403624 23027 0ustar00christiaanstaff000000000000Validation-Class-7.900059/tuse FindBin; use Test::More; use utf8; use strict; use warnings; { package TestClass::AttributeAssignments; use Validation::Class; has 'awesome'; package main; my $class = "TestClass::AttributeAssignments"; my $self = $class->new; ok $class eq ref $self, "$class instantiated"; ok $self->can('awesome'), "$class has an attribute named awesome"; ok ! defined $self->awesome, "awesome attribute has yet to be defined"; ok $class eq ref $self->awesome("sweet dee"), "awesome attribute assignment was successful"; ok "sweet dee" eq $self->awesome, "awesome attribute is holding sweet dee"; $self = $class->new(awesome => "sweet dee"); ok $class eq ref $self, "$class instantiated w/attribute constructor args"; ok defined $self->awesome, "awesome attribute has yet to be defined"; ok "sweet dee" eq $self->awesome, "awesome attribute is holding sweet dee"; } done_testing; 10-profile-method.t100644000765000024 127014410403624 22644 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacyBEGIN { use FindBin; use lib $FindBin::Bin . "/myapp/lib"; } use utf8; use Test::More; use Data::Dumper; { package MyApp; use Validation::Class; fld name => { required => 1 }; pro is_name_ok => sub { return shift->validate('name') }; package main; my $class = "MyApp"; my $self = $class->new(name => 'Rob Blahblah'); ok $class eq ref $self, "$class instantiated"; ok $self->validate_profile('is_name_ok'), 'is_name_ok profile returned true'; $self->name(undef); #die Data::Dumper::Dumper($self->params); ok !$self->validate_profile('is_name_ok'), 'is_name_ok profile returned false'; } done_testing; Class000755000765000024 014410403624 21361 5ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/ValidationUtil.pm100644000765000024 1023114410403624 23011 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class# Utility Functions for Validation Classes package Validation::Class::Util; use strict; use warnings; our $VERSION = '7.900059'; # VERSION use Module::Runtime 'use_module'; use Scalar::Util 'blessed'; use Carp 'confess'; use Exporter (); our @ISA = qw(Exporter); our @EXPORT = qw( build_args build_args_collection has hold isa_arrayref isa_classref isa_coderef isa_hashref isa_listing isa_mapping isa_prototype isa_regexp prototype_registry ); sub build_args { my $self = shift; my $class = ref $self || $self; if ( scalar @_ == 1 ) { confess "The new() method for $class expects single arguments to " . "take the form of a hash reference" unless defined $_[0] && ref $_[0] eq 'HASH' ; return {%{$_[0]}}; } elsif ( @_ % 2 ) { confess "The new() method for $class expects a hash reference or a " . "key/value list. You passed an odd number of arguments" ; } else { return {@_}; } } sub build_args_collection { my $class = shift; # Validation::Class::Mapping should already be loaded return Validation::Class::Mapping->new($class->build_args(@_)); } sub has { my ( $attrs, $default ) = @_; return unless $attrs; confess "Error creating accessor, default must be a coderef or constant" if ref $default && ref $default ne 'CODE'; $attrs = [$attrs] unless ref $attrs eq 'ARRAY'; for my $attr (@$attrs) { confess "Error creating accessor '$attr', name has invalid characters" unless $attr =~ /^[a-zA-Z_]\w*$/; my $code; if ( defined $default ) { $code = sub { if ( @_ == 1 ) { return $_[0]->{$attr} if exists $_[0]->{$attr}; return $_[0]->{$attr} = ref $default eq 'CODE' ? $default->( $_[0] ) : $default; } $_[0]->{$attr} = $_[1]; $_[0]; }; } else { $code = sub { return $_[0]->{$attr} if @_ == 1; $_[0]->{$attr} = $_[1]; $_[0]; }; } no strict 'refs'; no warnings 'redefine'; my $class = caller(0); *{"$class\::$attr"} = $code; } return; } sub hold { my ( $attrs, $default ) = @_; return unless $attrs; confess "Error creating accessor, default is required and must be a coderef" if ref $default ne 'CODE'; $attrs = [$attrs] unless ref $attrs eq 'ARRAY'; for my $attr (@$attrs) { confess "Error creating accessor '$attr', name has invalid characters" unless $attr =~ /^[a-zA-Z_]\w*$/; my $code; $code = sub { if ( @_ == 1 ) { return $_[0]->{$attr} if exists $_[0]->{$attr}; return $_[0]->{$attr} = $default->( $_[0] ); } # values are read-only cannot be changed confess "Error attempting to modify the read-only attribute ($attr)"; }; no strict 'refs'; no warnings 'redefine'; my $class = caller(0); *{"$class\::$attr"} = $code; } return; } sub import { strict->import; warnings->import; __PACKAGE__->export_to_level(1, @_); return; } sub isa_arrayref { return "ARRAY" eq ref(shift) ? 1 : 0; } sub isa_classref { my ($object) = @_; return blessed(shift) ? 1 : 0; } sub isa_coderef { return "CODE" eq ref(shift) ? 1 : 0; } sub isa_hashref { return "HASH" eq ref(shift) ? 1 : 0; } sub isa_listing { return "Validation::Class::Listing" eq ref(shift) ? 1 : 0; } sub isa_mapping { return "Validation::Class::Mapping" eq ref(shift) ? 1 : 0; } sub isa_prototype { return prototype_registry->has(shift) ? 1 : 0; } sub isa_regexp { return "REGEXP" eq uc(ref(shift)) ? 1 : 0; } sub prototype_registry { # Validation::Class::Prototype should be already loaded return Validation::Class::Prototype->registry; } 1; regression000755000765000024 014410403624 21343 5ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy00-load.t100644000765000024 12014410403624 22775 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regressionuse Test::More tests => 1; # load module BEGIN { use_ok('Validation::Class') } Field.pm100644000765000024 272214410403624 23105 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class# Field Object for Validation::Class Classes # Validation::Class::Field provides functions for processing for field objects # and provides accessors for field directives. This class is derived from the # L class. package Validation::Class::Field; use strict; use warnings; use Validation::Class::Directives; use Validation::Class::Errors; use Validation::Class::Util '!has'; use Carp 'confess'; our $VERSION = '7.900059'; # VERSION use base 'Validation::Class::Mapping'; my $directives = Validation::Class::Directives->new; foreach my $directive ($directives->values) { # create accessors from default configuration (once) # ugly hack but it works so it stay .. for now if ($directive->field) { my $name = $directive->name; next if __PACKAGE__->can($name); # errors object if ($name eq 'errors') { my %spec = ($name => sub { Validation::Class::Errors->new }); Validation::Class::Util::has(%spec); } # everything else else { my %spec = ($name => sub { undef }); Validation::Class::Util::has(%spec); } } } sub new { my $class = shift; my $config = $class->build_args(@_); confess "Cannot create a new field object without a name attribute" unless $config->{name} ; my $self = bless {}, $class; $self->add($config); return $self; } 1; Mixin.pm100644000765000024 263614410403624 23152 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class# Mixin Object for Validation::Class Classes # Validation::Class::Mixin provides functions for processing for mixin objects # and provides accessors for mixin directives. This class is derived from the # L class. package Validation::Class::Mixin; use strict; use warnings; use Validation::Class::Directives; use Validation::Class::Errors; use Validation::Class::Util '!has'; use Carp 'confess'; our $VERSION = '7.900059'; # VERSION use base 'Validation::Class::Mapping'; my $directives = Validation::Class::Directives->new; foreach my $directive ($directives->values) { # create accessors from default configuration (once) if ($directive->mixin) { my $name = $directive->name; next if __PACKAGE__->can($name); # errors object if ($name eq 'errors') { my %spec = ($name => sub { Validation::Class::Errors->new }); Validation::Class::Util::has(%spec); } # everything else else { my %spec = ($name => sub { undef }); Validation::Class::Util::has(%spec); } } } sub new { my $class = shift; my $config = $class->build_args(@_); confess "Can't create a new mixin object without a name attribute" unless $config->{name} ; my $self = bless {}, $class; $self->add($config); return $self; } 1; 90-method-modifiers.t100644000765000024 253014410403624 23175 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacyBEGIN { use FindBin; use lib $FindBin::Bin . "/myapp/lib"; } use Test::More; SKIP: { eval { require 'Class/Method/Modifiers.pm' }; $@ ? plan skip_all => 'Class::Method::Modifiers is not installed.' : eval <<'CLASS'; package TestClass::Modified; use Validation::Class; use Class::Method::Modifiers; fld name => { required => 1 }; has log => 0; after validate => sub { my ($self) = @_; $self->log($self->error_count ? 1 : 0); }; mth change_log => { input => ['name'], using => sub { shift->log('thank you') } }; after change_log => sub { my ($self) = @_; $self->log($self->log eq 'thank you' ? 1 : 0); }; CLASS package main; my $class = "TestClass::Modified"; my $self = $class->new; ok $class eq ref $self, "$class instantiated"; $self->validate('name'); ok $self->log, "validate() modifier setting log attribute as expected"; $self->name('iamlegend'); $self->validate('name'); ok !$self->log, "validate() modifier setting log attribute as expected"; ok $self->change_log, "change_log() validates as expected"; ok $self->log, "change_log() modifier setting log attribute as expected"; $self->name(''); $self->change_log; ok !$self->log, "change_log() modifier setting log attribute as expected"; } done_testing; 10-prototype-method.t100644000765000024 65714410403624 23241 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacyBEGIN { use FindBin; use lib $FindBin::Bin . "/myapp/lib"; } use utf8; use Test::More; { # testing the prototype method # this method is designed to .... package MyApp; use Validation::Class; fld name => { required => 1 }; package main; my $class = "MyApp"; my $self = $class->new(name => "..."); ok $class eq ref $self, "$class instantiated"; } done_testing; 10-attribute-method.t100644000765000024 374614410403624 23221 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacyBEGIN { use FindBin; use lib $FindBin::Bin . "/myapp/lib"; } use utf8; use Test::More; { # testing the attribute method # this method is designed to add accessors to the calling class # this method can also be referred to as has() package MyApp; use Validation::Class; attribute name => 'Thomas'; attribute sex => 'M'; has age => 23; attribute type => sub { my ($self) = @_; if ($self->age > 21) { if ($self->sex eq 'M') { return 'Man'; } if ($self->sex eq 'M') { return 'Woman'; } } else { if ($self->sex eq 'M') { return 'Boy'; } if ($self->sex eq 'M') { return 'Girl'; } } }; has slang_type => sub { my ($self) = @_; if ($self->age > 21) { if ($self->sex eq 'M') { return 'Oldhead'; } if ($self->sex eq 'M') { return 'Oldjawn'; } } else { if ($self->sex eq 'M') { return 'Youngbawl'; } if ($self->sex eq 'M') { return 'Youngjawn'; } } }; __PACKAGE__->attribute(class => 'upper') ; # override the existing class method package main; my $class = "MyApp"; my $self = $class->new; ok $class eq ref $self, "$class instantiated"; ok 'Thomas' eq $self->name, 'The name attribute has the correct value'; ok 'M' eq $self->sex, 'The sex attribute has the correct value'; ok 23 eq $self->age, 'The age attribute has the correct value'; ok 'Man' eq $self->type, 'The type attribute has the correct value'; ok 'Oldhead' eq $self->slang_type, 'The slang_type attribute has the correct value'; ok 'upper' eq $self->class, 'The class attribute has the correct value'; } done_testing; 10-directive-method.t100644000765000024 217214410403624 23164 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacyBEGIN { use FindBin; use lib $FindBin::Bin . "/myapp/lib"; } use utf8; use Test::More; { # testing the directive method # this method is designed to register field directives which V::C will make # available to all classes when instantiated package MyApp1; use Validation::Class; dir is_true => sub {1}; fld name => {is_true => 1, required => 1,}; package MyApp2; use Validation::Class; directive is_true => sub {1}; field name => {is_true => 1, required => 1,}; package MyApp3; use Validation::Class; fld name => { is_true => 1, required => 1, }; package main; my ($class, $self); $class = "MyApp1"; $self = $class->new(name => "..."); ok $class eq ref $self, "$class instantiated"; $self = undef; $class = "MyApp2"; $self = $class->new(name => "..."); ok $class eq ref $self, "$class instantiated"; $self = undef; $class = "MyApp3"; eval { $self = $class->new(name => "...") }; ok $@ =~ /directive.*not supported/, "$class NOT instantiated, bad directive"; } done_testing; 10-stash.t100644000765000024 115014410403624 23225 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regressionuse Test::More tests => 7; package MyVal; use Validation::Class; package main; my $v = MyVal->new( fields => { foobar => { validation => sub { shift->stash->{foo}; } } } ); ok $v, 'class initialized'; ok $v->stash(foo => 'bar'), 'stash key foo set'; ok $v->stash('foo') eq 'bar', 'stash value bar set'; ok $v->stash({baz => 'xyz'}), 'stash key baz set'; ok $v->stash('baz') eq 'xyz', 'stash value xyz set'; ok 2 == keys %{$v->stash}, 'stash hash access and keys validated'; ok $v->validate('foobar'), 'stash accessible from custom val-routine'; Params.pm100644000765000024 257014410403624 23306 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class# Container Class for Data Input Parameters # Validation::Class::Params is a container class for input parameters and is # derived from the L class. package Validation::Class::Params; use strict; use warnings; use Validation::Class::Util '!has'; use Hash::Flatten (); use Carp 'confess'; our $VERSION = '7.900059'; # VERSION use base 'Validation::Class::Mapping'; use Validation::Class::Mapping; sub add { my $self = shift; my $arguments = $self->build_args(@_); while (my ($key, $value) = each %{$arguments}) { confess "A parameter value must be a string or an array of strings, all " . "other structures are illegal" unless ("ARRAY" eq (ref($value) || "ARRAY")) ; $self->{$key} = $value; } confess "Parameter values must be strings, arrays of strings, or hashrefs " . "whose values are any of the previously mentioned values, i.e. an " . "array with nested structures is illegal" if $self->flatten->grep(qr/(:.*:|:\d+.)/)->count ; return $self; } sub flatten { my ($self) = @_; return Validation::Class::Mapping->new( Hash::Flatten::flatten($self->hash) ); } sub unflatten { my ($self) = @_; return Validation::Class::Mapping->new( Hash::Flatten::unflatten($self->hash) ); } 1; Mixins.pm100644000765000024 155614410403624 23335 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class# Container Class for Validation::Class::Mixin Objects # Validation::Class::Mixins is a container class for L # objects and is derived from the L class. package Validation::Class::Mixins; use strict; use warnings; use Validation::Class::Util '!has'; our $VERSION = '7.900059'; # VERSION use base 'Validation::Class::Mapping'; use Validation::Class::Mixin; sub add { my $self = shift; my $arguments = $self->build_args(@_); while (my ($key, $value) = each %{$arguments}) { # do not overwrite unless (defined $self->{$key}) { $self->{$key} = $value; # accept an object as a value $self->{$key} = Validation::Class::Mixin->new($value) unless "Validation::Class::Mixin" eq ref $self->{$key} ; } } return $self; } 1; Fields.pm100644000765000024 330314410403624 23264 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class# Container Class for Validation::Class::Field Objects # Validation::Class::Fields is a container class for L # objects and is derived from the L class. package Validation::Class::Fields; use strict; use warnings; use Validation::Class::Util '!has'; use Hash::Flatten (); use Carp; our $VERSION = '7.900059'; # VERSION use base 'Validation::Class::Mapping'; use Validation::Class::Mapping; use Validation::Class::Field; sub add { my $self = shift; my $arguments = $self->build_args(@_); my @suspects = sort keys %{$arguments}; confess "Illegal field names detected, possible attempt to define validation " . "rules for a parameter containing an array of nested structures on " . "the following fields: " . join ", ", @suspects if grep /(:.*:|:\d+.)/, @suspects ; while (my ($key, $value) = each %{$arguments}) { # never overwrite unless (defined $self->{$key}) { if (isa_hashref($value)) { $value->{name} = $key; } $self->{$key} = $value; # accept an object as a value $self->{$key} = Validation::Class::Field->new($value) unless "Validation::Class::Field" eq ref $self->{$key}; # unless obj } } return $self; } sub AUTOLOAD { (my $routine = $Validation::Class::Fields::AUTOLOAD) =~ s/.*:://; my ($self) = @_; if ($routine) { if ($self->has($routine)) { return $self->get($routine); } } croak sprintf q(Can't locate object method "%s" via package "%s"), $routine, ((ref $_[0] || $_[0]) || 'main') ; } sub DESTROY {} 1; Simple.pm100644000765000024 2135314410403624 23334 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class# ABSTRACT: Simple Ad-Hoc Data Validation package Validation::Class::Simple; use 5.10.0; use strict; use warnings; use Validation::Class::Prototype; use Scalar::Util ('refaddr'); use Validation::Class::Util ('prototype_registry'); use Validation::Class (); our $VERSION = '7.900059'; # VERSION sub new { my $class = shift; $class = ref $class || $class; my $self = bless {}, $class; my $addr = refaddr $self; prototype_registry->add( $addr => Validation::Class::Prototype->new( package => $class # inside-out prototype ) ); # let Validation::Class handle arg processing $self->Validation::Class::initialize_validator(@_); return $self; } { no strict 'refs'; # inject prototype class aliases unless exist my @aliases = Validation::Class::Prototype->proxy_methods; foreach my $alias (@aliases) { *{$alias} = sub { my ($self, @args) = @_; $self->prototype->$alias(@args); }; } # inject wrapped prototype class aliases unless exist my @wrapped_aliases = Validation::Class::Prototype->proxy_methods_wrapped; foreach my $alias (@wrapped_aliases) { *{$alias} = sub { my ($self, @args) = @_; $self->prototype->$alias($self, @args); }; } } sub proto { goto &prototype } sub prototype { my $self = shift; my $addr = refaddr $self; return prototype_registry->get($addr); } sub DESTROY { my $self = shift; my $addr = refaddr $self; prototype_registry->delete($addr) if $self && prototype_registry; return; } 1; __END__ =pod =head1 NAME Validation::Class::Simple - Simple Ad-Hoc Data Validation =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $params = { name => 'Root', email => 'root@localhost', pass => 's3cret', pass2 => 's2cret' }; # define object specific rules my $rules = Validation::Class::Simple->new( # define fields on-the-fly fields => { name => { required => 1 }, email => { required => 1 }, pass => { required => 1 }, pass2 => { required => 1, matches => 'pass' }, } ); # set parameters to be validated $rules->params->add($params); # validate unless ($rules->validate) { # handle the failures warn $rules->errors_to_string; } =head1 DESCRIPTION Validation::Class::Simple is a simple validation module built around the powerful L data validation framework. This module is merely a blank canvas, a clean validation class derived from L which has not been pre-configured (e.g. configured via keywords, etc). It can be useful in an environment where you wouldn't care to create a validation class and instead would simply like to pass rules to a validation engine in an ad-hoc fashion. =head1 QUICKSTART If you are looking for a data validation module with an even lower learning curve built using the same tenets and principles as Validation::Class which is as simple and even lazier than this module, please review the documentation for L. Please review the L for a detailed step-by-step look into how Validation::Class works. =head1 RATIONALE If you are new to Validation::Class, or would like more information on the underpinnings of this library and how it views and approaches data validation, please review L. =head1 PROXY METHODS Each instance of Validation::Class::Simple is associated with a prototype class which provides the data validation engine and keeps the class namespace free from pollution and collisions, please see L for more information on specific methods and attributes. Validation::Class::Simple is injected with a few proxy methods which are basically aliases to the corresponding prototype (engine) class methods, however it is possible to access the prototype directly using the proto/prototype methods. =head2 class $self->class; See L for full documentation. =head2 clear_queue $self->clear_queue; See L for full documentation. =head2 error_count $self->error_count; See L for full documentation. =head2 error_fields $self->error_fields; See L for full documentation. =head2 errors $self->errors; See L for full documentation. =head2 errors_to_string $self->errors_to_string; See L for full documentation. =head2 get_errors $self->get_errors; See L for full documentation. =head2 get_fields $self->get_fields; See L for full documentation. =head2 get_hash $self->get_hash; See L for full documentation. =head2 get_params $self->get_params; See L for full documentation. =head2 get_values $self->get_values; See L for full documentation. =head2 fields $self->fields; See L for full documentation. =head2 filtering $self->filtering; See L for full documentation. =head2 ignore_failure $self->ignore_failure; See L for full documentation. =head2 ignore_unknown $self->ignore_unknown; See L for full documentation. =head2 is_valid $self->is_valid; See L for full documentation. =head2 param $self->param; See L for full documentation. =head2 params $self->params; See L for full documentation. =head2 plugin $self->plugin; See L for full documentation. =head2 queue $self->queue; See L for full documentation. =head2 report_failure $self->report_failure; See L for full documentation. =head2 report_unknown $self->report_unknown; See L for full documentation. =head2 reset_errors $self->reset_errors; See L for full documentation. =head2 reset_fields $self->reset_fields; See L for full documentation. =head2 reset_params $self->reset_params; See L for full documentation. =head2 set_errors $self->set_errors; See L for full documentation. =head2 set_fields $self->set_fields; See L for full documentation. =head2 set_params $self->set_params; See L for full documentation. =head2 set_method $self->set_method; See L for full documentation. =head2 stash $self->stash; See L for full documentation. =head2 validate $self->validate; See L for full documentation. =head2 validate_document $self->validate_document; See L for full documentation. =head2 validate_method $self->validate_method; See L for full documentation. =head2 validate_profile $self->validate_profile; See L for full documentation. =head1 EXTENSIBILITY Validation::Class does NOT provide method modifiers but can be easily extended with L. =head2 before before foo => sub { ... }; See L<< Class::Method::Modifiers/before method(s) => sub { ... } >> for full documentation. =head2 around around foo => sub { ... }; See L<< Class::Method::Modifiers/around method(s) => sub { ... } >> for full documentation. =head2 after after foo => sub { ... }; See L<< Class::Method::Modifiers/after method(s) => sub { ... } >> for full documentation. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Errors.pm100644000765000024 153614410403624 23340 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class# Error Handling Object for Fields and Classes # Validation::Class::Errors is responsible for error handling in # Validation::Class derived classes on both the class and field levels # respectively and is derived from the L class. package Validation::Class::Errors; use strict; use warnings; use Validation::Class::Util '!has', '!hold'; our $VERSION = '7.900059'; # VERSION use base 'Validation::Class::Listing'; sub add { my $self = shift; my $arguments = isa_arrayref($_[0]) ? $_[0] : [@_]; push @{$self}, @{$arguments}; @{$self} = ($self->unique); return $self; } sub to_string { my ($self, $delimiter, $transformer) = @_; $delimiter = ', ' unless defined $delimiter; # default is a comma-space $self->each($transformer) if $transformer; return $self->join($delimiter); } 1; 05-heirarchal-role-handling.t100644000765000024 233114410403624 23310 0ustar00christiaanstaff000000000000Validation-Class-7.900059/tuse FindBin; use Test::More; use utf8; use strict; use warnings; { package TestClass::Test1::RoleRequirements::Role::A; use Validation::Class; has 'foobar'; } { package TestClass::Test1::RoleRequirements::Role::B; use Validation::Class; has 'foobar'; has 'barbaz'; } { package TestClass::Test1::Define; use Validation::Class; set role => 'TestClass::Test1::RoleRequirements::Role::A'; set role => 'TestClass::Test1::RoleRequirements::Role::B'; package TestClass::Test1::Consume; use Validation::Class; set role => 'TestClass::Test1::Define'; package main; my $class = "TestClass::Test1::Consume"; my $self = $class->new; ok $class eq ref $self, "$class instantiated"; ok $self->proto->can('does'), "$class prototype has does method"; ok $self->proto->does('TestClass::Test1::Define'), "$class prototype has role TestClass::Test1::Define"; ok $self->proto->does('TestClass::Test1::RoleRequirements::Role::A'), "$class prototype has role TestClass::Test1::RoleRequirements::Role::A"; ok $self->proto->does('TestClass::Test1::RoleRequirements::Role::B'), "$class prototype has role TestClass::Test1::RoleRequirements::Role::B"; } done_testing; 10-initialize-method.t100644000765000024 321114410403624 23342 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacyBEGIN { use FindBin; use lib $FindBin::Bin . "/myapp/lib"; } use utf8; use Test::More; { # testing the initialize method # this method is designed to allow the Validation::Class framework to wrap # an existing class configuration, most useful with OO systems like Moose, etc package MyApp; sub new { my ($class) = @_; my $self = bless {}, $class; return $self; } use Validation::Class 'field'; field name => { required => 1 }; package main; my $class = "MyApp"; my $self = $class->new(name => "..."); ok $class eq ref $self, "$class instantiated"; eval { $self->name }; ok !$@, "$class has a name field"; eval { $self->initialize_validator }; ok !$@, "$class has initialized with no errors"; } { # testing initialization and parameter handling package MyApp::A; use Validation::Class; field numbers => { required => 1, filters => ['numeric'] }; package main; my $class = "MyApp::A"; my $self = $class->new(params => {numbers => [2, 1]}); ok "ARRAY" eq ref $self->numbers, "numbers method has an arrayref"; ok $self->numbers->[0] == 2, "numbers array #0 is correct"; ok $self->numbers->[1] == 1, "numbers array #1 is correct"; } { # testing initialization and parameter handling package MyApp::B; use Validation::Class; field numbers => { required => 1 }; package main; my $class = "MyApp::A"; my $self = $class->new(numbers => 12345); ok 12345 == $self->numbers, "numbers method has 12345 as expected"; } done_testing; Listing.pm100644000765000024 1227614410403624 23520 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class# ABSTRACT: Generic Container Class for an Array Reference package Validation::Class::Listing; use strict; use warnings; use Validation::Class::Util '!has', '!hold'; use List::MoreUtils 'uniq'; our $VERSION = '7.900059'; # VERSION sub new { my $class = shift; $class = ref $class if ref $class; my $arguments = isa_arrayref($_[0]) ? $_[0] : [@_]; my $self = bless [], $class; $self->add($arguments); return $self; } sub add { my $self = shift; my $arguments = isa_arrayref($_[0]) ? $_[0] : [@_]; push @{$self}, @{$arguments}; return $self; } sub clear { my ($self) = @_; foreach my $pair ($self->pairs) { $self->delete($pair->{index}); } return $self->new; } sub count { my ($self) = @_; return scalar($self->list); } sub delete { my ($self, $index) = @_; return delete $self->[$index]; } sub defined { my ($self, $index) = @_; return defined $self->[$index]; } sub each { my ($self, $code) = @_; $code ||= sub {}; my $i=0; foreach my $value ($self->list) { $code->($i, $value); $i++; } return $self; } sub first { my ($self) = @_; return $self->[0]; } sub get { my ($self, $index) = @_; return $self->[$index]; } sub grep { my ($self, $pattern) = @_; $pattern = qr/$pattern/ unless "REGEXP" eq uc ref $pattern; return $self->new(grep { $_ =~ $pattern } ($self->list)); } sub has { my ($self, $index) = @_; return $self->defined($index) ? 1 : 0; } sub iterator { my ($self, $function, @arguments) = @_; $function = 'list' unless grep { $function eq $_ } ('sort', 'rsort', 'nsort', 'rnsort'); my @keys = ($self->$function(@arguments)); @keys = $keys[0]->list if $keys[0] eq ref $self; my $i = 0; return sub { return unless defined $keys[$i]; return $keys[$i++]; } } sub join { my ($self, $delimiter) = @_; return join($delimiter, ($self->list)); } sub last { my ($self) = @_; return $self->[-1]; } sub list { my ($self) = @_; return (@{$self}); } sub nsort { my ($self) = @_; my $code = sub { $_[0] <=> $_[1] }; return $self->sort($code); } sub pairs { my ($self, $function, @arguments) = @_; $function ||= 'list'; my @values = ($self->$function(@arguments)); return () unless @values; @values = $values[0]->list if ref $values[0] && ref $values[0] eq ref $self; my $i=0; my @pairs = map {{ index => $i++, value => $_ }} (@values); return (@pairs); } sub rnsort { my ($self) = @_; my $code = sub { $_[1] <=> $_[0] }; return $self->sort($code); } sub rsort { my ($self) = @_; my $code = sub { $_[1] cmp $_[0] }; return $self->sort($code); } sub sort { my ($self, $code) = @_; return "CODE" eq ref $code ? sort { $a->$code($b) } ($self->keys) : sort { $a cmp $b } ($self->list); } sub unique { my ($self) = @_; return uniq ($self->list); } 1; __END__ =pod =head1 NAME Validation::Class::Listing - Generic Container Class for an Array Reference =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Listing; my $foos = Validation::Class::Listing->new; $foos->add('foo'); $foos->add('bar', 'baz'); print $foos->count; # 3 objects =head1 DESCRIPTION Validation::Class::Listing is a container class that provides general-purpose functionality for arrayref objects. =head1 METHODS =head2 new my $self = Validation::Class::Listing->new; =head2 add $self = $self->add('foo', 'bar'); =head2 clear $self = $self->clear; =head2 count my $count = $self->count; =head2 delete $value = $self->delete($index); =head2 defined $true if $self->defined($name) # defined =head2 each $self = $self->each(sub{ my ($index, $value) = @_; }); =head2 first my $value = $self->first; =head2 get my $value = $self->get($index); # i.e. $self->[$index] =head2 grep $new_list = $self->grep(qr/update_/); =head2 has $true if $self->has($name) # defined =head2 iterator my $next = $self->iterator(); # defaults to iterating by keys but accepts sort, rsort, nsort, or rnsort # e.g. $self->iterator('sort', sub{ (shift) cmp (shift) }); while (my $item = $next->()) { # do something with $item } =head2 join my $string = $self->join($delimiter); =head2 last my $value = $self->last; =head2 list my @list = $self->list; =head2 nsort my @list = $self->nsort; =head2 pairs my @pairs = $self->pairs; # or filter using $self->pairs('grep', $regexp); foreach my $pair (@pairs) { # $pair->{index} is $pair->{value}; } =head2 rnsort my @list = $self->rnsort; =head2 rsort my @list = $self->rsort; =head2 sort my @list = $self->sort(sub{...}); =head2 unique my @list = $self->unique(); =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Mapping.pm100644000765000024 1366614410403624 23506 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class# ABSTRACT: Generic Container Class for a Hash Reference package Validation::Class::Mapping; use strict; use warnings; use Validation::Class::Util '!has', '!hold'; use Hash::Merge (); our $VERSION = '7.900059'; # VERSION sub new { my $class = shift; $class = ref $class if ref $class; my $arguments = $class->build_args(@_); my $self = bless {}, $class; $self->add($arguments); return $self; } sub add { my $self = shift; my $arguments = $self->build_args(@_); while (my ($key, $value) = each %{$arguments}) { $self->{$key} = $value; } return $self; } sub clear { my ($self) = @_; $self->delete($_) for keys %{$self}; return $self; } sub count { my ($self) = @_; return scalar($self->keys); } sub delete { my ($self, $name) = @_; return delete $self->{$name}; } sub defined { my ($self, $index) = @_; return defined $self->{$index}; } sub each { my ($self, $code) = @_; $code ||= sub {}; while (my @args = each(%{$self})) { $code->(@args); } return $self; } sub exists { my ($self, $name) = @_; return exists $self->{$name} ? 1 : 0; } sub get { my ($self, $name) = @_; return $self->{$name}; } sub grep { my ($self, $pattern) = @_; $pattern = qr/$pattern/ unless "REGEXP" eq uc ref $pattern; return $self->new(map {$_=>$self->get($_)}grep{$_=~$pattern}($self->keys)); } sub has { my ($self, $name) = @_; return ($self->defined($name) || $self->exists($name)) ? 1 : 0; } sub hash { my ($self) = @_; return {$self->list}; } sub iterator { my ($self, $function, @arguments) = @_; $function = 'keys' unless grep { $function eq $_ } ('sort', 'rsort', 'nsort', 'rnsort'); my @keys = ($self->$function(@arguments)); my $i = 0; return sub { return unless defined $keys[$i]; return $self->get($keys[$i++]); } } sub keys { my ($self) = @_; return (keys(%{$self->hash})); } sub list { my ($self) = @_; return (%{$self}); } sub merge { my $self = shift; my $arguments = $self->build_args(@_); my $merger = Hash::Merge->new('LEFT_PRECEDENT'); # eval bug in Hash::Merge (v0.12 line 100) will likely never be fixed # https://rt.cpan.org/Public/Bug/Display.html?id=55978 # something is hijacking $SIG{__DIE__} eval { $self->add($merger->merge($arguments, $self->hash)) }; return $self; } sub nsort { my ($self) = @_; my $code = sub { $_[0] <=> $_[1] }; return $self->sort($code); } sub pairs { my ($self, $function, @arguments) = @_; $function ||= 'keys'; my @keys = ($self->$function(@arguments)); my @pairs = map {{ key => $_, value => $self->get($_) }} (@keys); return (@pairs); } sub rmerge { my $self = shift; my $arguments = $self->build_args(@_); my $merger = Hash::Merge->new('RIGHT_PRECEDENT'); # eval bug in Hash::Merge (v0.12 line 100) will likely never be fixed # https://rt.cpan.org/Public/Bug/Display.html?id=55978 # something is hijacking $SIG{__DIE__} eval { $self->add($merger->merge($arguments, $self->hash)) }; return $self; } sub rnsort { my ($self) = @_; my $code = sub { $_[1] <=> $_[0] }; return $self->sort($code); } sub rsort { my ($self) = @_; my $code = sub { $_[1] cmp $_[0] }; return $self->sort($code); } sub sort { my ($self, $code) = @_; return "CODE" eq ref $code ? sort { $a->$code($b) } ($self->keys) : sort { $a cmp $b } ($self->keys); } sub values { my ($self) = @_; return (values(%{$self->hash})); } 1; __END__ =pod =head1 NAME Validation::Class::Mapping - Generic Container Class for a Hash Reference =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Mapping; my $foos = Validation::Class::Mapping->new; $foos->add(foo => 'one foo'); $foos->add(bar => 'one bar'); print $foos->count; # 2 objects =head1 DESCRIPTION Validation::Class::Mapping is a container class that provides general-purpose functionality for hashref objects. =head1 METHODS =head2 new my $self = Validation::Class::Mapping->new; =head2 add $self = $self->add(foo => 1, bar => 2); =head2 clear $self = $self->clear; =head2 count my $count = $self->count; =head2 delete $value = $self->delete($name); =head2 defined $true if $self->defined($name) # defined =head2 each $self = $self->each(sub{ my ($key, $value) = @_; }); =head2 exists $true if $self->exists($name) # exists =head2 get my $value = $self->get($name); # i.e. $self->{$name} =head2 grep $new_list = $self->grep(qr/update_/); =head2 has $true if $self->has($name) # defined or exists =head2 hash my $hash = $self->hash; =head2 iterator my $next = $self->iterator(); # defaults to iterating by keys but accepts: sort, rsort, nsort, or rnsort # e.g. $self->iterator('sort', sub{ (shift) cmp (shift) }); while (my $item = $next->()) { # do something with $item (value) } =head2 keys my @keys = $self->keys; =head2 list my %hash = $self->list; =head2 merge $self->merge($hashref); =head2 nsort my @keys = $self->nsort; =head2 pairs my @pairs = $self->pairs; # or filter using $self->pairs('grep', $regexp); foreach my $pair (@pairs) { # $pair->{key} is $pair->{value}; } =head2 rmerge $self->rmerge($hashref); =head2 rnsort my @keys = $self->rnsort; =head2 rsort my @keys = $self->rsort; =head2 sort my @keys = $self->sort(sub{...}); =head2 values my @values = $self->values; =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut MyApp000755000765000024 014410403624 22105 5ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/myapp/libTest.pm100644000765000024 205114410403624 23520 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/myapp/lib/MyApppackage MyApp::Test; use Validation::Class; set { classes => [__PACKAGE__] }; # rules mixin mxn basic => { required => 1, max_length => 255, filters => [qw/trim strip/] }; # attr(s) w/rules fld id => { mixin => 'basic', max_length => 11, required => 0 }; fld name => { mixin => 'basic', min_length => 5 }; fld email => { mixin => 'basic', min_length => 3 }; fld login => { mixin => 'basic', min_length => 5 }; fld password => { mixin => 'basic', min_length => 5, min_symbols => 1 }; # just an attr has attitude => 1; # self-validating method mth create => { input => [qw/name email login password/], output => ['+id'], using => sub { my ($self, @args) = @_; # make sure to set id for output validation } }; # build method, run automatically after new() bld sub { shift->attitude(0) }; 1;99-battery.t100644000765000024 1044114410403624 23621 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regressionuse Test::More tests => 17; package MyVal; use Validation::Class; # declare validation rules mixin 'basic' => { required => 1, min_length => 1, max_length => 255, filters => ['lowercase', 'alphanumeric'] }; mixin 'validation' => {}; field 'login' => { mixin => 'basic', label => 'user login', error => 'login invalid', validation => sub { my ($self, $this, $fields) = @_; return $this->{value} eq 'admin' ? 1 : 0; } }; field 'password' => { mixin => 'basic', label => 'user password', error => 'password invalid', validation => sub { my ($self, $this, $fields) = @_; return $this->{value} eq 'pass' ? 1 : 0; } }; field 'something' => {mixin => ['basic', 'validation']}; package main; # create instance my $v = MyVal->new; ok $v, 'instance created'; # verify fields received mixins ok defined $v->fields->{login}->{required} && defined $v->fields->{login}->{min_length} && defined $v->fields->{login}->{max_length}, 'login field received mixin'; ok defined $v->fields->{password}->{required} && defined $v->fields->{password}->{min_length} && defined $v->fields->{password}->{max_length}, 'password field received mixin'; # check attributes ok $v->params, 'params attr ok'; ok $v->fields, 'fields attr ok'; # ok $v->mixins, 'mixins attr ok'; - DEPRECATED ok $v->proto->mixins, 'mixins attr ok'; # ok $v->filters, 'filters attr ok'; - DEPRECATED ok $v->proto->filters, 'filters attr ok'; # ok $v->types, 'types attr ok'; - DEPRECATED # ok $v->proto->types, 'types attr ok'; # process field with multiple mixins ok defined $v->fields->{something}->{required} && defined $v->fields->{something}->{min_length} && defined $v->fields->{something}->{max_length}, 'something field generated from multiple mixins'; # define grouped fields $v->fields->{'auth.login'} = { mixin => 'basic', label => 'user login', error => 'login invalid', validation => sub { my ($self, $this, $fields) = @_; return $this->{value} eq 'admin' ? 1 : 0; } }; $v->fields->{'auth.password'} = { mixin => 'basic', label => 'user password', error => 'password invalid', validation => sub { my ($self, $this, $fields) = @_; return $this->{value} eq 'pass' ? 1 : 0; } }; $v->fields->{'user.name'} = { mixin => 'basic', label => 'user name', error => 'invalid name', validation => sub { my ($self, $this, $fields) = @_; return 1; } }; $v->fields->{'user.phone'} = { mixin => 'basic', label => 'user phone', error => 'phone invalid', validation => sub { my ($self, $this, $fields) = @_; return 0; } }; $v->fields->{'user.email'} = { mixin => 'basic', label => 'user email', error => 'email invalid', validation => sub { my ($self, $this, $fields) = @_; return 1; } }; package main; my $params = { login => 'admin1%^&%&^%^%&', password => 'pass@@@#$#%$^', name => 'al newkirk', phone => '2155551212', email => 'awncorp2cpan.org' }; $v = MyVal->new(params => $params, fields => $v->fields->hash); # params set at new function ok scalar(keys %{$v->params}), 'params have been set at instantiation'; # error class exists ok !$v->error_count, 'error count reporting'; # validate login only ok !$v->validate({login => 'auth.login'}), 'login field failed as expected'; ok $v->error_count == 1, 'error count accurate'; ok $v->errors_to_string eq 'login invalid', 'error messages and error class to_string method works'; # check formatting ok $v->params->{login} eq 'admin1', 'login formatting worked'; ok $v->params->{password} eq 'pass', 'password formatting worked'; # process common password confirmation $v->fields->{'password_cfm'} = { mixin_field => 'password', default => 'pass', validation => sub { my ($self, $this, $params) = @_; return $this->{value} eq $params->{password} ? 1 : 0; } }; $v = MyVal->new(params => $v->params->hash, fields => $v->fields->hash); ok $v->validate('password'), 'password field validates'; ok $v->validate('password', 'password_cfm'), 'password confirmation validates'; 18-cloning.t100644000765000024 301014410403624 23541 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regressionuse Test::More tests => 15; package MyVal; use Validation::Class; field email => {required => 1, min_length => 1, max_length => 255}; package main; my $v = MyVal->new( params => { email => 1, email1 => 1, email2 => 1, email3 => 1 } ); ok $v, 'initialization successful'; # $v->clone_field - DEPRECATED $v->proto->clone_field('email', 'email3', {label => 'Third Email', required => 0}); $v->proto->clone_field('email', 'email2'); $v->proto->clone_field('email', 'email1'); ok $v->fields->{email1}->{required}, 'email1 cloned of email, has req'; ok 1 == $v->fields->{email1}->{min_length}, 'email1 cloned of email, has min'; ok 255 == $v->fields->{email1}->{max_length}, 'email1 cloned of email, has max'; ok !$v->fields->{email1}->{label}, 'email1 cloned of email, no label'; ok $v->fields->{email2}->{required}, 'email2 cloned of email, has req'; ok 1 == $v->fields->{email2}->{min_length}, 'email2 cloned of email, has min'; ok 255 == $v->fields->{email2}->{max_length}, 'email2 cloned of email, has max'; ok !$v->fields->{email2}->{label}, 'email2 cloned of email, no label'; ok !$v->fields->{email3}->{required}, 'email3 cloned of email, has no req'; ok 1 == $v->fields->{email3}->{min_length}, 'email3 cloned of email, has min'; ok 255 == $v->fields->{email3}->{max_length}, 'email3 cloned of email, has max'; ok $v->fields->{email3}->{label}, 'email3 cloned of email, has label'; ok $v->validate(qr/email(\d+)?/), 'validation passed'; ok $v->error_count == 0, 'validation ok'; 98-anomaly.t100644000765000024 126514410403624 23572 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regressionuse Test::More tests => 2; package MyVal; use Validation::Class; package main; my $params = {_dc => '0123456789'}; my $v = MyVal->new( fields => { status => { required => 1, error => 'Invalid account status. Use Active/Inactive.', filters => ['trim', 'strip', 'alpha'], options => 'Active, Inactive' } }, params => {_dc => '0123456789'}, ignore_unknown => 1 ); # params set at new function ok $v->validate(keys %{$params}), 'validation ok'; # ok $v->fields->{_dc}, 'found anomaly, param converted to field'; ok !$v->fields->{_dc}, 'anomaly fixed, unknown param no longer converted to field'; Exporter.pm100644000765000024 724614410403624 23700 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class# ABSTRACT: Simple Exporter for Validation::Class Classes package Validation::Class::Exporter; use 5.008001; use strict; use warnings; our $VERSION = '7.900059'; # VERSION sub apply_spec { my ($this, %args) = @_; no strict 'refs'; no warnings 'once'; no warnings 'redefine'; my $parent = caller(0); my @keywords = @{$args{keywords}} if $args{keywords}; my @routines = @{$args{routines}} if $args{routines}; my $settings = {@{$args{settings}}} if $args{settings}; *{"$parent\::import"} = sub { my $child = caller(0); *{"$child\::$_"} = *{"$parent\::$_"} for @{$args{keywords}}; *{"$child\::$_"} = *{"$parent\::$_"} for @{$args{routines}}; my $ISA = "$child\::ISA"; push @$ISA, 'Validation::Class' unless grep { $_ eq 'Validation::Class' } @$ISA; *{"$child\::$_"} = *{"Validation\::Class\::$_"} for @Validation::Class::EXPORT; strict->import; warnings->import; $child->load({@{$args{settings}}}) if $args{settings}; return $child; }; return $this; } 1; __END__ =pod =head1 NAME Validation::Class::Exporter - Simple Exporter for Validation::Class Classes =head1 VERSION version 7.900059 =head1 SYNOPSIS package MyApp::Validator; use Validation::Class; use Validation::Class::Exporter; my @settings = ( classes => [ MyApp::Validator::DomainAlpha MyApp::Validator::DomainBeta ] ); Validation::Class::Exporter->apply_spec( routines => ['thing'], # export additional routines as is settings => [@settings] # passed to the `load` keyword in V::C ); sub thing { my $args = pop; my $class = shift || caller; # routine as a keyword # ... do some thing }; ... in your application class: package MyApp; use MyApp::Validator; thing ['a', 'b']; ... in your application: package main; my $app = MyApp->new; =head1 DESCRIPTION This module (while experimental) encapsulates the exporting of keywords and routines. It applies the L framework along with any keyword routines and/or sub-routines specified with the apply_spec() method. It does this by simply by copying the spec into the calling class. To simplify writing exporter modules, C also imports C and C into your exporter module, as well as into modules that use it. =head1 METHODS =head2 apply_spec When you call this method, C builds a custom C method on the calling class. The C method will export the functions you specify, and can also automatically export C making the calling class a Validation::Class derived class. This method accepts the following parameters: =over 8 =item * routines => [ ... ] This list of function I will be exported into the calling class exactly as is, the functions can be used traditionally or as keywords so their parameter handling should be configured accordingly. =item * settings => [ ... ] This list of key/value pair will be passed to the load method imported from C and will be applied on the calling class. This approach affords you some trickery in that you can utilize the load method to apply the current class' configuration to the calling class' configuration, etc. =back =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut 98-03-document-example-nested.t100644000765000024 430214410403624 23450 0ustar00christiaanstaff000000000000Validation-Class-7.900059/tuse utf8; use strict; use warnings; use Test::More; { package T; use Validation::Class; field 'state' => { state => 1 }; field 'string' => { mixin => ':str' }; document 'location' => { 'id' => 'string', 'type' => 'string', 'name' => 'string', 'company' => 'string', 'address1' => 'string', 'address2' => 'string', 'city' => 'string', 'state' => 'state', 'zip' => 'string' }; document 'user' => { 'id' => 'string', 'type' => 'string', 'name' => 'string', 'company' => 'string', 'login' => 'string', 'email' => 'string', 'locations.@' => 'location' }; package main; my $class; eval { $class = T->new; }; ok "T" eq ref $class, "T instantiated"; my $documents = $class->prototype->documents; ok "Validation::Class::Mapping" eq ref $documents, "T documents hash registered as setting"; ok 2 == keys %{$documents}, "T has 1 registered document"; my $user = $documents->{user}; ok 7 == keys %{$user}, "T user document has 3 mappings"; can_ok $class, 'validate_document'; my $data = { "id" => 1234, "type" => "Master", "name" => "Root", "company" => "System, LLC", "login" => "root", "email" => "root\@localhost", "locations" => [ { "id" => 9876, "type" => "Node", "name" => "DevBox", "company" => "System, LLC", "address1" => "123 Street Road", "address2" => "Suite 2", "city" => "SINCITY", "state" => "NO", "zip" => "00000" } ] }; ok ! $class->validate_document(user => $data), "T document (user) not valid"; ok $class->errors_to_string =~ /locations\.0\.state/, "T proper error message set"; $class->prototype->documents->{location}->{state} = 'string'; ok $class->validate_document(user => $data), "T document (user) validated"; } done_testing; 98-02-document-synopsis-adhoc.t100644000765000024 255314410403624 23505 0ustar00christiaanstaff000000000000Validation-Class-7.900059/tuse utf8; use strict; use warnings; use Test::More; package T; use Validation::Class; package main; my $data = { "id" => "1234-ABC", "name" => "Anita Campbell-Green", "title" => "Designer", "company" => { "name" => "House of de Vil", "supervisor" => { "name" => "Cruella de Vil", "rating" => [ { "support" => -9, "guidance" => -9 } ] }, "tags" => [ "evil", "cruelty", "dogs" ] }, }; my $schema = { 'id' => { mixin => [':num'], max_length => 4 }, 'name' => { mixin => [':str'], min_length => 2 }, 'title' => { mixin => [':str'], min_length => 5 }, 'company.name' => { mixin => [':str'], min_length => 2 }, 'company.tags.@' => { mixin => [':str'], min_length => 2 }, 'company.super*.name' => { mixin => [':str'], min_length => 2 }, 'company.super*.rating.@.*' => { mixin => [':str'], }, }; my $class; eval { $class = T->new }; ok "T" eq ref $class, "T instantiated"; can_ok $class, 'validate_document'; ok $class->validate_document($schema => $data), "T (ad-hoc data) validated"; ok $data->{id} !~ /\D/, "document ID has been filtered"; done_testing; 99-objects-not-sharing-params.t100644000765000024 76614410403624 23635 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t#!/usr/bin/perl use utf8; use strict; use warnings; use Test::More; plan skip_all => 'TODO: Fix bug' if ! $ENV{'DEVELOPMENT_TESTS'}; package MyApp::Person; use Validation::Class; field 'name'; package main; my $person1 = MyApp::Person->new(params => { name => 'foo' }); my $person2 = MyApp::Person->new(params => { name => 'bar' }); diag $person1->params->get('name'); diag $person2->params->get('name'); ok $person1->name ne $person2->name, 'parameter values are different'; done_testing(); 15-toggling.t100644000765000024 144014410403624 23724 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regressionuse Test::More tests => 7; package MyVal; use Validation::Class; field name => {required => 1}; field email => {required => 1}; field phone => {required => 1}; field address => {required => 1}; field company => {}; field fax => {}; field country => { validation => sub {0} }; package main; my $v = MyVal->new(params => {}); ok $v, 'initialization successful'; ok $v->validate('country'), 'country validation passed, not required'; ok !$v->validate('+country'), 'country validation failed, requirement toggled'; ok $v->validate('country'), 'country validation passed, not required'; ok !$v->validate('name'), 'name validation failed, required'; ok $v->validate('-name'), 'name validation passed, requirement toggled'; ok !$v->validate('name'), 'name validation failed, required'; Cookbook.pod100644000765000024 6462614410403624 24031 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class# PODNAME: Validation::Class::Cookbook # ABSTRACT: Recipes for Validation::Class # VERSION __END__ =pod =head1 NAME Validation::Class::Cookbook - Recipes for Validation::Class =head1 VERSION version 7.900059 =head1 GUIDED TOUR The instructions contained in this documentation are also relevant for configuring any class derived from L. The validation logic that follows is not specific to a particular use-case. =head2 Parameter Handling There are three ways to declare parameters you wish to have validated. The first and most common approach is to supply the target parameters to the validation class constructor: use Validation::Class::Simple; my $rules = Validation::Class::Simple->new(params => $params); All input parameters are wrapped by the L container which provides generic functionality for managing hashes. Additionally you can declare parameters by using the params object directly: use Validation::Class::Simple; my $rules = Validation::Class::Simple->new; $rules->params->clear; $rules->params->add(user => 'admin', pass => 's3cret'); printf "%s parameters were submitted", $rules->params->count; Finally, any parameter which has corresponding validation rules that has been declared in a validation class derived from L will have an accessor which can be used directly or as an argument to the constructor: package MyApp::Person; use Validation::Class; field 'name' => { required => 1 }; package main; my $rules = MyApp::Person->new(name => 'Egon Spangler'); $rules->name('Egon Spengler'); =head2 Validation Rules Validation::Class comes with a complete standard set of validation rules which allows you to easily describe the constraints and operations that need to be performed per parameter. Validation rules are referred to as I, fields are named after the parameters they expect to be matched against. A field is also a hashref whose keys are called directives which correspond with the names of classes in the directives namespace, and whose values are arguments which control how directives carry-out their operations. use Validation::Class::Simple; my $rules = Validation::Class::Simple->new; $rules->fields->clear; $rules->fields->add(name => { required => 1, max_length => 255 }); Fields can be specified as an argument to the class constructor, or managed directly using the L container. Every field is wrapped by the L container which provides accessors for all core directives. Directives can be found under the directives namespace, e.g. the required directive refers to L. Please see L for a list of all core directives. =head2 Flow Control A good data validation tool is not simply checking input against constraints, its also providing a means to easily handle different and often complex data input scenarios. The queue method allows you to designate and defer fields to be validated. It also allows you to set fields that must be validated regardless of what has been passed to the validate method. Additionally it allows you to conditionally specify constraints: use Validation::Class::Simple; my $rules = Validation::Class::Simple->new; $rules->queue('name'); # always validate the name parameter $rules->queue('email', 'email2') if $rules->param('change_email'); $rules->queue('login', 'login2') if $rules->param('change_login'); # validate name # validate email and email confirmation if change_email is true # validate login and login confirmation if change_login is true $rules->validate('password'); # additionally, validate password $rules->clear_queue; # reset the queue when finished Akin to the queue method is the stash method. At-times it is necessary to break out of the box in order to design constraints that fit your particular use-case. The stash method allows you to share arbitrary objects with routines used by validation classes. use Validation::Class::Simple; my $rules = Validation::Class::Simple->new; $rules->fields->add( email => { # email validation relies on a stashed object validation => sub { my ($self, $field, $params) = @_; return 0 if ! my $dbo = $self->stash('dbo'); return 0 if ! $dbo->email_exists($field->value); return 1; } } ); # elsewhere in the program $rules->stash(dbo => $database_object); # stash the database object =head2 Error Handling When validation fails, and it will, you need to be able to report what failed and why. L give you complete control over error handling and messages. Errors can exist at the field-level and class-level (errors not specific to a particular field). All errors are wrapped in a L container. use Validation::Class::Simple; my $rules = Validation::Class::Simple->new; # print a comma separated list of class and field errors print $rules->errors_to_string unless $rules->validate; # print a newline separated list of class and field errors print $rules->errors_to_string("\n") unless $rules->validate; # print a comma separated list of class and upper-cased field errors print $rules->errors_to_string(undef, sub{ ucfirst lc shift }) # print total number of errors at the class and field levels print "Found %s errors", $rules->error_count; # return a hashref of fields with errors my $errors = $rules->error_fields; # get errors for specific fields only my @errors = $rules->get_errors('email', 'login'); =head2 Input Filtering Filtering data is one fringe benefits of a good data validation framework. The process is also known as scrubbing or sanitizing data. The process ensures that the data being passed to the business logic will be clean and consistent. Filtering data is not as simple and straight-forward as it may seem which is why it is necessary to think-through your applications interactions before implementation. Filtering is the process of applying transformations to the incoming data. The problem with filtering is that it permanently alters the data input and in the event of a failure could report inconsistent error messages: use Validation::Class::Simple; my $rules = Validation::Class::Simple->new; $rules->fields->add( # even if the input is submitted as lowercase it will fail # the filter is run as a pre-process by default username => { filters => ['uppercase'], validation => sub { return 0 if $_[1]->value =~ /[A-Z]/; return 1; } } ); When designing a system to filter data, it is always necessary to differentiate pre-processing filters from post-processing filters. L provides a filtering directive which designates certain fields to run filters in post-processing: $rules->fields->add( # if the input is submitted as lowercase it will pass username => { filters => ['uppercase'], filtering => 'post', validation => sub { return 0 if $_[1]->value =~ /[A-Z]/; return 1; } } ); =head2 Handling Failures A data validation framework exists to handle failures, it is its main function and purpose, in-fact, the difference between a validation framework and a type-constraint system is how it responds to errors. When a type-constraint system finds an error it raises an exception. Exception handling is the process of responding to the occurrence, during computation, of exceptions (anomalous or exceptional situations). Typically the errors reported when an exception is raised includes a dump of the program's state up until the point of the exception which is apropos as exceptions are unexpected. A data validation framework can also be thought-of as a type system but one that is specifically designed to expect input errors and report user-friendly error messages. L may encounter exceptions as programmers defined validation rules which remain mutable. L provides attributes for determining how the validation engine reacts to exceptions and validation failures: use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( ignore_failure => 1, # do not throw errors if validation fails ignore_unknown => 0, # throw errors if unknown directives are found report_failure => 0, # register errors if "method validations" fail report_unknown => 0, # register errors if "unknown directives" are found ); =head2 Data Validation Once your fields are defined and you have your parameter rules configured as desired you will like use the validate method to perform all required operations. The validation operations occur in the following order: normalization (resetting fields, clearing existing errors, etc) pre-processing (applying filters, etc) validation (processing directives, etc) post-processing (applying filters, etc) What gets validated is determined by the state and arguments passed to the validate method. The validate method determines what to validate in the following order: checks the validation queue for fields checks arguments for regular expression objects and adds matching fields validates fields with matching parameters if no fields are specified validates all fields if no parameters are specified It is also important to under what it means to declare a field as being required. A field is a data validation rule matching a specific parameter, A required field simply means that if-and-when a parameter is submitted, it is required to have a value. It does not mean that a field is always required to be validated. Occasionally you may need to temporarily set a field as required or not-required for a specific validation operation. This requirement is referred to as the toggle function. The toggle function is enacted by prefixing a field name with a plus or minus sign (+|-) when passed to the validate method: use Validation::Class::Simple; my $rules = Validation::Class::Simple->new(fields => {...}); # meaning, email is always required to have a value # however password and password2 can be submitted as empty strings # but if password and password2 have values they will be validated $rules->validate('+email', '-password', '-password2'); Here are a few examples and explanations of using the validate method: use Validation::Class::Simple; my $rules = Validation::Class::Simple->new(fields => {...}); unless ($rules->validate) { # validate all fields with matching parameters } unless ($rules->validate) { # validate all fields because no parameters were submitted } unless ($rules->validate(qr/^email/)) { # validate all fields whose name being with email # e.g. email, email2, email_update } unless ($rules->validate('login', 'password')) { # validate the login and password specifically # regardless of what parameters have been set } unless ($rules->validate({ user => 'login', pass => 'password' })) { # map user and pass parameters to the appropriate fields as aliases # and validate login and password fields using the aliases } =head1 BUILDING CLASSES This recipe displays the usage of keywords to configure a validation class. =head2 Problem You want to know how to use the L keywords to define a validation class. =head2 Solution Use the keywords exported by L to register validation rules, templates, profiles, methods and filters. =head2 Discussion Your validation class can be thought of as your data-model/input-firewall. The benefits this approach provides might require you to change your perspective on parameter handling and workflow. Typically when designing an application we tend to name parameters arbitrarily and validate the same data at various stages during a program's execution in various places in the application stack. This approach is inefficient and prone to bugs and security problems. To get the most out of Validation::Class you should consider each parameter hitting your application (individually) as a transmission fitting a very specific criteria, yes, like a field in a data model. Your validation rules will act as filters which will reject or accept and format the transmission for use within your application, yes, almost exactly like a firewall. A validation class is defined as follows: package MyApp::Person; use Validation::Class; # a validation rule template mixin 'basic' => { required => 1, min_length => 1, max_length => 255, filters => ['lowercase', 'alphanumeric'] }; # a validation rule field 'login' => { mixin => 'basic', label => 'user login', error => 'login invalid', validation => sub { my ($self, $field, $params) = @_; return $field->value eq 'admin' ? 1 : 0; } }; # a validation rule field 'password' => { mixin => 'basic', label => 'user password', error => 'password invalid', validation => sub { my ($self, $field, $params) = @_; return $field->value eq 'pass' ? 1 : 0; } }; # a validation profile profile 'registration' => sub { my ($self, @args) = @_; return $self->validate(qw(login password)); }; # an auto-validating method method 'registers' => { input => 'registration', using => sub { my ($self, @args) = shift; # ... do something } }; 1; The fields defined will be used to validate the specified input parameters. You specify the input parameters at/after instantiation, parameters should take the form of a hashref of key/value pairs passed to the params attribute, or attribute/value pairs. The following is an example on using your validate class to validate input in various scenarios: # web app package MyApp; use MyApp::User; use Misc::WebAppFramework; get '/auth' => sub { # get user input parameters my $params = shift; # initialize validation class and set input parameters my $user = MyApp::User->new(params => $params); unless ($user->registers) { # print errors to browser unless validation is successful return $user->errors_to_string; } return 'you have authenticated'; }; A field can have aliases, parameter names that if detected will be mapped to the parameter name matching the field definition. Multiple fields cannot have the same alias defined, such a configuration would result in a runtime error. use MyApp::User; my $user = MyApp::User->new(params => $params); unless ($user->validate) { return $input->errors_to_string; } package MyApp::User; field 'email' => { ..., alias => [ 'emails', 'email_address', 'email_addresses' ] }; package main; use MyApp::User; my $user = MyApp::User->new(params => { email_address => '...' }); unless ($user->validate('email'){ return $user->errors_to_string; } # valid because email_address is an alias on the email field =head1 INTEGRATING CLASSES AND FRAMEWORKS This recipe displays methods of configuring your validation class to cooperate with your pre-existing classes and object-system. =head2 Problem You want to know how to configure L to cooperate with pre-existing classes or object systems like L, L, L, and L. =head2 Solution Use a combination of techniques such as excluding keywords exported by L and utilizing the initialize_validator method. =head2 Discussion L will atuomatically inject a method name `initialize_validator` if a pre-existing `new` method is dicovered which allows you to execute certain validation class normalization routines. When, the initialize_validator method is called is not important, it is only important that it is called before your object is used as a validation class object. A validation class using Moose as an object system could be configured as follows: package MyApp::Person; use Moose; use Validation::Class qw(fld mxn); # the order in which these frameworks are used is important # loading Moose first ensures that the Moose::Object constructor # has precedence sub BUILD { my ($self, $params) = @_; $self->initialize_validator($params); } mxn 'basic' => { required => 1, min_length => 1, max_length => 255, filters => ['lowercase', 'alphanumeric'] }; fld 'login' => { mixin => 'basic', label => 'user login', error => 'login invalid' }; fld 'password' => { mixin => 'basic', label => 'user password', error => 'password invalid' }; has 'profile' => ( is => 'rw', isa => 'MyApp::Person::Profile' ); 1; =head1 FILTERING DATA This recipe describes how to define filtering in your validation class rules. =head2 Problem You want to know how to define filters to sanatize and transform your data although some transformations may need to occur after a successful validation. =head2 Solution Data validation rules can be configured to apply filtering as both pre-and-post processing operations. =head2 Discussion Validation::Class supports pre/post filtering but is configured to pre-filter incoming data by default. This means that based upon the filtering options supplied within the individual fields, filtering will happen before validation (technically at instantiation and again just before validation). As expected, this is configurable via the filtering attribute. A WORD OF CAUTION: Validation::Class is configured to pre-filter incoming data which boosts application security and is best used with passive filtering (e.g. converting character case - filtering which only alters the input in predictable ways), versus aggressive filtering (e.g. formatting a telephone number) which completely and permanently changes the incoming data ... so much so that if the validation still fails ... errors that are reported may not match the data that was submitted. If you're sure you'd rather employ aggressive filtering, I suggest setting the filtering attribute to 'post' for post-filtering or setting it to null and applying the filters manually by calling the apply_filters() method. =head1 DELEGATING VALIDATION This recipe describes how to separate validation logic between multiple related classes. =head2 Problem You want to know how to define multiple validation classes and pass input data and input parameters between them. =head2 Solution Use classes as validation domains, as a space to logically group related validation rules, then use built-in methods to have multiple validation classes validate in-concert. =head2 Discussion For larger applications where a single validation class might become cluttered and inefficient, Validation::Class comes equipped to help you separate your validation rules into separate classes. The idea is that you'll end up with a main validation class (most likely empty) that will simply serve as your point of entry into your relative (child) classes. The following is an example of this: package MyApp::User; use Validation::Class; field name => { ... }; field email => { ... }; field login => { ... }; field password => { ... }; package MyApp::Profile; use Validation::Class; field age => { ... }; field sex => { ... }; field birthday => { ... }; package MyApp; use Validation::Class; set classes => 1; package main; my $input = MyApp->new(params => $params); my $user = $input->class('user'); my $profile = $input->class('profile'); 1; =head1 INTROSPECT AND EXTEND This recipe describes how to peek under the curtain and leverage the framework for other purposes. =head2 Problem You want to know how to use your data validation classes to perform other tasks programmatically (e.g. generate documentation, etc). =head2 Solution By using the prototype class associated with your validation class you can introspect it's configuration and perform additional tasks programmatically. =head2 Discussion Most users will never venture beyond the public API, but powerful abilities await the more adventureous developer and this section was written specifically for you. To assist you on along your journey, let me explain exactly what happens when you define and instantiate a validation class. Classes are defined using keywords (field, mixin, filter, etc) which register rule definitions on a cached class profile (of-sorts) associated with the class which is being constructed. On instantiation, the cached class profile is cloned then merged with any arguments provided to the constructor, this means that even in a persistent environment the original class profile is never altered. To begin introspection, simply look into the attributes attached to the class prototype, e.g. fields, mixins, filters, etc., the following examples will give you an idea of how to use introspection to extend your application code using Validation::Class. Please keep in mind that Validation::Class is likely to already have most of the functionalty you would need to introspect your codebase. The following is an introspection design template that will work in most cases: package MyApp::Introspect; use Validation::Class; load classes => 'MyApp'; # load MyApp and all child classes sub per_class { my ($self, $code) = @_; my %relatives = %{$self->proto->settings->{relatives}}; while (my($parent, $children) = each(%relatives)) { while (my($nickname, $namespace) = each(%{$children})) { # do something with each class $code->($namespace); } } } sub per_field_per_class { my ($self, $code) = @_; $self->per_class(sub{ my $namespace = shift; my $class = $namespace->new; foreach my $field ($class->fields->values) { # do something with each field in each class $code->($class, $class->fields->{$field}); } }); } =head1 CLIENT-SIDE VALIDATION This recipe describes how to generate JSON objects which can be used to validate user input in the web-browser (client-side). =head2 Problem You want to know how to make the most out of your data validation rules by making your configuration available as JSON objects in the browser. =head2 Solution Using introspection, you can leverage the prototype class associated with your validation class to generate JSON objects based on your validation class configuration. =head2 Discussion In the context of a web-application, it is often best to perform the initial input validation on the client (web-browser) before submitting data to the server for further validation and processing. In the following code we will generate javascript objects that match our Validation::Class data models which we will then use with some js library to validate form data, etc. ... example validation class package MyApp::Model; use Validation::Class; use Validation::Class::Plugin::JavascriptObjects; mxn scrub => { filters => ['trim', 'strip'] }; fld login => { mixin => 'scrub' email => 1, required => 1, alias => 'user', }; fld password => { mixin => 'scrub', required => 1, alias => 'pass', min_length => 5, min_symbols => 1, min_alpha => 1, min_digits => 1 }; ... in your webapp controller get '/js/model' => sub { my $model = MyApp::Model->new; # generate the JS object my $data = $model->plugin('javascript_objects')->render( namespace => 'validate.model', fields => [qw/email password/], include => [qw/required email minlength maxlength/] ) return print $data; }; The output of the /js/model route should generate a javascript object which looks similar to the following: var validate = { "model" : { "email" : { "minlength" : 3, "required" : 1, "maxlength" : 255 }, "password" : { "minlength" : 5, "required" : 1, "maxlength" : 255 } } }; If its not obvious yet, we can now easily use this generated javascript API with jQuery (or other client-side library) to validate form data, etc. AUTH REQUIRED
[% input.errors_to_string %]

Halt, who goes there?






=head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Directive.pm100644000765000024 1005114410403624 24012 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class# ABSTRACT: Base Class for Validation Class Directives package Validation::Class::Directive; use strict; use warnings; use Validation::Class::Util; use Carp 'confess'; our $VERSION = '7.900059'; # VERSION # defaults has 'mixin' => 0; has 'field' => 0; has 'multi' => 0; has 'message' => '%s could not be validated'; has 'validator' => sub { sub{1} }; has 'dependencies' => sub {{ normalization => [], validation => [] }}; has 'name' => sub { my ($self) = @_; my $name = ref $self || $self; my $regexp = qr/Validation::Class::Directive::(.*)$/; $name = $1 if $name =~ $regexp; $name =~ s/([a-z])([A-Z])/$1_$2/g; $name =~ s/\W/_/g; $name = lc $name; return $name; }; sub new { my $class = shift; my $arguments = $class->build_args(@_); confess "Error creating directive without a name, specifying a name is " . "required to instatiate a new non-subclass directive" if 'Validation::Class::Directive' eq $class && ! $arguments->{name} ; my $self = bless {}, $class; while (my($key, $value) = each %{$arguments}) { $self->$key($value); } return $self; } sub error { my ($self, $proto, $field, $param, @tokens) = @_; my $name = $field->label || $field->name; unshift @tokens, $name; # use custom field-level error message if ($field->error) { $field->errors->add($field->error); } # use field-level error message override elsif (defined $field->{messages} && $field->{messages}->{$self->name}) { my $message = $field->{messages}->{$self->name}; $field->errors->add(sprintf($message, @tokens)); } # use class-level error message override elsif ($proto->messages->has($self->name)) { my $message = $proto->messages->get($self->name); $field->errors->add(sprintf($message, @tokens)); } # use directive error message else { $field->errors->add(sprintf($self->message, @tokens)); } return $self; } sub validate { my $self = shift; my ($proto, $field, $param) = @_; my $context = $proto->stash->{'validation.context'}; # nasty hack, we need a better way !!! $self->validator->($context, $field, $proto->params); return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive - Base Class for Validation Class Directives =head1 VERSION version 7.900059 =head1 SYNOPSIS package Validation::Class::Directive::CheckBlacklist; use base 'Validation::Class::Directive'; use strict; use warnings; use Validation::Class::Util; use File::Slurp; has 'mixin' => 0; has 'field' => 1; has 'multi' => 0; has 'message' => '%s has been blacklisted'; sub validate { my $self = shift; my ($proto, $field, $param) = @_; if (defined $field->{check_blacklist} && $param) { # is the parameter value blacklisted? my @blacklist = read_file('/blacklist.txt'); $self->error if grep { $param =~ /^$_$/ } @blacklist; } } 1; ... in your validation class: package MyApp::Person; use Validation::Class; field ip_address => { required => 1, check_blacklist => 1 }; 1; ... in your application: package main; use MyApp::Person; my $person = MyApp::Person->new(ip_address => '0.0.0.0'); unless ($person->validates('ip_address')) { # handle validation error } =head1 DESCRIPTION You can extend Validation::Class by creating your own validation rules (directives). Validation::Class::Directive provides a base-class for you to use when creating new directive classes. Please see L for a complete list of core directives. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Prototype.pm100644000765000024 22237214410403624 24134 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class# ABSTRACT: Data Validation Engine for Validation::Class Classes package Validation::Class::Prototype; use 5.10.0; use strict; use warnings; use Validation::Class::Configuration; use Validation::Class::Directives; use Validation::Class::Listing; use Validation::Class::Mapping; use Validation::Class::Params; use Validation::Class::Fields; use Validation::Class::Errors; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION use List::MoreUtils 'uniq', 'firstval'; use Hash::Flatten 'flatten', 'unflatten'; use Module::Runtime 'use_module'; use Module::Find 'findallmod'; use Scalar::Util 'weaken'; use Hash::Merge 'merge'; use Carp 'confess'; use Clone 'clone'; my $_registry = Validation::Class::Mapping->new; # prototype registry hold 'attributes' => sub { Validation::Class::Mapping->new }; hold 'builders' => sub { Validation::Class::Listing->new }; hold 'configuration' => sub { Validation::Class::Configuration->new }; hold 'directives' => sub { Validation::Class::Mapping->new }; hold 'documents' => sub { Validation::Class::Mapping->new }; hold 'errors' => sub { Validation::Class::Errors->new }; hold 'events' => sub { Validation::Class::Mapping->new }; hold 'fields' => sub { Validation::Class::Fields->new }; has 'filtering' => 'pre'; hold 'filters' => sub { Validation::Class::Mapping->new }; has 'ignore_failure' => '1'; has 'ignore_intervention' => '0'; has 'ignore_unknown' => '0'; hold 'messages' => sub { Validation::Class::Mapping->new }; hold 'methods' => sub { Validation::Class::Mapping->new }; hold 'mixins' => sub { Validation::Class::Mixins->new }; hold 'package' => sub { undef }; hold 'params' => sub { Validation::Class::Params->new }; hold 'profiles' => sub { Validation::Class::Mapping->new }; hold 'queued' => sub { Validation::Class::Listing->new }; has 'report_failure' => 0; has 'report_unknown' => 0; hold 'settings' => sub { Validation::Class::Mapping->new }; has 'validated' => 0; has 'stashed' => sub { Validation::Class::Mapping->new }; Hash::Merge::specify_behavior( { 'SCALAR' => { 'SCALAR' => sub { $_[1] }, 'ARRAY' => sub { [$_[0], @{$_[1]}] }, 'HASH' => sub { $_[1] }, }, 'ARRAY' => { 'SCALAR' => sub { [@{$_[0]}, $_[1]] }, 'ARRAY' => sub { [@{$_[0]}, @{$_[1]}] }, 'HASH' => sub { [@{$_[0]}, $_[1]] }, }, 'HASH' => { 'SCALAR' => sub { $_[1] }, 'ARRAY' => sub { $_[1] }, 'HASH' => sub { Hash::Merge::_merge_hashes($_[0], $_[1]) }, }, }, # based on RIGHT_PRECEDENT, STORAGE_PRECEDENT and RETAINMENT_PRECEDENT # ... this is intended to DWIM in the context of role-settings-merging 'ROLE_PRECEDENT' ); sub new { my $class = shift; my $arguments = $class->build_args(@_); confess "The $class class must be instantiated with a parameter named package ". "whose value is the name of the associated package" unless defined $arguments->{package} && $arguments->{package} =~ /\w/ ; my $self = bless $arguments, $class; $_registry->add($arguments->{package}, $self); return $self; } sub apply_filter { my ($self, $filter, $field) = @_; my $name = $field; $field = $self->fields->get($field); $filter = $self->filters->get($filter); return unless $field && $filter; if ($self->params->has($name)) { if (isa_coderef($filter)) { if (my $value = $self->params->get($name)) { if (isa_arrayref($value)) { foreach my $el (@{$value}) { $el = $filter->($el); } } else { $value = $filter->($value); } $self->params->add($name, $value); } } } return $self; } sub apply_filters { my ($self, $state) = @_; $state ||= 'pre'; # state defaults to (pre) filtering # check for and process input filters and default values my $run_filter = sub { my ($name, $spec) = @_; if ($spec->filtering) { if ($spec->filtering eq $state) { # the filters directive should always be an arrayref $spec->filters([$spec->filters]) unless isa_arrayref($spec->filters); # apply filters $self->apply_filter($_, $name) for @{$spec->filters}; } } }; $self->fields->each($run_filter); return $self; } sub apply_mixin { my ($self, $field, $mixin) = @_; return unless $field && $mixin; $field = $self->fields->get($field); $mixin ||= $field->mixin; return unless $mixin && $field; # mixin values should be in arrayref form my $mixins = isa_arrayref($mixin) ? $mixin : [$mixin]; foreach my $name (@{$mixins}) { my $mixin = $self->mixins->get($name); next unless $mixin; $self->merge_mixin($field->name, $mixin->name); } return $self; } sub apply_mixin_field { my ($self, $field_a, $field_b) = @_; return unless $field_a && $field_b; $self->check_field($field_a); $self->check_field($field_b); # some overwriting restricted my $fields = $self->fields; $field_a = $fields->get($field_a); $field_b = $fields->get($field_b); return unless $field_a && $field_b; my $name = $field_b->name if $field_b->has('name'); my $label = $field_b->label if $field_b->has('label'); # merge $self->merge_field($field_a->name, $field_b->name); # restore $field_b->name($name) if defined $name; $field_b->label($label) if defined $label; $self->apply_mixin($name, $field_a->mixin) if $field_a->can('mixin'); return $self; } sub apply_validator { my ( $self, $field_name, $field ) = @_; # does field have a label, if not use field name (e.g. for errors, etc) my $name = $field->{label} ? $field->{label} : $field_name; my $value = $field->{value} ; # check if required my $req = $field->{required} ? 1 : 0; if (defined $field->{'toggle'}) { $req = 1 if $field->{'toggle'} eq '+'; $req = 0 if $field->{'toggle'} eq '-'; } if ( $req && ( !defined $value || $value eq '' ) ) { my $error = defined $field->{error} ? $field->{error} : "$name is required"; $field->errors->add($error); return $self; # if required and fails, stop processing immediately } if ( $req || $value ) { # find and process all the validators foreach my $key (keys %{$field}) { my $directive = $self->directives->{$key}; if ($directive) { if ($directive->{validator}) { if ("CODE" eq ref $directive->{validator}) { # execute validator directives $directive->{validator}->( $field->{$key}, $value, $field, $self ); } } } } } return $self; } sub check_field { my ($self, $name) = @_; my $directives = $self->directives; my $field = $self->fields->get($name); foreach my $key ($field->keys) { my $directive = $directives->get($key); unless (defined $directive) { $self->pitch_error( sprintf "The %s directive supplied by the %s field is not supported", $key, $name ); } } return 1; } sub check_mixin { my ($self, $name) = @_; my $directives = $self->directives; my $mixin = $self->mixins->get($name); foreach my $key ($mixin->keys) { my $directive = $directives->get($key); unless (defined $directive) { $self->pitch_error( sprintf "The %s directive supplied by the %s mixin is not supported", $key, $name ); } } return 1; } sub class { my $self = shift; my ($name, %args) = @_; return unless $name; my @strings; @strings = split /\//, $name; @strings = map { s/[^a-zA-Z0-9]+([a-zA-Z0-9])/\U$1/g; $_ } @strings; @strings = map { /\w/ ? ucfirst $_ : () } @strings; my $class = join '::', $self->{package}, @strings; return unless $class; my @attrs = qw( ignore_failure ignore_intervention ignore_unknown report_failure report_unknown ); # to be copied (stash and params copied later) my %defaults = ( map { $_ => $self->$_ } @attrs ); $defaults{'stash'} = $self->stashed; # copy stash $defaults{'params'} = $self->get_params; # copy params my %settings = %{ merge \%args, \%defaults }; use_module $class; for (keys %settings) { delete $settings{$_} unless $class->can($_); } return unless $class->can('new'); return unless $self->registry->has($class); # isa validation class my $child = $class->new(%settings); { my $proto_method = $child->can('proto') ? 'proto' : $child->can('prototype') ? 'prototype' : undef ; if ($proto_method) { my $proto = $child->$proto_method; if (defined $settings{'params'}) { foreach my $key ($proto->params->keys) { if ($key =~ /^$name\.(.*)/) { if ($proto->fields->has($1)) { push @{$proto->fields->{$1}->{alias}}, $key; } } } } } } return $child; } sub clear_queue { my $self = shift; my @names = $self->queued->list; for (my $i = 0; $i < @names; $i++) { $names[$i] =~ s/^[\-\+]{1}//; $_[$i] = $self->params->get($names[$i]); } $self->queued->clear; return @_; } sub clone_field { my ($self, $field, $new_field, $directives) = @_; $directives ||= {}; $directives->{name} = $new_field unless $directives->{name}; # build a new field from an existing one during runtime $self->fields->add( $new_field => Validation::Class::Field->new($directives) ); $self->apply_mixin_field($new_field, $field); return $self; } sub does { my ($self, $role) = @_; my $roles = $self->settings->get('roles'); return $roles ? (firstval { $_ eq $role } @{$roles}) ? 1 : 0 : 0; } sub error_count { my ($self) = @_; my $i = $self->errors->count; $i += $_->errors->count for $self->fields->values; return $i; } sub error_fields { my ($self, @fields) = @_; my $failed = {}; @fields = $self->fields->keys unless @fields; foreach my $name (@fields) { my $field = $self->fields->{$name}; if ($field->{errors}->count) { $failed->{$name} = [$field->{errors}->list]; } } return $failed; } sub errors_to_string { my $self = shift; # combine class and field errors my $errors = Validation::Class::Errors->new([]); $errors->add($self->errors->list); $errors->add($_->errors->list) for ($self->fields->values); return $errors->to_string(@_); } sub flatten_params { my ($self, $hash) = @_; if ($hash) { $hash = Hash::Flatten::flatten($hash); $self->params->add($hash); } return $self->params->flatten->hash || {}; } sub get_errors { my ($self, @criteria) = @_; my $errors = Validation::Class::Errors->new([]); # combined errors if (!@criteria) { $errors->add($self->errors->list); $errors->add($_->errors->list) for ($self->fields->values); } elsif (isa_regexp($criteria[0])) { my $query = $criteria[0]; $errors->add($self->errors->grep($query)->list); $errors->add($_->errors->grep($query)->list) for $self->fields->values; } else { $errors->add($_->errors->list) for map {$self->fields->get($_)} @criteria; } return ($errors->list); } sub get_fields { my ($self, @fields) = @_; return () unless @fields; return (map { $self->fields->get($_) || undef } @fields); } sub get_hash { my ($self) = @_; return { map { $_ => $self->get_values($_) } $self->fields->keys }; } sub get_params { my ($self, @params) = @_; my $params = $self->params->hash || {}; if (@params) { return @params ? (map { defined $params->{$_} ? $params->{$_} : undef } @params) : () ; } else { return $params; } } sub get_values { my ($self, @fields) = @_; return () unless @fields; return ( map { my $field = $self->fields->get($_); my $param = $self->params->get($_); $field->readonly ? $field->default || undef : $field->value || $param ; } @fields ); } sub is_valid { my ($self) = @_; return $self->error_count ? 0 : 1; } sub merge_field { my ($self, $field_a, $field_b) = @_; return unless $field_a && $field_b; my $directives = $self->directives; $field_a = $self->fields->get($field_a); $field_b = $self->fields->get($field_b); return unless $field_a && $field_b; # keep in mind that in this case we're using field_b as a mixin foreach my $pair ($field_b->pairs) { my ($key, $value) = @{$pair}{'key', 'value'}; # skip unless the directive is mixin compatible next unless $directives->get($key)->mixin; # do not override existing keys but multi values append if ($field_a->has($key)) { next unless $directives->get($key)->multi; } if ($directives->get($key)->field) { # can the directive have multiple values, merge array if ($directives->get($key)->multi) { # if field has existing array value, merge unique if (isa_arrayref($field_a->{$key})) { my @values = isa_arrayref($value) ? @{$value} : ($value); push @values, @{$field_a->{$key}}; @values = uniq @values; $field_a->{$key} = [@values]; } # simple copy else { $field_a->{$key} = isa_arrayref($value) ? $value : [$value]; } } # simple copy else { $field_a->{$key} = $value; } } } return $self; } sub merge_mixin { my ($self, $field, $mixin) = @_; return unless $field && $mixin; my $directives = $self->directives; $field = $self->fields->get($field); $mixin = $self->mixins->get($mixin); foreach my $pair ($mixin->pairs) { my ($key, $value) = @{$pair}{'key', 'value'}; # do not override existing keys but multi values append if ($field->has($key)) { next unless $directives->get($key)->multi; } if ($directives->get($key)->field) { # can the directive have multiple values, merge array if ($directives->get($key)->multi) { # if field has existing array value, merge unique if (isa_arrayref($field->{$key})) { my @values = isa_arrayref($value) ? @{$value} : ($value); push @values, @{$field->{$key}}; @values = uniq @values; $field->{$key} = [@values]; } # merge copy else { my @values = isa_arrayref($value) ? @{$value} : ($value); push @values, $field->{$key} if $field->{$key}; @values = uniq @values; $field->{$key} = [@values]; } } # simple copy else { $field->{$key} = $value; } } } return $field; } sub normalize { my ($self, $context) = @_; # we need context confess "Context object ($self->{package} class instance) required ". "to perform validation" unless $self->{package} eq ref $context ; # stash the current context object $self->stash->{'normalization.context'} = $context; # resets $self->validated(0); $self->reset_fields; # validate mixin directives foreach my $key ($self->mixins->keys) { $self->check_mixin($key); } # check for and process a mixin directive foreach my $key ($self->fields->keys) { my $field = $self->fields->get($key); next unless $field; $self->apply_mixin($key, $field->{mixin}) if $field->can('mixin') && $field->{mixin}; } # check for and process a mixin_field directive foreach my $key ($self->fields->keys) { my $field = $self->fields->get($key); next unless $field; $self->apply_mixin_field($key, $field->{mixin_field}) if $field->can('mixin_field') && $field->{mixin_field} ; } # execute normalization events foreach my $key ($self->fields->keys) { $self->trigger_event('on_normalize', $key); } # alias checking, ... for duplicate aliases, etc my $mapper = {}; my @fields = $self->fields->keys; foreach my $name (@fields) { my $field = $self->fields->get($name); my $label = $field->{label} ? $field->{label} : "The field $name"; if (defined $field->{alias}) { my $aliases = "ARRAY" eq ref $field->{alias} ? $field->{alias} : [$field->{alias}]; foreach my $alias (@{$aliases}) { if ($mapper->{$alias}) { my $alt_field = $self->fields->get($mapper->{$alias}) ; my $alt_label = $alt_field->{label} ? $alt_field->{label} : "the field $mapper->{$alias}" ; my $error = qq($label contains the alias $alias which is also an alias on $alt_label) ; $self->throw_error($error); } if ($self->fields->has($alias)) { my $error = qq($label contains the alias $alias which is the name of an existing field) ; $self->throw_error($error); } $mapper->{$alias} = $name; } } } # final checkpoint, validate field directives foreach my $key ($self->fields->keys) { $self->check_field($key); } # delete the stashed context object delete $self->stash->{'normalization.context'}; return $self; } sub param { my ($self, $name, $value) = @_; if (defined $value) { $self->params->add($name, $value); return $value; } else { return unless $self->params->has($name); return $self->params->get($name); } } sub pitch_error { my ($self, $error_message) = @_; $error_message =~ s/\n/ /g; $error_message =~ s/\s+/ /g; if ($self->ignore_unknown) { if ($self->report_unknown) { $self->errors->add($error_message); } } else { $self->throw_error($error_message); } return $self; } sub plugin { my ($self, $name) = @_; return unless $name; # transform what looks like a shortname my @strings; @strings = split /\//, $name; @strings = map { s/[^a-zA-Z0-9]+([a-zA-Z0-9])/\U$1/g; $_ } @strings; @strings = map { /\w/ ? ucfirst $_ : () } @strings; my $class = join '::', 'Validation::Class::Plugin', @strings; eval { use_module $class }; return $class->new($self); } sub proxy_methods { return qw{ class clear_queue error error_count error_fields errors errors_to_string get_errors get_fields get_hash get_params get_values fields filtering ignore_failure ignore_intervention ignore_unknown is_valid param params plugin queue report_failure report_unknown reset_errors reset_fields reset_params set_errors set_fields set_params stash } } sub proxy_methods_wrapped { return qw{ validate validates validate_document document_validates validate_method method_validates validate_profile profile_validates } } sub queue { my $self = shift; push @{$self->queued}, @_; return $self; } sub register_attribute { my ($self, $attribute, $default) = @_; my $settings; no strict 'refs'; no warnings 'redefine'; confess "Error creating accessor '$attribute', name has invalid characters" unless $attribute =~ /^[a-zA-Z_]\w*$/; confess "Error creating accessor, default must be a coderef or constant" if ref $default && ref $default ne 'CODE'; $default = ($settings = $default)->{default} if isa_hashref($default); my $check; my $code; if ($settings) { if (defined $settings->{isa}) { $settings->{isa} = 'rw' unless defined $settings->{isa} and $settings->{isa} eq 'ro' ; } } if (defined $default) { $code = sub { if (@_ == 1) { return $_[0]->{$attribute} if exists $_[0]->{$attribute}; return $_[0]->{$attribute} = ref $default eq 'CODE' ? $default->($_[0]) : $default; } $_[0]->{$attribute} = $_[1]; $_[0]; }; } else { $code = sub { return $_[0]->{$attribute} if @_ == 1; $_[0]->{$attribute} = $_[1]; $_[0]; }; } $self->set_method($attribute, $code); $self->configuration->attributes->add($attribute, $code); return $self; } sub register_builder { my ($self, $code) = @_; $self->configuration->builders->add($code); return $self; } sub register_directive { my ($self, $name, $code) = @_; my $directive = Validation::Class::Directive->new( name => $name, validator => $code ); $self->configuration->directives->add($name, $directive); return $self; } sub register_document { my ($self, $name, $data) = @_; $self->configuration->documents->add($name, $data); return $self; } sub register_ensure { my ($self, $name, $data) = @_; my $package = $self->{package}; my $code = $package->can($name); confess "Error creating pre/post condition(s) ". "around method $name on $package: method does not exist" unless $code ; $data->{using} = $code; $data->{overwrite} = 1; $self->register_method($name, $data); return $self; } sub register_field { my ($self, $name, $data) = @_; my $package = $self->package; my $merge = 0; $merge = 2 if $name =~ s/^\+{2}//; $merge = 1 if $name =~ s/^\+{1}//; confess "Error creating field $name, name is not properly formatted" unless $name =~ /^(?:[a-zA-Z_](?:[\w\.]*\w|\w*)(?:\:\d+)?)$/; if ($merge) { if ($self->configuration->fields->has($name) && $merge == 2) { $self->configuration->fields->get($name)->merge($data); return $self; } if ($self->configuration->fields->has($name) && $merge == 1) { $self->configuration->fields->delete($name); $self->configuration->fields->add($name, $data); return $self; } } confess "Error creating accessor $name on $package: attribute collision" if $self->fields->has($name); confess "Error creating accessor $name on $package: method collision" if $package->can($name); $data->{name} = $name; $self->configuration->fields->add($name, $data); my $method_name = $name; $method_name =~ s/\W/_/g; my $method_routine = sub { my $self = shift @_; my $proto = $self->proto; my $field = $proto->fields->get($name); if (@_ == 1) { $proto->params->add($name, $_[0]); $field->value($_[0]); } return $proto->params->get($name); }; $self->set_method($method_name, $method_routine); return $self; } sub register_filter { my ($self, $name, $code) = @_; $self->configuration->filters->add($name, $code); return $self; } sub register_message { my ($self, $name, $template) = @_; $self->messages->add($name, $template); return $self; } sub register_method { my ($self, $name, $data) = @_; my $package = $self->package; unless ($data->{overwrite}) { confess "Error creating method $name on $package: ". "collides with attribute $name" if $self->attributes->has($name) ; confess "Error creating method $name on $package: ". "collides with method $name" if $package->can($name) ; } my @output_keys = my @input_keys = qw( input input_document input_profile input_method ); s/input/output/ for @output_keys; confess "Error creating method $name, requires " . "at-least one pre or post-condition option, e.g., " . join ', or ', map { "'$_'" } sort @input_keys, @output_keys unless grep { $data->{$_} } @input_keys, @output_keys ; $data->{using} ||= $package->can("_$name"); $data->{using} ||= $package->can("_process_$name"); confess "Error creating method $name, requires the " . "'using' option and a coderef or subroutine which conforms ". "to the naming conventions suggested in the documentation" unless "CODE" eq ref $data->{using} ; $self->configuration->methods->add($name, $data); # create method no strict 'refs'; my $method_routine = sub { my $self = shift; my @args = @_; my $i_validator; my $o_validator; my $input_type = firstval { defined $data->{$_} } @input_keys; my $output_type = firstval { defined $data->{$_} } @output_keys; my $input = $input_type ? $data->{$input_type} : ''; my $output = $output_type ? $data->{$output_type} : ''; my $using = $data->{'using'}; my $return = undef; if ($input and $input_type eq 'input') { if (isa_arrayref($input)) { $i_validator = sub {$self->validate(@{$input})}; } elsif ($self->proto->profiles->get($input)) { $i_validator = sub {$self->validate_profile($input, @args)}; } elsif ($self->proto->methods->get($input)) { $i_validator = sub {$self->validate_method($input, @args)}; } else { confess "Method $name has an invalid input specification"; } } elsif ($input) { my $type = $input_type; $type =~ s/input_//; my $type_list = "${type}s"; my $type_validator = "validate_${type}"; if ($type && $type_list && $self->proto->$type_list->get($input)) { $i_validator = sub {$self->$type_validator($input, @args)}; } else { confess "Method $name has an invalid input specification"; } } if ($output and $output_type eq 'output') { if (isa_arrayref($output)) { $o_validator = sub {$self->validate(@{$output})}; } elsif ($self->proto->profiles->get($output)) { $o_validator = sub {$self->validate_profile($output, @args)}; } elsif ($self->proto->methods->get($output)) { $o_validator = sub {$self->validate_method($output, @args)}; } else { confess "Method $name has an invalid output specification"; } } elsif ($output) { my $type = $output_type; $type =~ s/output_//; my $type_list = "${type}s"; my $type_validator = "validate_${type}"; if ($type && $type_list && $self->proto->$type_list->get($output)) { $o_validator = sub {$self->$type_validator($output, @args)}; } else { confess "Method $name has an invalid output specification"; } } if ($using) { if (isa_coderef($using)) { my $error = "Method $name failed to validate"; # execute input validation if ($input) { unless ($i_validator->(@args)) { confess $error. " input, ". $self->errors_to_string if !$self->ignore_failure; unshift @{$self->errors}, $error if $self->report_failure; return $return; } } # execute routine $return = $using->($self, @args); # execute output validation if ($output) { confess $error. " output, ". $self->errors_to_string unless $o_validator->(@args); } # return return $return; } else { confess "Error executing $name, invalid coderef specification"; } } return $return; }; $self->set_method($name, $method_routine); return $self; }; sub register_mixin { my ($self, $name, $data) = @_; my $mixins = $self->configuration->mixins; my $merge = 0; $merge = 2 if $name =~ s/^\+{2}//; $merge = 1 if $name =~ s/^\+{1}//; $data->{name} = $name; if ($mixins->has($name) && $merge == 2) { $mixins->get($name)->merge($data); return $self; } if ($mixins->has($name) && $merge == 1) { $mixins->delete($name); $mixins->add($name, $data); return $self; } $mixins->add($name, $data); return $self; } sub register_profile { my ($self, $name, $code) = @_; $self->configuration->profiles->add($name, $code); return $self; } sub register_settings { my ($self, $data) = @_; my @keys; my $name = $self->package; # grab configuration settings, not instance settings my $settings = $self->configuration->settings; # attach classes @keys = qw(class classes); if (my $alias = firstval { exists $data->{$_} } @keys) { $alias = $data->{$alias}; my @parents; if ($alias eq 1 && !ref $alias) { push @parents, $name; } else { push @parents, isa_arrayref($alias) ? @{$alias} : $alias; } foreach my $parent (@parents) { my $relatives = $settings->{relatives}->{$parent} ||= {}; # load class children and create relationship map (hash) foreach my $child (findallmod $parent) { my $name = $child; $name =~ s/^$parent\:://; $relatives->{$name} = $child; } } } # attach requirements @keys = qw(requires required requirement requirements); if (my $alias = firstval { exists $data->{$_} } @keys) { $alias = $data->{$alias}; my @requirements; push @requirements, isa_arrayref($alias) ? @{$alias} : $alias; foreach my $requirement (@requirements) { $settings->{requirements}->{$requirement} = 1; } } # attach roles @keys = qw(base role roles bases); if (my $alias = firstval { exists $data->{$_} } @keys) { $alias = $data->{$alias}; my @roles; if ($alias) { push @roles, isa_arrayref($alias) ? @{$alias} : $alias; } if (@roles) { no strict 'refs'; foreach my $role (@roles) { eval { use_module $role }; # is the role a validation class? unless ($self->registry->has($role)) { confess sprintf "Can't apply the role %s to the " . "class %s unless the role uses Validation::Class", $role, $self->package ; } my $role_proto = $self->registry->get($role);; # check requirements my $requirements = $role_proto->configuration->settings->{requirements}; ; if (defined $requirements) { my @failures; foreach my $requirement (keys %{$requirements}) { unless ($self->package->can($requirement)) { push @failures, $requirement; } } if (@failures) { confess sprintf "Can't use the class %s as a role for ". "use with the class %s while missing method(s): %s", $role, $self->package, join ', ', @failures ; } } push @{$settings->{roles}}, $role; my @routines = grep { defined &{"$role\::$_"} } keys %{"$role\::"}; if (@routines) { # copy methods foreach my $routine (@routines) { eval { $self->set_method($routine, $role->can($routine)); } unless $self->package->can($routine); } # merge configurations my $self_profile = $self->configuration->profile; my $role_profile = clone $role_proto->configuration->profile; # manually merge profiles with list/map containers foreach my $attr ($self_profile->keys) { my $lst = 'Validation::Class::Listing'; my $map = 'Validation::Class::Mapping'; my $sp_attr = $self_profile->{$attr}; my $rp_attr = $role_profile->{$attr}; if (ref($rp_attr) and $rp_attr->isa($map)) { $sp_attr->merge($rp_attr->hash); } elsif (ref($rp_attr) and $rp_attr->isa($lst)) { $sp_attr->add($rp_attr->list); } else { # merge via spec-based merging for standard types Hash::Merge::set_behavior('ROLE_PRECEDENT'); $sp_attr = merge $sp_attr => $rp_attr; Hash::Merge::set_behavior('LEFT_PRECEDENT'); } } } } } } return $self; } sub registry { return $_registry; } sub reset { my $self = shift; $self->queued->clear; $self->reset_fields; $self->reset_params; return $self; } sub reset_errors { my $self = shift; $self->errors->clear; foreach my $field ($self->fields->values) { $field->errors->clear; } return $self; } sub reset_fields { my $self = shift; foreach my $field ( $self->fields->values ) { # set default, special directives, etc $field->{name} = $field->name; $field->{value} = ''; } $self->reset_errors(); return $self; } sub reset_params { my $self = shift; my $params = $self->build_args(@_); $self->params->clear; $self->params->add($params); return $self; } sub set_errors { my ($self, @errors) = @_; $self->errors->add(@errors) if @errors; return $self->errors->count; } sub set_fields { my $self = shift; my $fields = $self->build_args(@_); $self->fields->add($fields); return $self; } sub set_method { my ($self, $name, $code) = @_; # proto and prototype methods cannot be overridden confess "Error creating method $name, method already exists" if ($name eq 'proto' || $name eq 'prototype') && $self->package->can($name) ; # place routines on the calling class no strict 'refs'; no warnings 'redefine'; return *{join('::', $self->package, $name)} = $code; } sub set_params { my $self = shift; $self->params->add(@_); return $self; } sub set_values { my $self = shift; my $values = $self->build_args(@_); while (my($name, $value) = each(%{$values})) { my $param = $self->params->get($name); my $field = $self->fields->get($name); next if $field->{readonly}; $value ||= $field->{default}; $self->params->add($name => $value); $field->value($value); } return $self; } sub snapshot { my ($self) = @_; # reset the stash $self->stashed->clear; # clone configuration settings and merge into the prototype # ... which makes the prototype kind've a snapshot of the configuration if (my $config = $self->configuration->configure_profile) { my @clonable_configuration_settings = qw( attributes directives documents events fields filters methods mixins profiles settings ); foreach my $name (@clonable_configuration_settings) { my $settings = $config->$name->hash; $self->$name->clear->merge($settings); } $self->builders->add($config->builders->list); } return $self; } sub stash { my $self = shift; return $self->stashed->get($_[0]) if @_ == 1 && ! ref $_[0]; $self->stashed->add($_[0]->hash) if @_ == 1 && isa_mapping($_[0]); $self->stashed->add($_[0]) if @_ == 1 && isa_hashref($_[0]); $self->stashed->add(@_) if @_ > 1; return $self->stashed; } sub throw_error { my $error_message = pop; $error_message =~ s/\n/ /g; $error_message =~ s/\s+/ /g; confess $error_message ; } sub trigger_event { my ($self, $event, $field) = @_; return unless $event; return unless $field; my @order; my $directives; my $process_all = $event eq 'on_normalize' ? 1 : 0; my $event_type = $event eq 'on_normalize' ? 'normalization' : 'validation'; $event = $self->events->get($event); $field = $self->fields->get($field); return unless defined $event; return unless defined $field; # order events via dependency resolution $directives = Validation::Class::Directives->new( {map{$_=>$self->directives->get($_)}(sort keys %{$event})} ); @order = ($directives->resolve_dependencies($event_type)); @order = keys(%{$event}) unless @order; # execute events foreach my $i (@order) { # skip if the field doesn't have the subscribing directive unless ($process_all) { next unless exists $field->{$i}; } my $routine = $event->{$i}; my $directive = $directives->get($i); # something else might fudge with the params so we wait # until now to collect its value my $name = $field->name; my $param = $self->params->has($name) ? $self->params->get($name) : undef; # execute the directive routine associated with the event $routine->($directive, $self, $field, $param); } return $self; } sub unflatten_params { my ($self) = @_; return $self->params->unflatten->hash || {}; } sub has_valid { goto &validate } sub validates { goto &validate } sub validate { my ($self, $context, @fields) = @_; confess "Context object ($self->{package} class instance) required ". "to perform validation" unless $self->{package} eq ref $context ; # normalize/sanitize $self->normalize($context); # create alias map manually if requested # ... extremely-deprecated but it remains for back-compat and nostalgia !!! my $alias_map; if (isa_hashref($fields[0])) { $alias_map = $fields[0]; @fields = (); # blank while (my($name, $alias) = each(%{$alias_map})) { $self->params->add($alias => $self->params->delete($name)); push @fields, $alias; } } # include queued fields if (@{$self->queued}) { push @fields, @{$self->queued}; } # include fields from field patterns @fields = map { isa_regexp($_) ? (grep { $_ } ($self->fields->sort)) : ($_) } @fields; # process toggled fields foreach my $field (@fields) { my ($switch) = $field =~ /^([+-])./; if ($switch) { # set field toggle directive $field =~ s/^[+-]//; if (my $field = $self->fields->get($field)) { $field->toggle(1) if $switch eq '+'; $field->toggle(0) if $switch eq '-'; } } } # determine what to validate and how if (@fields && $self->params->count) { # validate all parameters against only the fields explicitly # requested to be validated } elsif (!@fields && $self->params->count) { # validate all parameters against all defined fields because no fields # were explicitly requested to be validated, e.g. not explicitly # defining fields to be validated effectively allows the parameters # submitted to dictate what gets validated (may not be dangerous) @fields = ($self->params->keys); } elsif (@fields && !$self->params->count) { # validate fields specified although no parameters were submitted # will likely pass validation unless fields exist with a *required* # directive or other validation logic expecting a value } else { # validate all defined fields although no parameters were submitted # will likely pass validation unless fields exist with a *required* # directive or other validation logic expecting a value @fields = ($self->fields->keys); } # establish the bypass validation flag $self->stash->{'validation.bypass_event'} = 0; # stash the current context object $self->stash->{'validation.context'} = $context; # report fields requested that do not exist and are not aliases for my $f (grep {!$self->fields->has($_)} uniq @fields) { next if grep { if ($_->has('alias')) { my @aliases = isa_arrayref($_->get('alias')) ? @{$_->get('alias')} : ($_->get('alias')) ; grep { $f eq $_ } @aliases; } } $self->fields->values ; $self->pitch_error("Data validation field $f does not exist"); } # stash fields targeted for validation $self->stash->{'validation.fields'} = [grep {$self->fields->has($_)} uniq @fields] ; # execute on_before_validation events $self->trigger_event('on_before_validation', $_) for @{$self->stash->{'validation.fields'}} ; # execute on_validate events unless ($self->stash->{'validation.bypass_event'}) { $self->trigger_event('on_validate', $_) for @{$self->stash->{'validation.fields'}} ; $self->validated(1); $self->validated(2) if $self->is_valid; } # execute on_after_validation events $self->trigger_event('on_after_validation', $_) for @{$self->stash->{'validation.fields'}} ; # re-establish the bypass validation flag $self->stash->{'validation.bypass_event'} = 0; # restore params from alias map manually if requested # ... extremely-deprecated but it remains for back-compat and nostalgia !!! if ( defined $alias_map ) { while (my($name, $alias) = each(%{$alias_map})) { $self->params->add($name => $self->params->delete($alias)); } } return $self->validated == 2 ? 1 : 0; } sub document_validates { goto &validate_document } sub validate_document { my ($self, $context, $ref, $data, $options) = @_; my $name; my $documents = clone $self->documents->hash; my $_fmap = {}; # ad-hoc fields if ("HASH" eq ref $ref) { $ref = clone $ref; $name = "DOC" . time() . ($self->documents->count + 1); # build document on-the-fly from a hashref foreach my $rules (values %{$ref}) { next unless "HASH" eq ref $rules; my $id = uc "$rules"; $id =~ s/\W/_/g; $id =~ s/_$//; $self->fields->add($id => $rules); $rules = $id; $_fmap->{$id} = 1; } $documents->{$name} = $ref; } else { $name = $ref; } my $fields = { map { $_ => 1 } ($self->fields->keys) }; confess "Please supply a registered document name to validate against" unless $name ; confess "The ($name) document is not registered and cannot be validated against" unless $name && exists $documents->{$name} ; my $document = $documents->{$name}; confess "The ($name) document does not contain any mappings and cannot ". "be validated against" unless keys %{$documents} ; $options ||= {}; # handle sub-document references for my $key (keys %{$document}) { $document->{$key} = $documents->{$document->{$key}} if $document->{$key} && exists $documents->{$document->{$key}} && ! $self->fields->has($document->{$key}) ; } $document = flatten $document; my $signature = clone $document; # create document signature for my $key (keys %{$signature}) { (my $new = $key) =~ s/\\//g; $new =~ s/\*/???/g; $new =~ s/\.@/:0/g; $signature->{$new} = '???'; delete $signature->{$key} unless $new eq $key; } my $overlay = clone $signature; $_ = undef for values %{$overlay}; # handle regex expansions for my $key (keys %{$document}) { my $value = delete $document->{$key}; my $token; my $regex; $token = '\.\@'; $regex = ':\d+'; $key =~ s/$token/$regex/g; $token = '\*'; $regex = '[^\.]+'; $key =~ s/$token/$regex/g; $document->{$key} = $value; } my $_dmap = {}; my $_pmap = {}; my $_xmap = {}; my $_zata = flatten $data; my $_data = merge $overlay, $_zata; # remove overlaid patterns if matching nodes exist for my $key (keys %{$_data}) { if ($key =~ /\?{3}/) { (my $regex = $key) =~ s/\?{3}/\\w+/g; delete $_data->{$key} if grep { $_ =~ /$regex/ && $_ ne $key } keys %{$_data}; } } # generate validation rules for my $key (keys %{$_data}) { my $point = $key; $point =~ s/\W/_/g; my $label = $key; $label =~ s/\:/./g; my $match = 0; my $switch; for my $regex (keys %{$document}) { if (exists $_data->{$key}) { my $field = $document->{$regex}; if ($key =~ /^$regex$/) { $switch = $1 if $field =~ s/^([+-])//; my $config = {label => $label}; $config->{mixin} = $self->fields->get($field)->mixin if $self->fields->get($field)->can('mixin') ; $self->clone_field($field, $point => $config); $self->apply_mixin($point => $config->{mixin}) if $config->{mixin} ; $_dmap->{$key} = 1; $_pmap->{$point} = $key; $match = 1; } } } $_xmap->{$point} = $key; # register node as a parameter $self->params->add($point => $_data->{$key}) unless ! $match; # queue node and requirement $self->queue($switch ? "$switch$point" : "$point") unless ! $match; # prune unnecessary nodes delete $_data->{$key} if $options->{prune} && ! $match; } # validate $self->validate($context); $self->clear_queue; my @errors = $self->get_errors; for (sort @errors) { my ($message) = $_ =~ /field (\w+) does not exist/; next unless $message; $message = $_xmap->{$message}; next unless $message; $message =~ s/\W/./g; # re-format unknown parameter errors $_ = "The parameter $message was not expected and could not be validated"; } $_dmap = unflatten $_dmap; while (my($point, $key) = each(%{$_pmap})) { $_data->{$key} = $self->params->get($point); # prepare data $self->fields->delete($point) unless $fields->{$point}; # reap clones } $self->fields->delete($_) for keys %{$_fmap}; # reap ad-hoc fields $self->reset_fields; $self->set_errors(@errors) if @errors; # report errors $_[3] = unflatten $_data if defined $_[2]; # restore data return $self->is_valid; } sub method_validates { goto &validate_method } sub validate_method { my ($self, $context, $name, @args) = @_; confess "Context object ($self->{package} class instance) required ". "to perform method validation" unless $self->{package} eq ref $context; return 0 unless $name; $self->normalize($context); $self->apply_filters('pre'); my $method_spec = $self->methods->{$name}; my $input = $method_spec->{input}; if ($input) { my $code = $method_spec->{using}; my $output = $method_spec->{output}; weaken $method_spec->{$_} for ('using', 'output'); $method_spec->{using} = sub { 1 }; $method_spec->{output} = undef; $context->$name(@args); $method_spec->{using} = $code; $method_spec->{output} = $output; } return $self->is_valid ? 1 : 0; } sub profile_validates { goto &validate_profile } sub validate_profile { my ($self, $context, $name, @args) = @_; confess "Context object ($self->{package} class instance) required ". "to perform profile validation" unless $self->{package} eq ref $context ; return 0 unless $name; $self->normalize($context); $self->apply_filters('pre'); if (isa_coderef($self->profiles->{$name})) { return $self->profiles->{$name}->($context, @args); } return 0; } 1; __END__ =pod =head1 NAME Validation::Class::Prototype - Data Validation Engine for Validation::Class Classes =head1 VERSION version 7.900059 =head1 DESCRIPTION Validation::Class::Prototype is the validation engine used by proxy via L whose methods are aliases to the methods defined here. Please see L for a quick introduction on how to get started. =head1 ATTRIBUTES =head2 attributes The attributes attribute provides access to simple attributes registered on the the calling class. This attribute is a L object containing hashref objects and CANNOT be overridden. =head2 builders The builders attribute provides access to coderefs registered to hook into the instantiation process of the calling class. This attribute is a L object containing coderef objects and CANNOT be overridden. =head2 configuration The configuration attribute provides the default configuration profile. This attribute is a L object and CANNOT be overridden. =head2 directives The directives attribute provides access to defined directive objects. This attribute is a L object containing hashrefs and CANNOT be overridden. =head2 documents The documents attribute provides access to defined document models. This attribute is a L object and CANNOT be overridden. =head2 errors The errors attribute provides access to class-level error messages. This attribute is a L object, may contain error messages and CANNOT be overridden. =head2 events The events attribute provides access to validation events and the directives that subscribe to them. This attribute is a L object and CANNOT be overridden. =head2 fields The fields attribute provides access to defined fields objects. This attribute is a L object containing L objects and CANNOT be overridden. =head2 filtering The filtering attribute (by default set to 'pre') controls when incoming data is filtered. Setting this attribute to 'post' will defer filtering until after validation occurs which allows any errors messages to report errors based on the unaltered data. Alternatively, setting the filtering attribute to 'off' will bypass all filtering unless explicitly defined at the field-level. =head2 filters The filters attribute provides access to defined filters objects. This attribute is a L object containing code references and CANNOT be overridden. =head2 ignore_failure The ignore_failure boolean determines whether your application will live or die upon failing to validate a self-validating method defined using the method keyword. This is on (1) by default, method validation failures will set errors and can be determined by checking the error stack using one of the error message methods. If turned off, the application will die and confess on failure. =head2 ignore_intervention The ignore_intervention boolean determines whether validation will short-circuit if required fields are not present. This is off (0) by default; The logic behind this decision is that, for example, in the case of a required field, if the field was not submitted but was required, there is no need to perform additional validation. This is a type-of short-circuiting which reduces validation overhead. If you would like to emit all applicable validation errors you can enable this option. =head2 ignore_unknown The ignore_unknown boolean determines whether your application will live or die upon encountering unregistered field directives during validation. This is off (0) by default, attempts to validate unknown fields WILL cause the program to die. =head2 messages The messages attribute provides access to class-level error message overrides. This attribute is a L object containing scalar values. =head2 methods The methods attribute provides access to self-validating code references. This attribute is a L object containing code references. =head2 mixins The mixins attribute provides access to field templates. This attribute is a L object and CANNOT be overridden. The package attribute contains the namespace of the instance object currently using this module. =head2 params The params attribute provides access to input parameters. This attribute is a L object and CANNOT be overridden. =head2 profiles The profiles attribute provides access to validation profile. This attribute is a L object containing hash references and CANNOT be overridden. =head2 queued The queued attribute returns an arrayref of field names for validation and CANNOT be overridden. It represents a list of field names stored to be used in validation later. If the queued attribute contains a list, you can omit arguments to the validate method. =head2 report_failure The report_failure boolean determines whether your application will report self-validating method failures as class-level errors. This is off (0) by default, if turned on, an error messages will be generated and set at the class-level specifying the method which failed in addition to the existing messages. =head2 report_unknown The report_unknown boolean determines whether your application will report unregistered fields as class-level errors upon encountering unregistered field directives during validation. This is off (0) by default, attempts to validate unknown fields will NOT be registered as class-level variables. =head2 settings The settings attribute provides access to settings specific to the associated class, not to be confused with settings which exist in the prototype's configuration. This attribute is a L object and CANNOT be overridden. =head2 validated The validated attribute simply denotes whether the validation routine has been executed since the last normalization process (which occurs at instantiation and before validation). It's values will either be 0 (not validated), 1 (validated with errors), or 2 (validated without errors). You can simply check this attribute for truth when you need to know if validation has occurred. =head1 METHODS =head2 apply_filters The apply_filters method can be used to run the currently defined parameters through the filters defined in their matching fields. $self = $self->apply_filters; # apply filters to fields where filtering is set to 'post' filtering $self = $self->apply_filters('post'); =head2 class This method instantiated and returns the validation class specified , existing parameters and configuration options are passed to the constructor of the validation class (including the stash object). You can prevent/override arguments from being copied to the new class object by supplying the them as arguments to this method. The class method is also quite handy in that it will detect parameters that are prefixed with the name of the class being fetched, and automatically create aliases on the matching rules (if any) to allow validation to occur seamlessly. package Class; use Validation::Class; load classes => 1; # load child classes e.g. Class::* package main; my $input = Class->new(params => $params); my $child1 = $input->class('Child'); # loads Class::Child; my $child2 = $input->class('StepChild'); # loads Class::StepChild; my $child3 = $input->class('child'); # loads Class::Child; my $child4 = $input->class('step_child'); # loads Class::StepChild; # intelligently detecting and mapping parameters to child class my $params = { 'my.name' => 'Guy Friday', 'child.name' => 'Guy Friday Jr.' }; $input->class('child'); # child field *name* mapped to param *child.name* # without copying params from class my $child = $input->class('child', params => {}); 1; =head2 clear_queue The clear_queue method resets the queue container, see the queue method for more information on queuing fields to be validated. The clear_queue method has yet another useful behavior in that it can assign the values of the queued parameters to the list it is passed, where the values are assigned in the same order queued. my $self = Class->new(params => $params); $self->queue(qw(name +email)); # ... additional logic $self->queue(qw(+login +password)); if ($self->validate) { $self->clear_queue(my($name, $email)); print "Name is $name and email is $email"; } =head2 clone_field The clone_field method is used to create new fields (rules) from existing fields on-the-fly. This is useful when you have a variable number of parameters being validated that can share existing validation rules. Please note that cloning a field does not include copying and/or processing of any mixins on the original field to the cloned field, if desired, this must be done manually. package Class; use Validation::Class; field 'phone' => { label => 'Your Phone', required => 1 }; package main; my $self = Class->new(params => $params); # clone phone rule at run-time to validate dynamically created parameters $self->clone_field('phone', 'phone2', { label => 'Phone A', required => 0 }); $self->clone_field('phone', 'phone3', { label => 'Phone B', required => 0 }); $self->clone_field('phone', 'phone4', { label => 'Phone C', required => 0 }); $self->validate(qw/phone phone2 phone3 phone4/); 1; =head2 does The does method is used to determine whether the current prototype is composed using the role specified. Return true if so, false if not. package Class; use Validation::Class; set role => 'Class::Root'; package main; my $self = Class->new(params => $params); return 1 if $self->proto->does('Class::Root'); =head2 error_count The error_count method returns the total number of errors set at both the class and field level. my $count = $self->error_count; =head2 error_fields The error_fields method returns a hashref containing the names of fields which failed validation and an arrayref of error messages. unless ($self->validate) { my $failed = $self->error_fields; } my $suspects = $self->error_fields('field2', 'field3'); =head2 errors_to_string The errors_to_string method stringifies the all error objects on both the class and fields using the specified delimiter (defaulting to comma-space (", ")). return $self->errors_to_string("\n"); return $self->errors_to_string(undef, sub{ ucfirst lc shift }); unless ($self->validate) { return $self->errors_to_string; } =head2 get_errors The get_errors method returns a list of combined class-and-field-level errors. # returns all errors my @errors = $self->get_errors; # filter errors by fields whose name starts with critical my @critical = $self->get_errors(qr/^critical/i); # return errors for field_a and field_b specifically my @specific_field_errors = $self->get_errors('field_a', 'field_b'); =head2 get_fields The get_fields method returns the list of L objects for specific fields and returns an empty list if no arguments are passed. If a field does not match the name specified it will return undefined. my ($a, $b) = $self->get_fields('field_a', 'field_b'); =head2 get_hash The get_hash method returns a hashref consisting of all fields with their absolute values (i.e. default value or matching parameter value). If a field does not have an absolute value its value will be undefined. my $hash = $self->get_hash; =head2 get_params The get_params method returns the values of the parameters specified (as a list, in the order specified). This method will return a list of key/value pairs if no parameter names are passed. if ($self->validate) { my ($name) = $self->get_params('name'); my ($name, $email, $login, $password) = $self->get_params(qw/name email login password/); # you should note that if the params don't exist they will return # undef meaning you should check that it is defined before doing any # comparison checking as doing so would generate an error, e.g. if (defined $name) { if ($name eq '') { print 'name parameter was passed but was empty'; } } else { print 'name parameter was never submitted'; } } # alternatively ... my $params = $self->get_params; # return hashref of parameters print $params->{name}; =head2 get_values The get_values method returns the absolute value for a given field. This method executes specific logic which returns the value a field has based on a set of internal conditions. This method always returns a list, field names that do not exist are returned as undefined. my ($value) = $self->get_values('field_name'); # equivalent to my $param = $self->params->get('field_name'); my $field = $self->fields->get('field_name'); my $value; if ($field->{readonly}) { $value = $field->{default} || undef; } else { $value = $field->{value} || $param; } =head2 is_valid The is_valid method returns a boolean value which is true if the last validation attempt was successful, and false if it was not (which is determined by looking for errors at the class and field levels). return "OK" if $self->is_valid; =head2 normalize The normalize method executes a set of routines that conditions the environment filtering any parameters present whose matching field has its filtering directive set to 'pre'. This method is executed automatically at instantiation and again just before each validation event. $self->normalize; =head2 param The param method gets/sets a single parameter by name. This method returns the value assigned or undefined if the parameter does not exist. my $value = $self->param('name'); $self->param($name => $value); =head2 plugin The plugin method returns an instantiated plugin object which is passed the current prototype object. Note: This functionality is somewhat experimental. package Class; use Validation::Class; package main; my $input = Class->new(params => $params); my $formatter = $input->plugin('telephone_format'); # ... returns a Validation::Class::Plugin::TelephoneFormat object =head2 queue The queue method is a convenience method used specifically to append the queued attribute allowing you to *queue* fields to be validated. This method also allows you to set fields that must always be validated. $self->queue(qw/name login/); $self->queue(qw/email email2/) if $input->param('change_email'); $self->queue(qw/login login2/) if $input->param('change_login'); =head2 reset The reset method clears all errors, fields and queued field names, both at the class and individual field levels. $self->reset(); =head2 reset_errors The reset_errors method clears all errors, both at the class and individual field levels. This method is called automatically every time the validate() method is triggered. $self->reset_errors(); =head2 reset_fields The reset_fields method set special default directives and clears all errors and field values, both at the class and individual field levels. This method is executed automatically at instantiation. $self->reset_fields(); =head2 reset_params The reset_params method is responsible for completely removing any existing parameters and adding those specified. This method returns the class object. This method takes a list of key/value pairs or a single hashref. $self->reset_params($new_params); =head2 set_errors The set_errors method pushes its arguments (error messages) onto the class-level error stack and returns a count of class-level errors. my $count = $self->set_errors('...', '...'); =head2 set_fields The set_fields method is responsible setting/overriding registered fields. This method returns the class object. This method takes a list of key/value pairs or a single hashref whose key should be a valid field name and whose value should be a hashref that is a valid field configuration object. $self->set_fields($name => $config); # accepts hashref also =head2 set_params The set_params method is responsible for setting/replacing parameters. This method returns the class object. This method takes a list of key/value pairs or a single hashref whose keys should match field names and whose value should be a scalar or arrayref of scalars. $self->set_params($name => $value); # accepts a hashref also =head2 set_value The set_value method assigns a value to the specified field's parameter unless the field is readonly. This method returns the class object. $self->set_values($name => $value); =head2 stash The stash method provides a container for context/instance specific information. The stash is particularly useful when custom validation routines require insight into context/instance specific operations. package MyApp::Person; use Validation::Class; field 'email' => { validation => sub { my ($self) = @_; my $db = $self->stash('database'); return 0 unless $db; return $db->find(...) ? 0 : 1 ; # email exists } }; package main; # store the database object for use in email validation $self->stash(database => $database_object); =head2 validate The validate method (or has_valid, or validates) returns true/false depending on whether all specified fields passed validation checks. Please consider, if this method is called without any parameters, the list of fields to be validated will be assumed/deduced, making the execution strategy conditional, which may not be what you want. use MyApp::Person; my $input = MyApp::Person->new(params => $params); # validate specific fields unless ($input->validate('login','password')){ return $input->errors_to_string; } # validate fields based on a regex pattern unless ($input->validate(qr/^setting(\d+)?/)){ return $input->errors_to_string; } # validate existing parameters # however, if no parameters exist, ... # validate all fields, which will return true unless a field exists # with a required directive unless ($input->validate){ return $input->errors_to_string; } # validate all fields period, obviously unless ($input->validate($input->fields->keys)){ return $input->errors_to_string; } # implicitly validate parameters which don't explicitly match a field my $parameter_map = { user => 'login', pass => 'password' }; unless ($input->validate($parameter_map)){ return $input->errors_to_string; } Another cool trick the validate() method can perform is the ability to temporarily alter whether a field is required or not during validation. This functionality is often referred to as the *toggle* function. This method is important when you define a field as required or non and want to change that per validation. This is done by calling the validate() method with a list of fields to be validated and prefixing the target fields with a plus or minus respectively as follows: use MyApp::Person; my $input = MyApp::Person->new(params => $params); # validate specific fields, force name, email and phone to be required # regardless of the field directives ... and force the age, sex # and birthday to be optional my @spec = qw(+name +email +phone -age -sex -birthday); unless ($input->validate(@spec)){ return $input->errors_to_string; } =head2 validate_document The validate_document method (or document_validates) is used to validate the specified hierarchical data against the specified document declaration. This is extremely valuable for validating serialized messages passed between machines. This method requires two arguments, the name of the document declaration to be used, and the data to be validated which should be submitted in the form of a hashref. The following is an example of this technique: my $boolean = $self->validate_document(foobar => $data); Additionally, you may submit options in the form of a hashref to further control the validation process. The following is an example of this technique: # the prune option removes non-matching parameters (nodes) my $boolean = $self->validate_document(foobar => $data, { prune => 1 }); Additionally, to support the validation of ad-hoc specifications, you may pass this method two hashrefs, the first being the document notation schema, and the second being the hierarchical data you wish to validate. =head2 validate_method The validate_method method (or method_validates) is used to determine whether a self-validating method will be successful. It does so by validating the methods input specification. This is useful in circumstances where it is advantageous to know in-advance whether a self-validating method will pass or fail. It effectively allows you to use the methods input specification as a validation profile. if ($self->validate_method('password_change')) { # password_change will pass validation if ($self->password_change) { # password_change executed } } =head2 validate_profile The validate_profile method (or profile_validates) executes a stored validation profile, it requires a profile name and can be passed additional parameters which get forwarded into the profile routine in the order received. unless ($self->validate_profile('password_change')) { print $self->errors_to_string; } unless ($self->validate_profile('email_change', $dbi_handle)) { print $self->errors_to_string; } =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut 99-instance-based-stash-object.t100644000765000024 55414410403624 23733 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t#!/usr/bin/perl use utf8; use strict; use warnings; use Test::More; package T; use Validation::Class; field name => { required => 1 }; package main; my $rules; $rules = T->new; $rules->stash('user_id' => 1234); ok 1234 == $rules->stash('user_id'), 'stash key is 1234'; $rules = T->new; ok ! $rules->stash('user_id'), 'stash key is empty'; done_testing(); 98-03-document-example-pruning.t100644000765000024 336414410403624 23657 0ustar00christiaanstaff000000000000Validation-Class-7.900059/tuse utf8; use strict; use warnings; use Test::More; { package T; use Validation::Class; field 'string' => { mixin => ':str' }; document 'user' => { 'id' => 'string', 'name' => 'string', 'email' => 'string', 'comp*' => 'string' }; package main; my $class; eval { $class = T->new; }; ok "T" eq ref $class, "T instantiated"; my $documents = $class->prototype->documents; ok "Validation::Class::Mapping" eq ref $documents, "T documents hash registered as setting"; ok 1 == keys %{$documents}, "T has 1 registered document"; my $user = $documents->{user}; ok 4 == keys %{$user}, "T user document has 3 mappings"; can_ok $class, 'validate_document'; my $data = { "id" => 1234, "type" => "Master", "name" => "Root", "company" => "System, LLC", "login" => "root", "email" => "root\@localhost", "locations" => [ { "id" => 9876, "type" => "Node", "name" => "DevBox", "company" => "System, LLC", "address1" => "123 Street Road", "address2" => "Suite 2", "city" => "SINCITY", "state" => "NO", "zip" => "00000" } ] }; ok $class->validate_document(user => $data, {prune => 1}), "T document (user) valid"; my $_data = { "id" => 1234, "name" => "Root", "company" => "System, LLC", "email" => "root\@localhost", }; is_deeply $data, $_data, "T document has the correct pruned structure"; } done_testing; 16-cascading.t100644000765000024 130314410403624 24025 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regressionuse Test::More tests => 5; package MyVal; use Validation::Class; field password => {required => 1}; field password_conf => {mixin_field => 'password', matches => 'password'}; field chng_password => {depends_on => ['password_conf']}; package main; my $v = MyVal->new(params => {chng_password => 1}); ok $v, 'initialization successful'; ok !$v->validate(qw/chng_password password_conf/), 'validation failed'; ok $v->error_count == 1, 'validation failed because password_conf is requried'; $v->params->add(password_conf => 1); ok !$v->validate(qw/chng_password password_conf/), 'validation failed'; ok $v->error_count == 1, 'validation failed because password_conf does not match password'; 14-relatives.t100644000765000024 166514410403624 24120 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regressionuse Test::More tests => 11; BEGIN { use FindBin; use lib $FindBin::Bin . "/modules"; } use_ok 'MyVal'; my $rules = MyVal->new(params => {flag => 1}); my $chk_person = $rules->class('person'); my $chk_ticket = $rules->class('ticket'); ok "MyVal::Person" eq ref($chk_person), 'person class loaded successfully'; ok "MyVal::Ticket" eq ref($chk_ticket), 'ticket class loaded successfully'; ok $chk_person->fields->{name}, 'person class has name'; ok $chk_person->fields->{email}, 'person class has email'; ok !$chk_person->fields->{description}, 'person class doesnt have description'; ok !$chk_person->fields->{priority}, 'person class doesnt have priority'; ok !$chk_ticket->fields->{name}, 'ticket class doesnt have name'; ok !$chk_ticket->fields->{email}, 'ticket class doesnt have email'; ok $chk_ticket->fields->{description}, 'ticket class has description'; ok $chk_ticket->fields->{priority}, 'ticket class has priority'; Directives.pm100644000765000024 3143114410403624 24202 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class# ABSTRACT: Validation::Class Core Directives Registry package Validation::Class::Directives; use strict; use warnings; use base 'Validation::Class::Mapping'; use Validation::Class::Util '!has'; use List::MoreUtils 'first_index'; use Module::Find 'usesub'; use Carp 'confess'; use List::MoreUtils; our $_registry = {}; foreach my $module (usesub 'Validation::Class::Directive') { $_registry->{$module} = $module->new if $module->isa('Validation::Class::Directive') ; } our $VERSION = '7.900059'; # VERSION sub new { my $class = shift; my $arguments = $class->build_args(@_); $arguments = $_registry unless keys %{$arguments}; my $self = bless {}, $class; $self->add($arguments); return $self; } sub add { my $self = shift; my $arguments = $self->build_args(@_); while (my ($key, $value) = each %{$arguments}) { # never overwrite unless (defined $self->{$key}) { # is it a direct directive? if ("Validation::Class::Directive" eq ref $value) { $self->{$key} = $value; } # is it a directive sub-class elsif (isa_classref($value)) { if ($value->isa("Validation::Class::Directive")) { $self->{$value->name} = $value; } } # is it a hashref elsif (isa_hashref($value)) { $self->{$key} = Validation::Class::Directive->new($value); } } } return $self; } sub resolve_dependencies { my ($self, $type) = @_; $type ||= 'validation'; my $dependencies = {}; foreach my $key ($self->keys) { my $class = $self->get($key); my $name = $class->name; my $dependents = $class->dependencies->{$type}; # avoid invalid dependencies by excluding the unknown $dependencies->{$name} = [grep { $self->has($_) } @{$dependents}]; } my @ordered; my %found; my %track; my @pending = keys %$dependencies; my $limit = scalar(keys %$dependencies); $limit += scalar(@{$_}) for values %$dependencies; while (@pending) { my $k = shift @pending; if (grep { $_ eq $k } @{$dependencies->{$k}}) { confess sprintf 'Direct circular dependency on event %s: %s -> %s', $type, $k, $k; } elsif (grep { ! exists $found{$_} } @{$dependencies->{$k}}) { confess sprintf 'Invalid dependency on event %s: %s -> %s', $type, $k, join(',', @{$dependencies->{$k}}) if grep { ! exists $dependencies->{$_} } @{$dependencies->{$k}}; confess sprintf 'Indirect circular dependency on event %s: %s -> %s ', $type, $k, join(',', @{$dependencies->{$k}}) if $track{$k} && $track{$k} > $limit; # allowed circular iterations $track{$k}++ if push @pending, $k; } else { $found{$k} = 1; push @ordered, $k; } } my @list = reverse @ordered; foreach my $x (keys %$dependencies) { foreach my $y (@{$dependencies->{$x}}) { my $a = first_index { $_ eq $x } @list; my $b = first_index { $_ eq $y } @list; confess sprintf 'Broken dependency chain; Faulty ordering on '. 'event %s: %s before %s', $type, $x, $y if $a > $b ; } } return (@ordered); } 1; __END__ =pod =head1 NAME Validation::Class::Directives - Validation::Class Core Directives Registry =head1 VERSION version 7.900059 =head1 DESCRIPTION Validation::Class::Directives provides a collection of installed Validation::Class directives. This class inherits from L. Please look at L for information of developing your own directives. =head1 RATIONALE The following is a list of core directives that get installed automatically with Validation::Class and can be used to jump-start your data validation initiative. B The purpose of the core directives is merely to provide a reasonable layer of protection against bad/malformed data, the validators are not very sophisticated and were created using a minimal level of strictness (e.g. the email and hostname directives do not perform a hostname lookup nor does the email directive conform to the RFC specification). Various applications have varied levels of strictness regarding various types of input (e.g. a hospital API may require a more sophisticated SSN validation than that of a department of education API; likewise; an email service API may require a more sophisticated email validation than that of a file sharing API). Validation::Class does not attempt to provide validators for all levels of strictness and the core directives exist to support typical use-cases with a minimal level of strictness. =head2 alias The alias directive is provided by L and handles parameter aliases. =head2 between The between directive is provided by L and handles numeric range validation. =head2 city The city directive is provided by L and handles city/area validation for cities in the USA. =head2 creditcard The creditcard directive is provided by L and handles validation for american express, bankcard, diners card, discover card, electron, enroute, jcb, maestro, mastercard, solo, switch, visa and voyager credit cards. =head2 date The date directive is provided by L and handles validation of simple date formats. =head2 decimal The decimal directive is provided by L and handles validation of floating point integers. =head2 default The default directive is provided by L and hold the value which should be used if no parameter is supplied. =head2 depends_on The depends_on directive is provided by L and validates the existence of dependent parameters. =head2 email The email directive is provided by L and checks the validity of email address specified by the associated parameters within reason. Please note, the email directive does not perform a host lookup nor does it conform to the RFC specification. =head2 error The error directive is provided by L and holds the error message that will supersede any other error messages that attempt to register errors at the field-level for the associated field. =head2 errors The errors directive is provided by L and is a container (object) which holds error message registered at the field-level for the associated field. =head2 filtering The filtering directive is provided by L and specifies whether filtering and sanitation should occur as a pre-process or post-process. =head2 filters The filters directive is provided by L and specifies which filter should be executed on the associated field. =head2 hostname The hostname directive is provided by L and handles validatation of server hostnames. =head2 label The label directive is provided by L and holds a user-friendly string (name) representing the associated field. =head2 length The length directive is provided by L and validates the exact length of the associated parameters. =head2 matches The matches directive is provided by L and validates whether the value of the dependent parameters matches that of the associated field. =head2 max_alpha The max_alpha directive is provided by L and validates the length of alphabetic characters in the associated parameters. =head2 max_digits The max_digits directive is provided by L and validates the length of numeric characters in the associated parameters. =head2 max_length The max_length directive is provided by L and validates the length of all characters in the associated parameters. =head2 max_sum The max_sum directive is provided by L and validates the numeric value of the associated parameters. =head2 max_symbols The max_symbols directive is provided by L and validates the length of non-alphanumeric characters in the associated parameters. =head2 messages The messages directive is provided by L and is a container (object) which holds error message which will supersede the default error messages of the associated directives. =head2 min_alpha The min_alpha directive is provided by L and validates the length of alphabetic characters in the associated parameters. =head2 min_digits The min_digits directive is provided by L and validates the length of numeric characters in the associated parameters. =head2 min_length The min_length directive is provided by L and validates the length of all characters in the associated parameters. =head2 min_sum The min_sum directive is provided by L and validates the numeric value of the associated parameters. =head2 min_symbols The min_symbols directive is provided by L and validates the length of non-alphanumeric characters in the associated parameters. =head2 mixin The mixin directive is provided by L and determines what directive templates will be merged with the associated field. =head2 mixin_field The mixin_field directive is provided by L and determines what fields will be used as templates and merged with the associated field. =head2 multiples The multiples directive is provided by L and validates whether the associated parameters may contain a multi-value (an array of strings). =head2 name The name directive is provided by L and merely holds the name of the associated field. This value is populated automatically. =head2 options The options directive is provided by L and holds an enumerated list of values to be validated against the associated parameters. =head2 pattern The pattern directive is provided by L and handles validation of simple patterns and complex regular expressions. =head2 readonly The readonly directive is provided by L and determines whether the associated parameters should be ignored. =head2 required The required directive is provided by L and handles validation of supply and demand. =head2 ssn The ssn directive is provided by L and handles validation of social security numbers in the USA. =head2 state The state directive is provided by L and handles state validation for states in the USA. =head2 telephone The telephone directive is provided by L and handles telephone number validation for the USA and North America. =head2 time The time directive is provided by L and handles validation for standard time formats. =head2 toggle The toggle directive is provided by L and used internally to handle validation of per-validation-event requirements. =head2 uuid The uuid directive is provided by L and handles validation of Globally/Universally Unique Identifiers. =head2 validation The validation directive is provided by L and used to execute user-defined validation routines. =head2 value The value directive is provided by L and hold the absolute value of the associated field. =head2 zipcode The zipcode directive is provided by L and handles postal-code validation for areas in the USA and North America. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut 01-attributes.t100644000765000024 115614410403624 24277 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regressionuse Test::More tests => 7; package MyVal; use Validation::Class; package main; my $v = MyVal->new; # check attributes ok $v->params, 'params attr ok'; ok $v->fields, 'fields attr ok'; # ok $v->filters({}), 'filters attr ok'; - DEPRECATED ok $v->proto->filters, 'filters attr ok'; # ok $v->mixins({}), 'mixins attr ok'; - DEPRECATED ok $v->proto->mixins, 'mixins attr ok'; # ok $v->types({}), 'types attr ok'; - DEPRECATED #ok $v->proto->types, 'types attr ok'; - DROPPED ok $v->ignore_unknown(1), 'ignore unknown attr ok'; ok $v->report_unknown(1), 'report unknown attr ok'; ok !$v->error_count, 'no errors yet'; 04-parameters.t100644000765000024 237114410403624 24257 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regressionuse Test::More tests => 3; # load module package MyVal; use Validation::Class; my $passer = sub {1}; field 'id', { label => 'ID', error => 'id error', min_length => 24, max_length => 24 }; field 'id2', { label => 'ID', required => 1, error => 'id error', min_length => 24, max_length => 24 }; field 'login', { label => 'user login', error => 'login invalid', validation => $passer }; field 'password', { label => 'user password', error => 'password invalid', validation => $passer }; field 'name', { label => 'user name', error => 'invalid name', validation => $passer }; field 'phone', { label => 'user phone', error => 'phone invalid', validation => $passer }; field 'email', { label => 'user email', error => 'email invalid', validation => $passer }; package main; my $v = MyVal->new( params => { id2 => '', login => 'admin', password => 'pass' } ); ok $v, 'validation-class initialized'; ok !$v->validate(qw/id2 login password/), 'validation works and found id error'; ok $v->errors_to_string eq 'id error', 'id error found with correct value'; 10-validation.t100644000765000024 424014410403624 24240 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regressionuse Test::More tests => 27; package MyVal; use Validation::Class; package main; my $v = MyVal->new( fields => {foobar => {error => 'foobar error'}}, params => {foobar => 'abc123456'} ); ok $v, 'class initialized'; ok defined $v->fields->{foobar}, 'foobar field exists'; ok defined $v->params->{foobar}, 'foobar param exists'; # check min_length directive $v->fields->{foobar}->{min_length} = 10; ok !$v->validate('foobar'), 'error found as expected'; ok !$v->validate, 'alternate use of validation found error also'; ok $v->error_count == 1, 'error count is correct'; ok $v->errors_to_string eq 'foobar error', 'error message specified captured'; $v->fields->{foobar}->{min_length} = 5; ok $v->validate('foobar'), 'foobar rule validates'; ok $v->validate, 'alternate use of validation validates'; ok $v->error_count == 0, 'error count is zero'; ok $v->errors_to_string eq '', 'no error messages found'; # check max_length directive $v->fields->{foobar}->{max_length} = 8; ok !$v->validate('foobar'), 'error found as expected'; ok !$v->validate, 'alternate use of validation found error also'; ok $v->error_count == 1, 'error count is correct'; ok $v->errors_to_string eq 'foobar error', 'error message specified captured'; $v->fields->{foobar}->{max_length} = 9; ok $v->validate('foobar'), 'foobar rule validates'; ok $v->validate, 'alternate use of validation validates'; ok $v->error_count == 0, 'error count is zero'; ok $v->errors_to_string eq '', 'no error messages found'; # check pattern directive $v->fields->{foobar}->{pattern} = 'XXX######'; ok $v->validate('foobar'), 'foobar rule validates'; ok $v->validate, 'alternate use of validation validates'; ok $v->error_count == 0, 'error count is zero'; ok $v->errors_to_string eq '', 'no error messages found'; # check pattern (telephone example) directive delete $v->fields->{foobar}->{error}; $v->fields->{foobar}->{pattern} = '(###) ###-####'; $v->params->{foobar} = '111-1111'; ok !$v->validate('foobar'), 'foobar rule doesnt validate'; ok !$v->validate, 'alternate use of validation doesnt validate'; ok $v->error_count == 1, 'error count is correct'; ok $v->errors_to_string =~ 'not formatted', 'pattern error message found'; Whitepaper.pod100644000765000024 4426714410403624 24372 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class# PODNAME: Validation::Class::Whitepaper # ABSTRACT: Operate with Impunity # VERSION __END__ =pod =head1 NAME Validation::Class::Whitepaper - Operate with Impunity =head1 VERSION version 7.900059 =head1 INTRODUCTION This whitepaper will serves as a guide to help readers understand the common data validation issues as well as the the rationale and various usage scenarios for Validation::Class. Data validation is an important aspect of every application yet it is often overlooked or neglected. Data validation should be thought of as your data input firewall, a layer that exist between the user of your application and the application's business objects. =head1 DATA VALIDATION PROBLEMS The most common application security weakness is the failure to properly validate input from the client or environment. Data validation is important because it provides security, it allows you to ensure user supplied data is formatted properly, is within length boundaries, contains permitted characters and adheres to business rules. To understand the problem domain we need to first ask ourselves: * what is data validation? and ... is that what I've been doing? * what are the common data validation requirements? * what are the common use-cases where validation becomes tricky? Data validation is the process of auditing a piece of data to ensure it fits a specific criteria. Standard data validation requirements are: * existence checking * range checking * type checking * list-lookup checking * dependency checking * pattern checking * custom validation checking (business logic) Typically when designing an application we tend to name input parameters in an arbitrarily fashion and validate the same data at various stages during a program's execution (duplicating logic and validation routines) in various places in the application stack. This approach is inefficient and prone to bugs, inconsistencies and security problems. Data can be submitted to an application in various formats and it is not always ideal, and the option to pre-format the data is not always ideal or even possible. A few common use-cases were validation is required and often fails (in a big big way) are as follows: * handling arbitrarily and/or dynamically-named parameters * handling input for batch-processing * handling multi-type parameters (array or scalar depending on context) * handling complex conditional validation logic * handling multi-variant parameter names (aliases) * handling parameter dependencies * handling errors (reporting messages, localization, etc) =head1 A DATA VALIDATION SOLUTION A better approach to data validation is to first consider each parameter hitting your application as a transmission fitting a very specific criteria and construct a data validation layer that operates with that in mind (e.g. exactly like a network firewall). Your data validation rules should act as filters which will accept or reject and format the transmission for use within your application. A proper validation framework should allow you to model data and construct validation objects with a focus on structuring rules, reusing common declarations, defining input filters and validating data. Its main purpose should be to properly handle data input errors. It's ulterior motive should be to ensure consistency and promote reuse of data validation rules. =head1 WHY VALIDATION::CLASS Validation::Class was built around the concept of compartmentalization and re-use. That premise gave birth to the idea of persistent data validation rules which exist in a class configuration which is associated with a class which acts as a validation domain for related validation rules. Validation classes derived from Validation::Class are typically configured using the Validation::Class sugar functions (or keywords). Validation classes are typically defined using the following keywords: * field - a data validation rule that matches an input parameter * mixin - a configuration template which can be merged with a field * directive - a field/mixin rule corresponding to a directive class name * filter - a custom filtering routine which transforms a field value * method - a self-validating sub-routine w/ associated validation profile A data validation framework exists to handle failures, it is its main function and purpose, in-fact, the difference between a validation framework and a type-constraint system is how it responds to errors. There are generally two types of errors that occur in an application, user-errors which are expected and should be handled and reported so that a user can correct the problem, and system-errors which are unexpected and should cause the application to terminate and/or handling the exception. Exception handling is the process of responding to the occurrence, during computation, of exceptions (anomalous or exceptional situations). User errors and system errors are poplar opposites. It is not always desired and/or appropriate to crash from a failure to validate user input. The following examples should clearly display how Validation::Class addresses key pain-points and handles common use-cases were validation is usually quite arduous. =head2 Dynamic Parameters # handling arbitrary and/or dynamically-named parameters package DynamicParameters; use Validation::Class; field email => { required => 1, pattern => qr/\@localhost$/ }; field login => { required => 1, min_length => 5, alias => ['user'] }; field password => { required => 1, min_length => 5, min_digits => 1, alias => ['pass'] }; package main; my $params = { user => 'admin', # arbitrary pass => 's3cret', # arbitrary email_1 => 'admin@localhost', # dynamic created email_2 => 'root@localhost', # dynamic created email_3 => 'sa@localhost', # dynamic created }; my $dp = DynamicParameters->new(params => $params); $dp->proto->clone_field('email', $_) for $dp->params->grep(qr/^email/)->keys ; print $dp->validate ? "OK" : "NOT OK"; 1; =head2 Batch-Processing # handling input for batch-processing package BatchProcessing; use Validation::Class; mixin scrub => { required => 1, filters => ['trim', 'strip'] }; field header => { mixin => 'scrub', options => ['name', 'email', 'contact', 'dob', 'country'], multiples => 1 # handle param as a scalar or arrayref }; field name => { mixin => 'scrub', filters => ['titlecase'], min_length => 2 }; field email => { mixin => 'scrub', min_length => 3 }; field contact => { mixin => 'scrub', length => 10 }; field dob => { mixin => 'scrub', length => 8, pattern => '##/##/##' }; field country => { mixin => 'scrub' }; package main; my $params = { pasted_data => q{ name email contact dob country john john@zuzu.com 9849688899 12/05/98 UK jim kathy kjim@zuz.com 8788888888 05/07/99 India Federar fed@zuzu.com 4484848989 11/21/80 USA Micheal micheal@zuzu.com 6665551212 06/10/87 USA Kwang Kit kwang@zuzu.com 7775551212 07/09/91 India Martin jmartin@zuzu.com 2159995959 02/06/85 India Roheeth roheeth@zuzu.com 9596012020 01/10/89 USA } }; # ... there are many ways this could be parsed and validated # ... but this is simple my $bpi = my @pasted_lines = map { s/^\s+//; $_ } split /\n/, $params->{pasted_data}; my @headers = split /\t/, shift @pasted_lines; my $bp = BatchProcessing->new(params => { header => [@headers] }); # validate headers first if ($bp->validate) { $bp->params->clear; $bpi--; # validate each line, halt on first bad line while (my $line = shift @pasted_lines) { my @data = split /\t/, $line; for (my $i=0; $i<@data; $i++) { $bp->params->add($headers[$i], $data[$i]); } last unless $bp->validate; $bp->params->clear; $bpi--; } } print ! $bpi ? "OK" : "NOT OK"; 1; =head2 Multi-Type Parameters # handling multi-type parameters (array or scalar depending on context) package MultiType; use Validation::Class; field letter_type => { required => 1, options => [ 'A' .. 'Z' ], multiples => 1 # turn on multi-type processing }; package main; my $mt = MultiType->new; my $ok = 0; $mt->params->add(letter_type => 'A'); $ok++ if $mt->validate; $mt->params->clear->add(letter_type => ['A', 'B', 'C']); $ok++ if $mt->validate; print $ok == 2 ? "OK" : "NOT OK"; 1; =head2 Complex Conditions # handling complex conditional validation logic package ComplexCondition; use Validation::Class; mixin scrub => { required => 1, filters => ['trim', 'strip'] }; mixin flag => { length => 1, options => [0, 1] }; field first_name => { mixin => 'scrub', filters => ['titlecase'] }; field last_name => { mixin => 'scrub', filters => ['titlecase'] }; field role => { mixin => 'scrub', filters => ['titlecase'], options => ['Client', 'Employee', 'Administrator'], default => 'Client' }; field address => { mixin => 'scrub', required => 0, depends_on => ['city', 'state', 'zip'] }; field city => { mixin => 'scrub', required => 0, depends_on => 'address' }; field state => { mixin => 'scrub', required => 0, length => '2', pattern => 'XX', depends_on => 'address' }; field zip => { mixin => 'scrub', required => 0, length => '5', pattern => '#####', depends_on => 'address' }; field has_mail => { mixin => 'flag' }; profile 'registration' => sub { my ($self) = @_; # address info not required unless role is client or has_mail is true return unless $self->validate('has_mail'); $self->queue(qw/first_name last_name/); if ($self->param('has_mail') || $self->param('role') eq 'Client') { # depends_on directive kinda makes city, state and zip required too $self->queue(qw/+address/); } my $ok = $self->validate; $self->clear_queue; return $ok; }; package main; my $ok = 0; my $mt; $mt = ComplexCondition->new( first_name => 'Rachel', last_name => 'Green' ); # defaults to client, missing address info $ok++ if ! $mt->validate_profile('registration'); $mt = ComplexCondition->new( first_name => 'monica', last_name => 'geller', role => 'employee' ); # filters (pre-process) role and titlecase, as employee no address needed $ok++ if $mt->validate_profile('registration'); $mt = ComplexCondition->new( first_name => 'phoebe', last_name => 'buffay', address => '123 street road', city => 'nomans land', state => 'zz', zip => '54321' ); $ok++ if $mt->validate_profile('registration'); print $ok == 3 ? "OK" : "NOT OK"; 1; =head2 Multi-Variant Parameters # handling multi-variant parameter names (aliases) package MultiName; use Validation::Class; field login => { required => 1, min_length => 5, # must be 5 or more chars min_alpha => 1, # must have at-least 1 alpha char min_digits => 1, # must have at-least 1 digit char min_symbols => 1, # must have at-least 1 non-alphanumeric char alias => [ 'signin', 'username', 'email', 'email_address' ] }; package main; my $ok = 0; # fail $ok++ if ! MultiName->new(login => 'miso')->validate; # nice $ok++ if MultiName->new(login => 'm!s0_soup')->validate; # no signin field exists, however, the alias directive pre-processing DWIM $ok++ if MultiName->new(signin => 'm!s0_soup')->validate; # process aliases $ok++ if MultiName->new(params => {signin => 'm!s0_soup'})->validate; $ok++ if MultiName->new(params => {username => 'm!s0_soup'})->validate; $ok++ if MultiName->new(params => {email => 'm!s0_soup'})->validate; $ok++ if MultiName->new(params => {email_address => 'm!s0_soup'})->validate; print $ok == 7 ? "OK" : "NOT OK"; 1; =head2 Parameter Dependencies # handling parameter dependencies package ParamDependencies; use Validation::Class; mixin scrub => { required => 1, filters => ['trim', 'strip'] }; mixin flag => { length => 1, options => [0, 1] }; field billing_address => { mixin => 'scrub', required => 1, depends_on => ['billing_city', 'billing_state', 'billing_zip'] }; field billing_city => { mixin => 'scrub', required => 0, depends_on => 'billing_address' }; field billing_state => { mixin => 'scrub', required => 0, length => '2', pattern => 'XX', depends_on => 'billing_address' }; field billing_zip => { mixin => 'scrub', required => 0, length => '5', pattern => '#####', depends_on => 'billing_address' }; field shipping_address => { mixin_field => 'billing_address', depends_on => ['shipping_city', 'shipping_state', 'shipping_zip'] }; field shipping_city => { mixin_field => 'billing_city', depends_on => 'shipping_address' }; field shipping_state => { mixin_field => 'billing_state', depends_on => 'shipping_address' }; field shipping_zip => { mixin_field => 'billing_zip', depends_on => 'shipping_address' }; field same_billing_shipping => { mixin => 'flag' }; profile 'addresses' => sub { my ($self) = @_; return unless $self->validate('same_billing_shipping'); # billing and shipping address always required $self->validate(qw/+billing_address +shipping_address/); # address must match if option is selected if ($self->param('same_billing_shipping')) { foreach my $param ($self->params->grep(qr/^shipping_/)->keys) { my ($suffix) = $param =~ /^shipping_(.*)/; my $billing = $self->param("billing_$suffix"); my $shipping = $self->param("shipping_$suffix"); # shipping_* must match billing_* unless ($billing eq $shipping) { $self->errors->add( "Billing and shipping addresses do not match" ); last; } } } return $self->error_count ? 0 : 1; }; package main; my $ok = 0; my $pd; $pd = ParamDependencies->new( billing_address => '10 liberty boulevard', billing_city => 'malvern', billing_state => 'pa', billing_zip => '19355' ); # missing shipping address info $ok++ if ! $pd->validate_profile('addresses'); $pd = ParamDependencies->new( billing_address => '10 liberty boulevard', billing_city => 'malvern', billing_state => 'pa', billing_zip => '19355', shipping_address => '301 cherry street', shipping_city => 'pottstown', shipping_state => 'pa', shipping_zip => '19464' ); $ok++ if $pd->validate_profile('addresses'); $pd = ParamDependencies->new( billing_address => '10 liberty boulevard', billing_city => 'malvern', billing_state => 'pa', billing_zip => '19355', same_billing_shipping => 1, shipping_address => '301 cherry street', shipping_city => 'pottstown', shipping_state => 'pa', shipping_zip => '19464' ); # billing and shipping don't match $ok++ if ! $pd->validate_profile('addresses'); $pd = ParamDependencies->new( billing_address => '10 liberty boulevard', billing_city => 'malvern', billing_state => 'pa', billing_zip => '19355', same_billing_shipping => 1, shipping_address => '10 liberty boulevard', shipping_city => 'malvern', shipping_state => 'pa', shipping_zip => '19355' ); $ok++ if $pd->validate_profile('addresses'); print $ok == 4 ? "OK" : "NOT OK"; 1; =head1 GETTING STARTED If you are looking for a simple way to get started with L, please review L. The instructions contained there are also relevant for configuring any class derived from L. =head1 ADDITIONAL INSIGHT The following L and/or L explains what L is, why it was created, and what it has to offer. Please note that this screencast and slideshow was created many moons ago and some of its content may be a bit outdated. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut 98-03-document-example-reporting.t100644000765000024 704714410403624 24210 0ustar00christiaanstaff000000000000Validation-Class-7.900059/tuse utf8; use strict; use warnings; use Test::More; { package T0; use Validation::Class; field 'string' => { mixin => ':str' }; document 'user' => { 'name' => 'string', 'email' => 'string', }; package main; my $class = eval { T0->new }; ok "T0" eq ref $class, "T0 instantiated"; my $data = {}; ok ! $class->validate_document(user => $data), "T0 document (user) not valid"; ok 2 == $class->error_count, "T0 document failed with 2 errors"; } { package T1; use Validation::Class; field 'string' => { mixin => ':str' }; document 'user' => { 'id' => 'string', 'name' => 'string', 'email' => 'string', 'comp*' => 'string' }; package main; my $class = eval { T1->new }; ok "T1" eq ref $class, "T1 instantiated"; my $documents = $class->prototype->documents; ok "Validation::Class::Mapping" eq ref $documents, "T1 documents hash registered as setting"; ok 1 == keys %{$documents}, "T1 has 1 registered document"; my $user = $documents->{user}; ok 4 == keys %{$user}, "T1 user document has 3 mappings"; can_ok $class, 'validate_document'; my $data = { "id" => 1234, "type" => "Master", "name" => "Root", "company" => "System, LLC", "login" => "root", "email" => "root\@localhost", "office_locations" => [ { "id" => 9876, "type" => "Node", "name" => "DevBox", "company" => "System, LLC", "address1" => "123 Street Road", "address2" => "Suite 2", "city" => "SINCITY", "state" => "NO", "zip" => "00000" } ] }; ok $class->validate_document(user => $data), "T1 document (user) valid"; ok 0 == $class->error_count, "T1 document passed with no errors"; } { package T2; use Validation::Class; field 'string' => { mixin => ':str' }; document 'user' => { 'id' => 'string', 'name' => 'string', 'email' => 'string', 'comp*' => 'string' }; package main; my $class = eval { T2->new }; ok "T2" eq ref $class, "T2 instantiated"; my $documents = $class->prototype->documents; ok "Validation::Class::Mapping" eq ref $documents, "T2 documents hash registered as setting"; ok 1 == keys %{$documents}, "T2 has 1 registered document"; my $user = $documents->{user}; ok 4 == keys %{$user}, "T2 user document has 3 mappings"; can_ok $class, 'validate_document'; my $data = { "id" => 1234, "type" => "Master", "name" => "Root", "company" => "System, LLC", "login" => "root", "email" => "root\@localhost", "office_locations" => [ { "id" => 9876, "type" => "Node", "name" => "DevBox", "company" => "System, LLC", "address1" => "123 Street Road", "address2" => "Suite 2", "city" => "SINCITY", "state" => "NO", "zip" => "00000" } ] }; ok $class->validate_document(user => $data), "T2 document (user) valid"; ok 0 == $class->error_count, "T2 document has no errors"; } done_testing; 42-inheritence.t100644000765000024 76414410403624 24377 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regressionuse Test::More; BEGIN { use FindBin; use lib $FindBin::Bin . "/modules"; } package main; use MyVal::Temp; my $v = MyVal::Temp->new; ok $v, 'new temp obj'; ok $v->fields->{name}, 'temp obj has name'; ok $v->fields->{email}, 'temp obj has email'; ok $v->fields->{login}, 'temp obj has login'; ok $v->fields->{password}, 'temp obj has password'; # ok $v->mixins->{TMP}, 'temp obj has TMP mixin'; - DEPRECATED ok $v->proto->mixins->{TMP}, 'temp obj has TMP mixin'; done_testing; modules000755000765000024 014410403624 23013 5ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regressionMyVal.pm100644000765000024 100214410403624 24532 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/modulespackage MyVal; use Validation::Class; load { classes => 1 }; profile new_ticket => sub { my ($self) = shift; # check person, and ticket values my $person = $self->class('person'); my $ticket = $self->class('ticket'); unless ($person->validate('+name')) { $self->set_errors($person->get_errors); } unless ($ticket->validate('+description', 'priority')) { $self->set_errors($ticket->get_errors); } return $self->error_count ? 0 : 1 }; 1; 99-check-queuing-and-alternatives.t100644000765000024 334514410403624 24477 0ustar00christiaanstaff000000000000Validation-Class-7.900059/tuse FindBin; use Test::More; use utf8; use strict; use warnings; { use_ok 'Validation::Class'; } { { package T; use Validation::Class; our $i = 0; field email => { min_length => 1 }; field passw => { validation => sub { return ++$i } }; profile create1 => sub { my ($self) = @_; return 0 unless $self->validate; return $self->validate('+email') ? 1 : 0; }; profile create2 => sub { my ($self) = @_; $self->queue('+email'); return $self->validate ? 1 : 0; }; profile create3 => sub { my ($self) = @_; return $self->validate($self->params->keys, '+passw') ? 1 : 0; }; profile create4 => sub { my ($self) = @_; $self->queue($self->params->keys, '+passw'); return $self->validate ? 1 : 0; }; } package main; my $t = T->new( ignore_unknown => 1, report_unknown => 1, ); $t->params->add({'email' => 'bob@test.net','unknown' => 'test'}); ok "T" eq ref $t, "T instantiated"; ok ! $t->validate_profile('create1'), 't profile create1 DOES NOT validate'; $t->report_unknown(0); ok $t->validate_profile('create1'), 't profile create1 validates'; ok $t->validate_profile('create2'), 't profile create2 validates'; $t->params->add(passw => 's3cret'); ok $t->validate_profile('create3'), 't profile create3 validates'; ok 1 == $T::i, 'validate method aggregated fields specified'; ok $t->validate_profile('create4'), 't profile create4 validates'; ok 2 == $T::i, 'validate method aggregated fields specified via queue'; } done_testing(); 98-02-document-synopsis-filtering.t100644000765000024 327114410403624 24410 0ustar00christiaanstaff000000000000Validation-Class-7.900059/tuse utf8; use strict; use warnings; use Test::More; package T; use Validation::Class; field 'title'; field 'rating'; field 'name'; field 'id' => { filters => ['numeric'] }; document 'person' => { 'id' => 'id', 'name' => 'name', 'title' => 'title', 'company.name' => 'name', 'company.supervisor.name' => 'name', 'company.supervisor.rating.@.support' => 'rating', 'company.supervisor.rating.@.guidance' => 'rating', 'company.tags.@' => 'name' }; package main; my $class; eval { $class = T->new; }; ok "T" eq ref $class, "T instantiated"; my $documents = $class->prototype->documents; ok "Validation::Class::Mapping" eq ref $documents, "T documents hash registered as setting"; ok 1 == keys %{$documents}, "T has 1 registered document"; my $person = $documents->{person}; ok 8 == keys %{$person}, "T user document has 3 mappings"; can_ok $class, 'validate_document'; $person = { "id" => "1234-ABC", "name" => "Anita Campbell-Green", "title" => "Designer", "company" => { "name" => "House of de Vil", "supervisor" => { "name" => "Cruella de Vil", "rating" => [ { "support" => -9, "guidance" => -9 } ] }, "tags" => [ "evil", "cruelty", "dogs" ] }, }; ok $class->validate_document(person => $person), "T document (person) validated"; ok $person->{id} !~ /\D/, "person document has been filtered"; done_testing; Container.pm100644000765000024 60214410403624 24503 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/myapp/lib/MyApppackage MyApp::Container; use base 'MyApp::Test::Base'; use Validation::Class; mxn other => { required => 1, max_length => 255, filters => [qw/trim strip/] }; fld name => { mixin => 'basic', max_length => 255, required => 0 }; bld sub { my ($self) = @_; $self->name('Boy'); return $self; }; 1;Test000755000765000024 014410403624 23024 5ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/myapp/lib/MyAppBase.pm100644000765000024 61714410403624 24360 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/myapp/lib/MyApp/Testpackage MyApp::Test::Base; use base 'MyApp::Test::Base::Email'; use Validation::Class; # rules mixin mxn basic => { required => 1, max_length => 255, filters => [qw/trim strip/] }; fld id => { mixin => 'basic', max_length => 11, required => 0 }; # build method, run automatically after new() bld sub { shift->id(1) }; 1;12-queued-rules.t100644000765000024 471014410403624 24532 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regressionuse Test::More tests => 27; package MyVal; use Validation::Class; mixin ID => { required => 1, min_length => 1, max_length => 11 }; mixin TEXT => { required => 1, min_length => 1, max_length => 255 }; field id => { mixin => 'ID', label => 'Object ID', error => 'Object ID error' }; field name => { mixin => 'TEXT', label => 'Object Name', error => 'Object Name error' }; field email => { mixin => 'TEXT', label => 'Object Email', error => 'Object Email error', max_length => 500 }; field email_confirm => { mixin_field => 'email', label => 'Object Email Confirm', error => 'Object Email confirmation error', min_length => 5 }; package main; use strict; use warnings; my $p = {name => '', email => 'awncorp@cpan.org'}; my $v = MyVal->new(params => $p); ok $v, 'initialization successful'; ok !$v->clear_queue, 'queue cleared, no errors'; ok $v->queue(qw/name email/), 'queued name and email'; ok !$v->validate, 'validation failed'; ok $v->error_count == 1, 'expected number of errors'; ok !$v->validate('id'), 'validation failed'; ok $v->error_count == 2, 'expected number of errors'; ok $v->param(qw/name AWNCORP/) eq 'AWNCORP', 'set parameter ok'; ok $v->param(qw/id 100/) == 100, 'set parameter ok'; ok $v->validate, 'validation succesful'; ok !$v->error_count, 'no errors'; ok $v->validate('id'), 'validation succesful'; ok !$v->error_count, 'no errors'; # ok $v->reset, 'reset ok'; - DEPRECATED ok $v->proto->clear_queue, 'queue reset ok'; ok $v->proto->reset_fields(), 'fields reset ok'; ok !$v->validate(keys %{$v->fields}), 'validate all (not queued) failed'; ok $v->error_count == 1, 'error - email_confirm not set'; # advanced queue usage $v->param($_ => '') for qw(id name); ok $v->queue('+id'), 'queued id w/requirement'; ok $v->queue('+name'), 'queued name w/requirement'; ok $v->queue('email'), 'queued email'; # ok 3 == @{$v->queued}, '3 fields queued'; - DEPRECATED ok 3 == @{$v->proto->queued}, '3 fields queued'; ok !$v->validate, 'error: both fields required, no input'; ok 2 == $v->error_count, '2 errors encoutered'; $v->param(id => 123); $v->param(name => 456); ok 3 == $v->clear_queue(my ($id, $name)), 'rid the queue of 3 fields, 2 set'; ok $id == 123, 'local variable (id) set correctly'; ok $name == 456, 'local variable (name) set correctly'; # ok ! @{$v->queued}, 'no fields queued' - DEPRECATED; ok !@{$v->proto->queued}, 'no fields queued'; 13-independence.t100644000765000024 350514410403624 24535 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regressionuse Test::More tests => 18; BEGIN { use FindBin; use lib $FindBin::Bin . "/modules"; } use_ok 'MyVal::Person'; use_ok 'MyVal::Ticket'; package val::a; use Validation::Class; mixin TMP => { required => 1, between => '1-255' }; field name => { mixin => 'TMP', label => 'Person\'s name' }; field email => { mixin => 'TMP', label => 'Person\'s email' }; package val::b; use Validation::Class; field description => { mixin => 'TMP', label => 'Ticket description' }; field priority => { mixin => 'TMP', label => 'Ticket priority', options => [qw/Low Normal High Other/] }; { package val::test1; use Test::More; my $foo = val::a->new(params => {flag => 0}); my $bar = val::b->new(params => {flag => 0}); ok $foo->fields->{name}, 'foo has name'; ok $foo->fields->{email}, 'foo has email'; ok !$foo->fields->{description}, 'foo doesnt have description'; ok !$foo->fields->{priority}, 'foo doesnt have priority'; ok !$bar->fields->{name}, 'bar doesnt have name'; ok !$bar->fields->{email}, 'bar doesnt have email'; ok $bar->fields->{description}, 'bar has description'; ok $bar->fields->{priority}, 'bar has priority'; } { package val::test2; use Test::More; my $foo = MyVal::Person->new(params => {flag => 1}); my $bar = MyVal::Ticket->new(params => {flag => 1}); ok $foo->fields->{name}, 'foo has name'; ok $foo->fields->{email}, 'foo has email'; ok !$foo->fields->{description}, 'foo doesnt have description'; ok !$foo->fields->{priority}, 'foo doesnt have priority'; ok !$bar->fields->{name}, 'bar doesnt have name'; ok !$bar->fields->{email}, 'bar doesnt have email'; ok $bar->fields->{description}, 'bar has description'; ok $bar->fields->{priority}, 'bar has priority'; } 03-mixin-usages.t100644000765000024 364614410403624 24532 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regressionuse Test::More tests => 9; package MyVal; use Validation::Class; mixin ID => { required => 1, min_length => 1, max_length => 11 }; mixin TEXT => { required => 1, min_length => 1, max_length => 255, filters => [qw/trim strip/] }; mixin UTEXT => { required => 1, min_length => 1, max_length => 255, filters => 'uppercase' }; field id => { mixin => 'ID', label => 'Object ID', error => 'Object ID error' }; field name => { mixin => 'TEXT', label => 'Object Name', error => 'Object Name error', filters => ['uppercase'] }; field handle => { mixin => 'UTEXT', label => 'Object Handle', error => 'Object Handle error', filters => [qw/trim strip/] }; field email => { mixin => 'TEXT', label => 'Object Email', error => 'Object Email error', max_length => 500 }; field email_confirm => { mixin_field => 'email', label => 'Object Email Confirm', error => 'Object Email confirmation error', min_length => 5 }; package main; my $v = MyVal->new(params => {name => ' p3rlc0dr '}); ok $v, 'initialization successful'; ok $v->fields->{email}->{max_length} == 500, 'email max_length mixin overridden'; ok $v->fields->{email_confirm}->{required}, 'email_confirm required ok'; ok $v->fields->{email_confirm}->{min_length} == 5, 'email_confirm min_length ok'; ok $v->fields->{email_confirm}->{max_length} == 500, 'email_confirm max_length ok'; ok $v->fields->{email_confirm}->{label} eq 'Object Email Confirm', 'email_confirm label ok'; ok $v->fields->{email_confirm}->{error} eq 'Object Email confirmation error', 'email_confirm error ok'; ok $v->params->{name} =~ /^P3RLC0DR$/, 'trim, strip and uppercase filters all applied'; my $w = MyVal->new(params => {name => ' p3rlc0dr '}); ok $w->params->{name} =~ /^P3RLC0DR$/, 'trim, strip and uppercase filters all applied'; filters000755000765000024 014410403624 23013 5ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression01-trim.t100644000765000024 44614410403624 24515 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/filtersuse Test::More tests => 1; # load module package MyVal; use Validation::Class; package main; my $v = MyVal->new( fields => {foobar => {filters => 'trim'}}, params => {foobar => ' 0011010101 '} ); ok $v->params->{foobar} =~ /^0011010101$/, 'trim filter working as expected'; Configuration.pm100644000765000024 1124714410403624 24713 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class# Configuration Class for Validation Classes # Validation::Class::Configuration provides a default configuration profile used # by validation classes and many class prototype methods. package Validation::Class::Configuration; use strict; use warnings; use Validation::Class::Directives; use Validation::Class::Listing; use Validation::Class::Mapping; use Validation::Class::Fields; use Validation::Class::Mixins; use Validation::Class::Util; use Module::Find 'usesub'; our $VERSION = '7.900059'; # VERSION sub attributes { my ($self) = @_; return $self->profile->{ATTRIBUTES}; } sub builders { my ($self) = @_; return $self->profile->{BUILDERS}; } sub configure_profile { my ($self) = @_; $self->configure_profile_register_directives; $self->configure_profile_register_filters; $self->configure_profile_register_events; return $self; } sub configure_profile_register_directives { my ($self) = @_; # automatically attach discovered directive classes my $directives = Validation::Class::Directives->new; foreach my $directive ($directives->values) { my $name = $directive->name; $self->directives->add($name => $directive); } return $self; } sub configure_profile_register_filters { my ($self) = @_; # automatically attach filters registered on in the filters directive my $directives = $self->directives; my $filters = $directives->get('filters'); return unless $filters; $self->filters->add($filters->registry); return $self; } sub configure_profile_register_events { my ($self) = @_; # inspect the directives for event subscriptions if (my @directives = ($self->directives->values)) { my $events = { # hookable events list, keyed by directive name 'on_after_validation' => {}, 'on_before_validation' => {}, 'on_normalize' => {}, 'on_validate' => {} }; while (my($name, $container) = each(%{$events})) { ($name) = $name =~ /^on_(\w+)/; foreach my $directive (@directives) { next if defined $container->{$name}; if (my $routine = $directive->can($name)) { $container->{$directive->name} = $routine; } } } $self->events->add($events); } return $self; } sub default_profile { my %default_mixins = ( ':flg' => Validation::Class::Mixin->new( required => 1, min_length => 1, filters => [qw/trim strip numeric/], between => [0, 1], name => ':flg', ), ':num' => Validation::Class::Mixin->new( required => 1, min_length => 1, filters => [qw/trim strip numeric/], name => ':num', ), ':str' => Validation::Class::Mixin->new( required => 1, min_length => 1, filters => [qw/trim strip/], name => ':str', ) ); return Validation::Class::Mapping->new({ ATTRIBUTES => Validation::Class::Mapping->new, BUILDERS => Validation::Class::Listing->new, DIRECTIVES => Validation::Class::Mapping->new, DOCUMENTS => Validation::Class::Mapping->new, EVENTS => Validation::Class::Mapping->new, FIELDS => Validation::Class::Fields->new, FILTERS => Validation::Class::Mapping->new, METHODS => Validation::Class::Mapping->new, MIXINS => Validation::Class::Mixins->new(%default_mixins), PROFILES => Validation::Class::Mapping->new, SETTINGS => Validation::Class::Mapping->new, }); } sub directives { my ($self) = @_; return $self->profile->{DIRECTIVES}; } sub documents { my ($self) = @_; return $self->profile->{DOCUMENTS}; } sub events { my ($self) = @_; return $self->profile->{EVENTS}; } sub fields { my ($self) = @_; return $self->profile->{FIELDS}; } sub filters { my ($self) = @_; return $self->profile->{FILTERS}; } sub methods { my ($self) = @_; return $self->profile->{METHODS}; } sub mixins { my ($self) = @_; return $self->profile->{MIXINS}; } sub new { my $self = bless {}, shift; $self->configure_profile; return $self; } sub profile { my ($self) = @_; return $self->{profile} ||= $self->default_profile; } sub profiles { my ($self) = @_; return $self->profile->{PROFILES}; } sub settings { my ($self) = @_; return $self->profile->{SETTINGS}; } 1; Directive000755000765000024 014410403624 23277 5ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/ClassSSN.pm100644000765000024 317114410403624 24442 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: SSN Directive for Validation Class Field Definitions package Validation::Class::Directive::SSN; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 0; has 'message' => '%s is not a valid social security number'; sub validate { my ($self, $proto, $field, $param) = @_; if (defined $field->{ssn} && defined $param) { if ($field->{required} || $param) { my $ssnre = qr/\A\b(?!000)[0-9]{3}-[0-9]{2}-[0-9]{4}\b\z/i; $self->error($proto, $field) unless $param =~ $ssnre; } } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::SSN - SSN Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { user_ssn => { ssn => 1 } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::SSN is a core validation class field directive that handles validation of social security numbers in the USA. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut 98-03-document-example-composition.t100644000765000024 323614410403624 24536 0ustar00christiaanstaff000000000000Validation-Class-7.900059/tuse utf8; use strict; use warnings; use Test::More; BEGIN { use FindBin; use lib $FindBin::Bin . '/lib'; } { package T; use Validation::Class; set roles => [ 'T::User', 'T::Location' ]; package main; my $class; eval { $class = T->new; }; ok "T" eq ref $class, "T instantiated"; my $documents = $class->prototype->documents; ok "Validation::Class::Mapping" eq ref $documents, "T documents hash registered as setting"; ok 2 == keys %{$documents}, "T has 2 registered document"; my $user = $documents->{'user'}; ok 7 == keys %{$user}, "T user document has 6 mappings"; can_ok $class, 'validate_document'; my $data = { "id" => 1234, "type" => "Master", "name" => "Root", "company" => "System, LLC", "login" => "root", "email" => "root\@localhost", "locations" => [ { "id" => 9876, "type" => "Node", "name" => "DevBox", "company" => "System, LLC", "address1" => "123 Street Road", "address2" => "Suite 2", "city" => "SINCITY", "state" => "NO", "zip" => "00000" } ] }; ok ! $class->validate_document(user => $data), "T document (user) not valid"; ok $class->errors_to_string =~ /locations\.0\.state/, "T proper error message set"; $class->prototype->documents->{'location'}->{state} = 'string'; ok $class->validate_document(user => $data), "T document (user) validated"; } done_testing; Introspect.pm100644000765000024 112114410403624 24730 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/myapp/lib/MyApppackage MyApp::Introspect; use Validation::Class; sub per_class { my ($self, $code) = @_; $self->proto->relatives->each(sub{ my ($alias, $namespace) = @_; # do something with each class $code->($namespace); }); } sub per_field_per_class { my ($self, $code) = @_; $self->per_class(sub{ my $namespace = shift; my $class = $namespace->new; foreach my $field (sort $class->fields->keys) { # do something with each field $code->($class, $class->fields->{$field}); } }); } 1; 02-alpha.t100644000765000024 44214410403624 24624 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/filtersuse Test::More tests => 1; # load module package MyVal; use Validation::Class; package main; my $v = MyVal->new( fields => {foobar => {filters => 'alpha'}}, params => {foobar => 'acb123def456xyz'} ); ok $v->params->{foobar} =~ /^acbdefxyz$/, 'alpha filter working as expected'; 04-strip.t100644000765000024 57414410403624 24710 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/filtersuse Test::More tests => 1; # load module package MyVal; use Validation::Class; package main; my $v = MyVal->new( fields => {foobar => {filters => 'strip'}}, params => { foobar => ' the quick brown fox jumped over the ...' } ); ok $v->params->{foobar} =~ /^the quick brown fox jumped over the ...$/, 'strip filter working as expected'; Time.pm100644000765000024 365514410403624 24704 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: Time Directive for Validation Class Field Definitions package Validation::Class::Directive::Time; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 0; has 'message' => '%s requires a valid time'; sub validate { my ($self, $proto, $field, $param) = @_; if (defined $field->{time} && defined $param) { if ($field->{required} || $param) { # determines if the param is a valid time # validates time as 24hr (HH:MM) or am/pm ([H]H:MM[a|p]m) # does not validate seconds my $tre = qr%^((0?[1-9]|1[012])(:[0-5]\d){0,2} ?([AP]M|[ap]m))$|^([01]\d|2[0-3])(:[0-5]\d){0,2}$%; $self->error($proto, $field) unless $param =~ $tre; } } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::Time - Time Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { creation_time => { time => 1 } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::Time is a core validation class field directive that handles validation for standard time formats. This directive respects the following time formats, 24hr (HH:MM) or am/pm ([H]H:MM[a|p]m) and does not validate seconds. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut City.pm100644000765000024 111230514410403624 24770 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: City Directive for Validation Class Field Definitions package Validation::Class::Directive::City; use utf8; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 0; has 'message' => '%s is not a valid US city'; has 'regexp' => sub {sprintf'^(%s)$',join'|',map{quotemeta}@{shift->cities}}; has 'cities' => sub {[ # u.s. cities and places 'Aaronsburg', 'Abbeville', 'Abbotsford', 'Abbott', 'Abbottstown', 'Abbyville', 'Abercrombie', 'Aberdeen', 'Aberdeen Gardens', 'Aberdeen Proving Ground', 'Abernathy', 'Abie', 'Abilene', 'Abingdon', 'Abington', 'Abita Springs', 'Abram-Perezville', 'Absarokee', 'Absecon', 'Accident', 'Accokeek', 'Accomac', 'Accord', 'Aceitunas', 'Acequia', 'Achille', 'Ackerly', 'Ackerman', 'Ackley', 'Ackworth', 'Acme', 'Acomita Lake', 'Acres Green', 'Acton', 'Acushnet Center', 'Acworth', 'Ada', 'Adair', 'Adair Village', 'Adairsville', 'Adairville', 'Adak', 'Adams', 'Adams Center', 'Adamsburg', 'Adamstown', 'Adamsville', 'Addieville', 'Addington', 'Addis', 'Addison', 'Addison (Webster Springs)', 'Addyston', 'Adel', 'Adelanto', 'Adeline', 'Adell', 'Adelphi', 'Adena', 'Adjuntas', 'Admire', 'Adona', 'Adrian', 'Advance', 'Adwolf', 'Affton', 'Afton', 'Agar', 'Agawam', 'Agency', 'Agenda', 'Agoura Hills', 'Agra', 'Agua Dulce', 'Agua Fria', 'Aguada', 'Aguadilla', 'Aguas Buenas', 'Aguas Claras', 'Aguilar', 'Aguilita', 'Ahmeek', 'Ahoskie', 'Ahtanum', 'Ahuimanu', 'Aibonito', 'Aiea', 'Aiken', 'Ailey', 'Ainaloa', 'Ainsworth', 'Air Force Academy', 'Airmont', 'Airport Drive', 'Airport Road', 'Airport Road Addition', 'Airway Heights', 'Aitkin', 'Ajo', 'Ak-Chin Village', 'Akaska', 'Akeley', 'Akhiok', 'Akiachak', 'Akiak', 'Akins', 'Akron', 'Akutan', 'Alabaster', 'Alachua', 'Alakanuk', 'Alamance', 'Alameda', 'Alamo', 'Alamo Heights', 'Alamogordo', 'Alamosa', 'Alamosa East', 'Alanson', 'Alapaha', 'Alatna', 'Alba', 'Albany', 'Albee', 'Albemarle', 'Albers', 'Albert', 'Albert City', 'Albert Lea', 'Alberta', 'Alberton', 'Albertson', 'Albertville', 'Albia', 'Albin', 'Albion', 'Albright', 'Albuquerque', 'Alburg', 'Alburnett', 'Alburtis', 'Alcalde', 'Alcan Border', 'Alcester', 'Alcoa', 'Alcova', 'Alda', 'Aldan', 'Alden', 'Alder', 'Alderson', 'Alderwood Manor', 'Aldine', 'Aldora', 'Aldrich', 'Aledo', 'Aleknagik', 'Aleneva', 'Alex', 'Alexander', 'Alexander City', 'Alexandria', 'Alexandria Bay', 'Alexis', 'Alford', 'Alfordsville', 'Alfred', 'Alfred-South La Paloma', 'Alger', 'Algodones', 'Algoma', 'Algona', 'Algonac', 'Algonquin', 'Algood', 'Alhambra', 'Alice', 'Alice Acres', 'Aliceville', 'Alicia', 'Aline', 'Aliquippa', 'Aliso Viejo', 'Allakaket', 'Allamuchy-Panther Valley', 'Allardt', 'Allegan', 'Allegany', 'Alleman', 'Allen', 'Allen Park', 'Allendale', 'Allenhurst', 'Allenport', 'Allenspark', 'Allensville', 'Allentown', 'Allenville', 'Allenwood', 'Allerton', 'Allgood', 'Alliance', 'Alligator', 'Allison', 'Allouez', 'Alloway', 'Allport', 'Allyn-Grapeview', 'Alma', 'Alma Center', 'Almanor', 'Almedia', 'Almena', 'Almira', 'Almond', 'Almont', 'Almyra', 'Aloha', 'Alondra Park', 'Alorton', 'Alpaugh', 'Alpena', 'Alpha', 'Alpharetta', 'Alpine', 'Alpine Northeast', 'Alpine Northwest', 'Alpine Village', 'Alsen', 'Alsey', 'Alsip', 'Alston', 'Alta', 'Alta Sierra', 'Alta Vista', 'Altadena', 'Altamahaw-Ossipee', 'Altamont', 'Altamonte Springs', 'Altavista', 'Altenburg', 'Altha', 'Altheimer', 'Altmar', 'Alto', 'Alto Bonito', 'Alto Pass', 'Alton', 'Alton North', 'Altona', 'Altoona', 'Altura', 'Alturas', 'Altus', 'Alum Creek', 'Alum Rock', 'Alva', 'Alvarado', 'Alvin', 'Alvo', 'Alvord', 'Alvordton', 'Ama', 'Amado', 'Amador City', 'Amagansett', 'Amagon', 'Amalga', 'Amanda', 'Amarillo', 'Amazonia', 'Amber', 'Amberley', 'Ambia', 'Ambler', 'Amboy', 'Ambridge', 'Ambrose', 'Amelia', 'Amenia', 'American Canyon', 'American Falls', 'American Fork', 'Americus', 'Amery', 'Ames', 'Ames Lake', 'Amesbury', 'Amesti', 'Amesville', 'Amherst', 'Amherst Center', 'Amherst Junction', 'Amherstdale-Robinette', 'Amidon', 'Amite City', 'Amity', 'Amity Gardens', 'Amityville', 'Ammon', 'Amo', 'Amoret', 'Amorita', 'Amory', 'Amsterdam', 'Amsterdam-Churchill', 'Anacoco', 'Anaconda', 'Anacortes', 'Anadarko', 'Anaheim', 'Anahola', 'Anahuac', 'Anaktuvuk Pass', 'Anamoose', 'Anamosa', 'Anawalt', 'Anchor', 'Anchor Point', 'Anchorage', 'Ancient Oaks', 'Andale', 'Andalusia', 'Anderson', 'Anderson Mill', 'Andersonville', 'Andes', 'Andover', 'Andrew', 'Andrews', 'Andrews AFB', 'Aneta', 'Aneth', 'Angel Fire', 'Angelica', 'Angels City', 'Angie', 'Angier', 'Angleton', 'Angola', 'Angola on the Lake', 'Angoon', 'Anguilla', 'Angus', 'Angwin', 'Aniak', 'Animas', 'Anita', 'Aniwa', 'Ankeny', 'Anmoore', 'Ann Arbor', 'Anna', 'Anna Maria', 'Annabella', 'Annada', 'Annandale', 'Annapolis', 'Annawan', 'Annetta', 'Annetta North', 'Annetta South', 'Anniston', 'Annona', 'Annville', 'Anoka', 'Anselmo', 'Ansley', 'Anson', 'Ansonia', 'Ansonville', 'Ansted', 'Antelope', 'Antelope Hills', 'Antelope Valley-Crestview', 'Anthon', 'Anthony', 'Anthonyville', 'Antigo', 'Antimony', 'Antioch', 'Antler', 'Antlers', 'Antoine', 'Anton', 'Antonito', 'Antreville', 'Antrim', 'Antwerp', 'Antón Ruíz', 'Anvik', 'Apache', 'Apache Junction', 'Apalachicola', 'Apalachin', 'Apex', 'Aplington', 'Apollo', 'Apollo Beach', 'Apopka', 'Appalachia', 'Apple Creek', 'Apple River', 'Apple Valley', 'Appleby', 'Applegate', 'Appleton', 'Appleton City', 'Applewold', 'Applewood', 'Appomattox', 'Aptos', 'Aptos Hills-Larkin Valley', 'Aquebogue', 'Aquia Harbour', 'Aquilla', 'Arab', 'Arabi', 'Aragon', 'Aransas Pass', 'Arapaho', 'Arapahoe', 'Arbela', 'Arboles', 'Arbon Valley', 'Arbuckle', 'Arbutus', 'Arbyrd', 'Arcade', 'Arcadia', 'Arcadia Lakes', 'Arcanum', 'Arcata', 'Archbald', 'Archbold', 'Archdale', 'Archer', 'Archer City', 'Archie', 'Arco', 'Arcola', 'Arctic Village', 'Arden', 'Arden Hills', 'Arden-Arcade', 'Arden-on-the-Severn', 'Ardencroft', 'Ardentown', 'Ardmore', 'Ardoch', 'Ardsley', 'Arecibo', 'Aredale', 'Arena', 'Arendtsville', 'Arenzville', 'Argenta', 'Argentine', 'Argo', 'Argonia', 'Argos', 'Argusville', 'Argyle', 'Arial', 'Arimo', 'Arion', 'Arispe', 'Aristes', 'Aristocrat Ranchettes', 'Ariton', 'Arizona City', 'Arizona Village', 'Arkadelphia', 'Arkansas City', 'Arkoe', 'Arkoma', 'Arkport', 'Arlee', 'Arley', 'Arlington', 'Arlington Heights', 'Arma', 'Armada', 'Armagh', 'Armington', 'Armona', 'Armonk', 'Armour', 'Armstrong', 'Arnaudville', 'Arnegard', 'Arnett', 'Arnold', 'Arnolds Park', 'Arnoldsville', 'Aroma Park', 'Aromas', 'Arona', 'Arp', 'Arpin', 'Arriba', 'Arrow Point', 'Arrow Rock', 'Arrowhead Springs', 'Arrowsmith', 'Arroyo', 'Arroyo Alto', 'Arroyo Colorado Estates', 'Arroyo Gardens-La Tina Ranch', 'Arroyo Grande', 'Artas', 'Artesia', 'Artesian', 'Arthur', 'Artondale', 'Arvada', 'Arvin', 'Asbury', 'Asbury Lake', 'Asbury Park', 'Ash Flat', 'Ash Fork', 'Ash Grove', 'Asharoken', 'Ashaway', 'Ashburn', 'Ashby', 'Ashdown', 'Asheboro', 'Asher', 'Asherton', 'Asheville', 'Ashford', 'Ashkum', 'Ashland', 'Ashland City', 'Ashland Heights', 'Ashley', 'Ashley Heights', 'Ashmore', 'Ashtabula', 'Ashton', 'Ashton-Sandy Spring', 'Ashville', 'Ashwaubenon', 'Askewville', 'Askov', 'Asotin', 'Aspen', 'Aspen Hill', 'Aspen Park', 'Aspermont', 'Aspinwall', 'Assaria', 'Assumption', 'Astatula', 'Astor', 'Astoria', 'Atalissa', 'Atascadero', 'Atascocita', 'Atchison', 'Atglen', 'Athalia', 'Athelstan', 'Athena', 'Athens', 'Atherton', 'Athol', 'Atka', 'Atkins', 'Atkinson', 'Atlanta', 'Atlantic', 'Atlantic Beach', 'Atlantic City', 'Atlantic Highlands', 'Atlantis', 'Atmautluak', 'Atmore', 'Atoka', 'Atomic City', 'Atqasuk', 'Attalla', 'Attapulgus', 'Attica', 'Attleboro', 'Attu Station', 'Atwater', 'Atwood', 'Au Gres', 'Au Sable', 'Au Sable Forks', 'Auberry', 'Aubrey', 'Auburn', 'Auburn Hills', 'Auburndale', 'Auburntown', 'Audubon', 'Audubon Park', 'August', 'Augusta', 'Aulander', 'Aullville', 'Ault', 'Ault Field', 'Aumsville', 'Aurelia', 'Aurora', 'Aurora Center', 'Austell', 'Austin', 'Austintown', 'Austwell', 'Autaugaville', 'Autryville', 'Auxvasse', 'Ava', 'Avalon', 'Avant', 'Avard', 'Avenal', 'Avenel', 'Aventura', 'Avera', 'Averill Park', 'Avery', 'Avery Creek', 'Avilla', 'Avinger', 'Avis', 'Aviston', 'Avoca', 'Avocado Heights', 'Avon', 'Avon Lake', 'Avon Park', 'Avon-by-the-Sea', 'Avondale', 'Avondale Estates', 'Avonia', 'Avonmore', 'Avra Valley', 'Awendaw', 'Axtell', 'Ayden', 'Ayer', 'Aynor', 'Ayr', 'Ayrshire', 'Azalea Park', 'Azle', 'Aztec', 'Azure', 'Azusa', 'Añasco', 'Babbie', 'Babbitt', 'Babson Park', 'Babylon', 'Back Mountain', 'Backus', 'Bacliff', 'Baconton', 'Bad Axe', 'Baden', 'Badger', 'Badin', 'Bagdad', 'Baggs', 'Bagley', 'Bagnell', 'Baidland', 'Bailey', 'Bailey Lakes', 'Bailey\'s Crossroads', 'Bailey\'s Prairie', 'Baileyton', 'Bainbridge', 'Bainbridge Island', 'Bainville', 'Baird', 'Bairdstown', 'Bairoa', 'Bairoil', 'Baiting Hollow', 'Bajadero', 'Bajandas', 'Baker', 'Baker City', 'Bakersfield', 'Bakersville', 'Bal Harbour', 'Balaton', 'Balch Springs', 'Balcones Heights', 'Bald Head Island', 'Bald Knob', 'Baldwin', 'Baldwin City', 'Baldwin Harbor', 'Baldwin Park', 'Baldwinsville', 'Baldwinville', 'Baldwyn', 'Balfour', 'Ball', 'Ball Ground', 'Ballantine', 'Ballard', 'Ballenger Creek', 'Ballinger', 'Ballou', 'Ballston Spa', 'Balltown', 'Ballville', 'Ballwin', 'Bally', 'Balmorhea', 'Balmville', 'Balsam Lake', 'Balta', 'Baltic', 'Baltimore', 'Bamberg', 'Bancroft', 'Bandera', 'Bandon', 'Baneberry', 'Bangor', 'Bangor Trident Base', 'Bangs', 'Banks', 'Banks Lake South', 'Bankston', 'Banner', 'Banner Elk', 'Banner Hill', 'Banning', 'Bannockburn', 'Bantam', 'Bantry', 'Bar Harbor', 'Bar Nunn', 'Baraboo', 'Barada', 'Baraga', 'Barahona', 'Barataria', 'Barbers Point Housing', 'Barberton', 'Barbourmeade', 'Barboursville', 'Barbourville', 'Barceloneta', 'Barclay', 'Barclay-Kingston', 'Bardolph', 'Bardonia', 'Bardstown', 'Bardwell', 'Bargersville', 'Baring', 'Barker', 'Barker Heights', 'Barker Ten Mile', 'Barkeyville', 'Barling', 'Barlow', 'Barnard', 'Barnegat', 'Barnegat Light', 'Barnes', 'Barnes City', 'Barnes Lake-Millers Lake', 'Barneston', 'Barnesville', 'Barnett', 'Barneveld', 'Barney', 'Barnhart', 'Barnhill', 'Barnsdall', 'Barnstable Town', 'Barnum', 'Barnum Island', 'Barnwell', 'Baroda', 'Barrackville', 'Barranquitas', 'Barre', 'Barrett', 'Barrington', 'Barrington Hills', 'Barron', 'Barrow', 'Barry', 'Barryton', 'Barstow', 'Bartelso', 'Bartlesville', 'Bartlett', 'Bartley', 'Bartolo', 'Barton', 'Barton Creek', 'Barton Hills', 'Bartonville', 'Bartow', 'Barview', 'Barwick', 'Basalt', 'Basco', 'Bascom', 'Basehor', 'Basile', 'Basin', 'Basin City', 'Baskin', 'Bass Lake', 'Bassett', 'Bassfield', 'Bastrop', 'Basye-Bryce Mountain', 'Batavia', 'Batchtown', 'Bates City', 'Batesburg-Leesville', 'Batesland', 'Batesville', 'Bath', 'Bath (Berkeley Springs)', 'Bathgate', 'Baton Rouge', 'Battle Creek', 'Battle Ground', 'Battle Lake', 'Battle Mountain', 'Battlefield', 'Battlement Mesa', 'Baudette', 'Bausell and Ellis', 'Bauxite', 'Baxley', 'Baxter', 'Baxter Estates', 'Baxter Springs', 'Bay', 'Bay Center', 'Bay City', 'Bay Harbor Islands', 'Bay Head', 'Bay Hill', 'Bay Lake', 'Bay Minette', 'Bay Park', 'Bay Pines', 'Bay Point', 'Bay Shore', 'Bay Springs', 'Bay St. Louis', 'Bay View', 'Bay View Gardens', 'Bay Village', 'Bayamón', 'Bayard', 'Bayboro', 'Bayfield', 'Baylis', 'Bayonet Point', 'Bayonne', 'Bayou Cane', 'Bayou Gauche', 'Bayou La Batre', 'Bayou Vista', 'Bayport', 'Bayshore', 'Bayshore Gardens', 'Bayside', 'Baytown', 'Bayview', 'Bayview-Montalvin', 'Bayville', 'Baywood', 'Baywood-Los Osos', 'Bazile Mills', 'Bazine', 'Beach', 'Beach City', 'Beach Haven', 'Beach Haven West', 'Beach Park', 'Beachwood', 'Beacon', 'Beacon Square', 'Beaconsfield', 'Beal City', 'Beale AFB', 'Beallsville', 'Beaman', 'Bear', 'Bear Creek', 'Bear Creek Village', 'Bear Lake', 'Bear River City', 'Bear Valley', 'Bear Valley Springs', 'Bearcreek', 'Bearden', 'Beardsley', 'Beardstown', 'Beargrass', 'Beasley', 'Beatrice', 'Beattie', 'Beatty', 'Beattyville', 'Beatyestown', 'Beaufort', 'Beaumont', 'Beauregard', 'Beaux Arts Village', 'Beaver', 'Beaver Bay', 'Beaver City', 'Beaver Creek', 'Beaver Crossing', 'Beaver Dam', 'Beaver Falls', 'Beaver Meadows', 'Beaver Springs', 'Beavercreek', 'Beaverdale-Lloydell', 'Beaverdam', 'Beaverdam Lake-Salisbury Mills', 'Beaverton', 'Beavertown', 'Beaverville', 'Bechtelsville', 'Beckemeyer', 'Becker', 'Beckett', 'Beckett Ridge', 'Beckley', 'Beckville', 'Beckwourth', 'Beclabito', 'Bedford', 'Bedford Heights', 'Bedford Park', 'Bee', 'Bee Cave', 'Bee Ridge', 'Beebe', 'Beech Bottom', 'Beech Creek', 'Beech Grove', 'Beech Mountain', 'Beecher', 'Beecher City', 'Beechwood', 'Beechwood Trails', 'Beechwood Village', 'Beedeville', 'Beemer', 'Beersheba Springs', 'Beeville', 'Beggs', 'Bejou', 'Bel Air', 'Bel Air North', 'Bel Air South', 'Bel Aire', 'Bel-Nor', 'Bel-Ridge', 'Belcher', 'Belchertown', 'Belcourt', 'Belden', 'Belding', 'Belen', 'Belfast', 'Belfield', 'Belfonte', 'Belford', 'Belfry', 'Belgium', 'Belgrade', 'Belhaven', 'Belington', 'Belk', 'Belknap', 'Bell', 'Bell Acres', 'Bell Buckle', 'Bell Center', 'Bell City', 'Bell Gardens', 'Bell Hill', 'Bella Villa', 'Bella Vista', 'Bellair-Meadowbrook Terrace', 'Bellaire', 'Bellbrook', 'Belle', 'Belle Center', 'Belle Chasse', 'Belle Fourche', 'Belle Glade', 'Belle Glade Camp', 'Belle Haven', 'Belle Isle', 'Belle Meade', 'Belle Plaine', 'Belle Prairie City', 'Belle Rive', 'Belle Rose', 'Belle Terre', 'Belle Valley', 'Belle Vernon', 'Belleair', 'Belleair Beach', 'Belleair Bluffs', 'Belleair Shore', 'Bellechester', 'Bellefontaine', 'Bellefontaine Neighbors', 'Bellefonte', 'Bellemeade', 'Bellerive', 'Bellerose', 'Bellerose Terrace', 'Belleview', 'Belleville', 'Bellevue', 'Bellevue Town', 'Bellewood', 'Bellflower', 'Bellingham', 'Bellmawr', 'Bellmead', 'Bellmont', 'Bellmore', 'Bellows Falls', 'Bellport', 'Bells', 'Bellview', 'Bellville', 'Bellwood', 'Belmar', 'Belmond', 'Belmont', 'Belmore', 'Beloit', 'Belpre', 'Belt', 'Belton', 'Beltrami', 'Beltsville', 'Beluga', 'Belvedere', 'Belvedere Park', 'Belvidere', 'Belview', 'Belville', 'Belvue', 'Belwood', 'Belzoni', 'Bement', 'Bemidji', 'Bemus Point', 'Ben Avon', 'Ben Avon Heights', 'Ben Lomond', 'Bena', 'Benavides', 'Benbrook', 'Bend', 'Bendersville', 'Bendersville Station-Aspers', 'Benedict', 'Benham', 'Benicia', 'Benjamin', 'Benkelman', 'Benld', 'Bennet', 'Bennett', 'Bennettsville', 'Bennington', 'Bennsville', 'Benoit', 'Bensenville', 'Bensley', 'Benson', 'Bent Creek', 'Bentley', 'Bentleyville', 'Benton', 'Benton City', 'Benton Harbor', 'Benton Heights', 'Benton Ridge', 'Bentonia', 'Bentonville', 'Benwood', 'Benzonia', 'Benítez', 'Berea', 'Beresford', 'Bergen', 'Bergenfield', 'Berger', 'Bergholz', 'Bergman', 'Berkeley', 'Berkeley Heights', 'Berkeley Lake', 'Berkey', 'Berkley', 'Berlin', 'Berlin Heights', 'Bermuda Dunes', 'Bermuda Run', 'Bern', 'Bernalillo', 'Bernard', 'Bernardsville', 'Berne', 'Bernice', 'Bernie', 'Bernville', 'Berrien Springs', 'Berry', 'Berry Hill', 'Berrysburg', 'Berryville', 'Bertha', 'Berthold', 'Berthoud', 'Bertram', 'Bertrand', 'Bertsch-Oceanview', 'Berwick', 'Berwyn', 'Berwyn Heights', 'Bessemer', 'Bessemer Bend', 'Bessemer City', 'Bessie', 'Betances', 'Bethalto', 'Bethania', 'Bethany', 'Bethany Beach', 'Bethel', 'Bethel Acres', 'Bethel Heights', 'Bethel Island', 'Bethel Park', 'Bethel Springs', 'Bethesda', 'Bethlehem', 'Bethlehem Village', 'Bethpage', 'Bethune', 'Bettendorf', 'Betterton', 'Bettles', 'Bettsville', 'Between', 'Beulah', 'Beulah Valley', 'Beulaville', 'Beurys Lake', 'Beverly', 'Beverly Beach', 'Beverly Hills', 'Beverly Shores', 'Bevier', 'Bevil Oaks', 'Bevington', 'Bexley', 'Bibb City', 'Bickleton', 'Bicknell', 'Biddeford', 'Biehle', 'Bienville', 'Big Arm', 'Big Bay', 'Big Bear City', 'Big Bear Lake', 'Big Beaver', 'Big Bend', 'Big Cabin', 'Big Coppitt Key', 'Big Creek', 'Big Delta', 'Big Falls', 'Big Flat', 'Big Flats', 'Big Flats Airport', 'Big Horn', 'Big Lake', 'Big Park', 'Big Pine', 'Big Pine Key', 'Big Piney', 'Big Point', 'Big Rapids', 'Big River', 'Big Run', 'Big Sandy', 'Big Sky', 'Big Spring', 'Big Springs', 'Big Stone City', 'Big Stone Gap', 'Big Timber', 'Big Water', 'Big Wells', 'Bigelow', 'Bigfoot', 'Bigfork', 'Biggers', 'Biggs', 'Biggs Junction', 'Biggsville', 'Biglerville', 'Billings', 'Billingsley', 'Billington Heights', 'Biloxi', 'Biltmore Forest', 'Binford', 'Bingen', 'Binger', 'Bingham', 'Bingham Farms', 'Bingham Lake', 'Binghamton', 'Biola', 'Birch Bay', 'Birch Creek', 'Birch Run', 'Birch Tree', 'Birchwood', 'Birchwood Village', 'Bird City', 'Bird Island', 'Birds', 'Birdsboro', 'Birdseye', 'Birdsong', 'Birmingham', 'Birnamwood', 'Birney', 'Biron', 'Bisbee', 'Biscay', 'Biscayne Park', 'Biscoe', 'Bishop', 'Bishop Hill', 'Bishop Hills', 'Bishopville', 'Bismarck', 'Bison', 'Bithlo', 'Bitter Springs', 'Biwabik', 'Bixby', 'Black', 'Black Canyon City', 'Black Creek', 'Black Diamond', 'Black Eagle', 'Black Earth', 'Black Forest', 'Black Hawk', 'Black Jack', 'Black Lick', 'Black Mountain', 'Black Oak', 'Black Point-Green Point', 'Black River', 'Black River Falls', 'Black Rock', 'Black Springs', 'Blackburn', 'Blackduck', 'Blackey', 'Blackfoot', 'Blackhawk', 'Blackhawk-Camino Tassajara', 'Blacklick Estates', 'Blacksburg', 'Blackshear', 'Blackstone', 'Blacksville', 'Blackville', 'Blackwater', 'Blackwell', 'Blackwood', 'Bladen', 'Bladenboro', 'Bladensburg', 'Blades', 'Blain', 'Blaine', 'Blair', 'Blairsburg', 'Blairsden', 'Blairstown', 'Blairsville', 'Blakely', 'Blakesburg', 'Blakeslee', 'Blanca', 'Blanchard', 'Blanchardville', 'Blanchester', 'Blanco', 'Bland', 'Blanding', 'Blandinsville', 'Blandville', 'Blanket', 'Blasdell', 'Blauvelt', 'Blawnox', 'Blencoe', 'Blenheim', 'Blennerhassett', 'Blessing', 'Blevins', 'Bliss', 'Bliss Corner', 'Blissfield', 'Blockton', 'Blodgett', 'Blomkest', 'Bloomburg', 'Bloomdale', 'Bloomer', 'Bloomfield', 'Bloomfield Hills', 'Bloomfield Township', 'Blooming Grove', 'Blooming Prairie', 'Blooming Valley', 'Bloomingburg', 'Bloomingdale', 'Bloomington', 'Bloomsburg', 'Bloomsbury', 'Bloomsdale', 'Bloomville', 'Blossburg', 'Blossom', 'Blountstown', 'Blountsville', 'Blountville', 'Blowing Rock', 'Bloxom', 'Blue Ash', 'Blue Bell', 'Blue Berry Hill', 'Blue Diamond', 'Blue Earth', 'Blue Eye', 'Blue Grass', 'Blue Hill', 'Blue Hills', 'Blue Island', 'Blue Lake', 'Blue Mound', 'Blue Mounds', 'Blue Mountain', 'Blue Point', 'Blue Rapids', 'Blue Ridge', 'Blue Ridge Manor', 'Blue River', 'Blue Springs', 'Bluefield', 'Bluejacket', 'Bluetown-Iglesia Antigua', 'Bluewater', 'Bluff', 'Bluff City', 'Bluffdale', 'Bluffs', 'Bluffton', 'Bluford', 'Blum', 'Blunt', 'Blyn', 'Blythe', 'Blythedale', 'Blytheville', 'Blythewood', 'Boalsburg', 'Boardman', 'Boaz', 'Boca Del Mar', 'Boca Pointe', 'Boca Raton', 'Bock', 'Bodcaw', 'Bode', 'Bodega Bay', 'Bodfish', 'Boerne', 'Bogalusa', 'Bogard', 'Bogart', 'Bogata', 'Boger City', 'Bogota', 'Bogue', 'Bogue Chitto', 'Bohemia', 'Bohners Lake', 'Boiling Spring Lakes', 'Boiling Springs', 'Boise City', 'Bokchito', 'Bokeelia', 'Bokoshe', 'Bolckow', 'Boles Acres', 'Boley', 'Boligee', 'Bolinas', 'Bolindale', 'Boling-Iago', 'Bolingbrook', 'Bolivar', 'Bolivar Peninsula', 'Bolivia', 'Bolton', 'Bombay Beach', 'Bon Air', 'Bonadelle Ranchos-Madera Ranchos', 'Bonanza', 'Bonaparte', 'Bondsville', 'Bonduel', 'Bondurant', 'Bondville', 'Bone Gap', 'Boneau', 'Bonesteel', 'Bonfield', 'Bonham', 'Bonifay', 'Bonita', 'Bonita Springs', 'Bonne Terre', 'Bonneau', 'Bonneauville', 'Bonner Springs', 'Bonner-West Riverside', 'Bonners Ferry', 'Bonnetsville', 'Bonney', 'Bonney Lake', 'Bonnie', 'Bonnie Lock-Woodsetter North', 'Bonnieville', 'Bono', 'Bonsall', 'Booker', 'Boone', 'Boones Mill', 'Booneville', 'Boonsboro', 'Boonton', 'Boonville', 'Boothbay Harbor', 'Boothville-Venice', 'Boothwyn', 'Bootjack', 'Boqueron', 'Boquerón', 'Borden', 'Bordentown', 'Borger', 'Boron', 'Boronda', 'Borrego Springs', 'Borup', 'Boscobel', 'Bosque Farms', 'Bossier City', 'Bostic', 'Boston', 'Boston Heights', 'Bostonia', 'Bostwick', 'Boswell', 'Bosworth', 'Bothell', 'Botines', 'Botkins', 'Bottineau', 'Boulder', 'Boulder City', 'Boulder Creek', 'Boulder Flats', 'Boulder Hill', 'Boulevard Gardens', 'Bound Brook', 'Bountiful', 'Bourbon', 'Bourbonnais', 'Bourne', 'Bouse', 'Bouton', 'Boutte', 'Bovey', 'Bovill', 'Bovina', 'Bow Mar', 'Bowbells', 'Bowdle', 'Bowdon', 'Bowen', 'Bowers', 'Bowerston', 'Bowersville', 'Bowie', 'Bowlegs', 'Bowler', 'Bowles', 'Bowleys Quarters', 'Bowling Green', 'Bowlus', 'Bowman', 'Bowmanstown', 'Bowmore', 'Box Canyon-Amistad', 'Box Elder', 'Boxford', 'Boxholm', 'Boy River', 'Boyce', 'Boyceville', 'Boyd', 'Boyden', 'Boydton', 'Boyertown', 'Boyes Hot Springs', 'Boyette', 'Boykins', 'Boyle', 'Boyne City', 'Boyne Falls', 'Boynton', 'Boynton Beach', 'Boys Town', 'Bozeman', 'Braceville', 'Brackenridge', 'Brackettville', 'Bradbury', 'Braddock', 'Braddock Heights', 'Braddock Hills', 'Braddyville', 'Braden', 'Bradenton', 'Bradenton Beach', 'Bradford', 'Bradfordsville', 'Bradfordwoods', 'Bradgate', 'Bradley', 'Bradley Beach', 'Bradner', 'Bradshaw', 'Brady', 'Brady Lake', 'Bragg City', 'Braggs', 'Braham', 'Braidwood', 'Brainard', 'Brainerd', 'Braintree', 'Braman', 'Bramwell', 'Branch', 'Branchdale', 'Branchville', 'Brandenburg', 'Brandon', 'Brandonville', 'Brandsville', 'Brandt', 'Brandywine', 'Branford', 'Branford Center', 'Branson', 'Branson West', 'Brantley', 'Braselton', 'Brashear', 'Brasher Falls-Winthrop', 'Brass Castle', 'Braswell', 'Bratenahl', 'Brattleboro', 'Brawley', 'Braxton', 'Bray', 'Braymer', 'Brayton', 'Brazil', 'Brazoria', 'Brea', 'Breaux Bridge', 'Breckenridge', 'Breckenridge Hills', 'Breckinridge Center', 'Brecksville', 'Breda', 'Breedsville', 'Breese', 'Breezy Point', 'Bremen', 'Bremerton', 'Bremond', 'Brenham', 'Brent', 'Brentford', 'Brentwood', 'Bressler-Enhaut-Oberlin', 'Bret Harte', 'Brevard', 'Brevig Mission', 'Brewer', 'Brewerton', 'Brewster', 'Brewster Hill', 'Brewton', 'Breñas', 'Brian Head', 'Briar', 'Briar Creek', 'Briarcliff', 'Briarcliff Manor', 'Briarcliffe Acres', 'Briaroaks', 'Briarwood', 'Brice', 'Brice Prairie', 'Bricelyn', 'Brices Creek', 'Brickerville', 'Bridge City', 'Bridgehampton', 'Bridgeport', 'Bridger', 'Bridgeton', 'Bridgetown North', 'Bridgeview', 'Bridgeville', 'Bridgewater', 'Bridgman', 'Bridgton', 'Brielle', 'Brier', 'Brigantine', 'Briggs', 'Brigham City', 'Bright', 'Brighton', 'Brightwaters', 'Brilliant', 'Brillion', 'Brimfield', 'Brimhall Nizhoni', 'Brimson', 'Brinckerhoff', 'Brinkley', 'Brinnon', 'Brinsmade', 'Brinson', 'Briny Breezes', 'Brisbane', 'Brisbin', 'Bristol', 'Bristow', 'Britt', 'Brittany Farms-Highlands', 'Britton', 'Broad Brook', 'Broad Fields', 'Broad Top City', 'Broadalbin', 'Broaddus', 'Broadland', 'Broadlands', 'Broadmoor', 'Broadus', 'Broadview', 'Broadview Heights', 'Broadview Park', 'Broadview-Pompano Park', 'Broadwater', 'Broadway', 'Broadwell', 'Brock', 'Brocket', 'Brockport', 'Brockton', 'Brockway', 'Brocton', 'Brodhead', 'Brodheadsville', 'Brodnax', 'Broeck Pointe', 'Brogden', 'Brokaw', 'Broken Arrow', 'Broken Bow', 'Bromide', 'Bromley', 'Bronaugh', 'Bronson', 'Bronte', 'Bronwood', 'Bronxville', 'Brook', 'Brook Park', 'Brookdale', 'Brooker', 'Brookeville', 'Brookfield', 'Brookfield Center', 'Brookford', 'Brookhaven', 'Brookhurst', 'Brookings', 'Brookland', 'Brooklawn', 'Brooklet', 'Brookline', 'Brooklyn', 'Brooklyn Center', 'Brooklyn Heights', 'Brooklyn Park', 'Brookmont', 'Brookneal', 'Brookport', 'Brookridge', 'Brooks', 'Brooksburg', 'Brookshire', 'Brookside', 'Brookside Village', 'Brookston', 'Brooksville', 'Brookview', 'Brookville', 'Brookwood', 'Broomall', 'Broomfield', 'Brooten', 'Broughton', 'Broussard', 'Broward Estates', 'Browerville', 'Brown City', 'Brown Deer', 'Browndell', 'Brownell', 'Brownfield', 'Brownfields', 'Browning', 'Brownington', 'Brownlee Park', 'Browns', 'Browns Lake', 'Browns Mills', 'Browns Valley', 'Brownsboro', 'Brownsboro Farm', 'Brownsboro Village', 'Brownsburg', 'Brownsdale', 'Brownstown', 'Brownsville', 'Brownsville-Bawcomville', 'Brownton', 'Browntown', 'Brownville', 'Brownwood', 'Broxton', 'Bruce', 'Bruceton', 'Bruceton Mills', 'Bruceville', 'Bruceville-Eddy', 'Bruin', 'Brule', 'Brumley', 'Brundage', 'Brundidge', 'Bruni', 'Bruning', 'Bruno', 'Brunson', 'Brunsville', 'Brunswick', 'Brunswick Station', 'Brush', 'Brush Creek', 'Brush Prairie', 'Brushton', 'Brushy', 'Brushy Creek', 'Brusly', 'Brussels', 'Bryan', 'Bryans Road', 'Bryant', 'Bryceland', 'Bryn Athyn', 'Bryn Mawr', 'Bryn Mawr-Skyway', 'Bryson', 'Bryson City', 'Buchanan', 'Buchanan Dam', 'Buchtel', 'Buck Grove', 'Buck Run', 'Buckeye', 'Buckeye Lake', 'Buckhannon', 'Buckhead', 'Buckhead Ridge', 'Buckholts', 'Buckhorn', 'Buckingham', 'Buckland', 'Buckley', 'Bucklin', 'Buckman', 'Buckner', 'Bucks Lake', 'Bucksport', 'Bucoda', 'Bucyrus', 'Buda', 'Budd Lake', 'Bude', 'Buechel', 'Buellton', 'Buena', 'Buena Park', 'Buena Vista', 'Buffalo', 'Buffalo Center', 'Buffalo City', 'Buffalo Gap', 'Buffalo Grove', 'Buffalo Lake', 'Buffalo Soapstone', 'Buffalo Springs', 'Buford', 'Buhl', 'Buhler', 'Buies Creek', 'Bull Creek', 'Bull Hollow', 'Bull Run', 'Bull Shoals', 'Bull Valley', 'Bullard', 'Bullhead', 'Bullhead City', 'Bulls Gap', 'Bulpitt', 'Bulverde', 'Buna', 'Bunceton', 'Bunche Park', 'Buncombe', 'Bunker', 'Bunker Hill', 'Bunker Hill Village', 'Bunkerville', 'Bunkie', 'Bunn', 'Bunnell', 'Buras-Triumph', 'Burbank', 'Burchard', 'Burden', 'Burdett', 'Burdette', 'Bureau Junction', 'Burgaw', 'Burgess', 'Burgettstown', 'Burgin', 'Burgoon', 'Burien', 'Burkburnett', 'Burke', 'Burkesville', 'Burket', 'Burkettsville', 'Burkeville', 'Burkittsville', 'Burleson', 'Burley', 'Burlingame', 'Burlington', 'Burlington Junction', 'Burlison', 'Burnet', 'Burnettown', 'Burnettsville', 'Burney', 'Burnham', 'Burns', 'Burns Flat', 'Burns Harbor', 'Burnside', 'Burnsville', 'Burnt Prairie', 'Burnt Store Marina', 'Burr', 'Burr Oak', 'Burr Ridge', 'Burrton', 'Burt', 'Burton', 'Burtonsville', 'Burtrum', 'Burwell', 'Busby', 'Bush', 'Bushnell', 'Bushong', 'Bushton', 'Bushyhead', 'Bussey', 'Butler', 'Butler Beach', 'Butlerville', 'Butner', 'Butte', 'Butte City', 'Butte Falls', 'Butterfield', 'Butternut', 'Butters', 'Butteville', 'Buttonwillow', 'Buxton', 'Buzzards Bay', 'Byars', 'Byers', 'Byesville', 'Byhalia', 'Byng', 'Bynum', 'Byram', 'Byrdstown', 'Byrnes Mill', 'Byromville', 'Byron', 'Byron Center', 'Bystrom', 'Búfalo', 'C-Road', 'Cabazon', 'Cabery', 'Cabin John', 'Cabo Rojo', 'Cabool', 'Cabot', 'Cabán', 'Cacao', 'Cache', 'Cactus', 'Caddo', 'Caddo Mills', 'Caddo Valley', 'Cadillac', 'Cadiz', 'Cadott', 'Cadwell', 'Caguas', 'Cahaba Heights', 'Cahokia', 'Cainsville', 'Cairo', 'Cajah\'s Mountain', 'Cal-Nev-Ari', 'Calabasas', 'Calabash', 'Calais', 'Calamus', 'Calcium', 'Calcutta', 'Caldwell', 'Cale', 'Caledonia', 'Calera', 'Calexico', 'Calhan', 'Calhoun', 'Calhoun City', 'Calhoun Falls', 'Calico Rock', 'Caliente', 'Califon', 'California', 'California City', 'Calimesa', 'Calio', 'Calion', 'Calipatria', 'Calistoga', 'Callahan', 'Callao', 'Callaway', 'Callender', 'Callensburg', 'Callery', 'Callicoon', 'Callimont', 'Callisburg', 'Calmar', 'Calpet', 'Calumet', 'Calumet City', 'Calumet Park', 'Calumet-Norvelt', 'Calvert', 'Calvert Beach-Long Beach', 'Calvert City', 'Calverton', 'Calverton Park', 'Calvin', 'Calwa', 'Calypso', 'Camak', 'Camanche', 'Camano', 'Camargo', 'Camarillo', 'Camas', 'Cambria', 'Cambrian Park', 'Cambridge', 'Cambridge City', 'Cambridge Springs', 'Camden', 'Camden Point', 'Camden-on-Gauley', 'Camdenton', 'Cameron', 'Cameron Park', 'Camilla', 'Camillus', 'Cammack Village', 'Camp Crook', 'Camp Douglas', 'Camp Hill', 'Camp Lake', 'Camp Pendleton North', 'Camp Pendleton South', 'Camp Point', 'Camp Springs', 'Camp Swift', 'Camp Three', 'Camp Verde', 'Camp Wood', 'Campanilla', 'Campbell', 'Campbell Hill', 'Campbell Station', 'Campbellsburg', 'Campbellsport', 'Campbellsville', 'Campbellton', 'Campbelltown', 'Campion', 'Campo', 'Campo Rico', 'Campobello', 'Campti', 'Campton', 'Campus', 'Camuy', 'Cana', 'Canaan', 'Canada Creek Ranch', 'Canada de los Alamos', 'Canadian', 'Canadian Lakes', 'Canadohta Lake', 'Canajoharie', 'Canal Fulton', 'Canal Point', 'Canal Winchester', 'Canalou', 'Canandaigua', 'Canaseraga', 'Canastota', 'Canby', 'Candelaria', 'Candelaria Arenas', 'Candelero Arriba', 'Candler-McAfee', 'Cando', 'Candor', 'Cane Savannah', 'Caney', 'Caney City', 'Caneyville', 'Canfield', 'Canisteo', 'Canistota', 'Cankton', 'Cannelburg', 'Cannelton', 'Cannon AFB', 'Cannon Ball', 'Cannon Beach', 'Cannon Falls', 'Cannonville', 'Canon', 'Canon City', 'Canonsburg', 'Canova', 'Canton', 'Canton City', 'Canton Valley', 'Cantrall', 'Cantril', 'Cantu Addition', 'Cantua Creek', 'Cantwell', 'Canute', 'Canutillo', 'Canyon', 'Canyon City', 'Canyon Day', 'Canyon Lake', 'Canyon Rim', 'Canyondam', 'Canyonville', 'Canóvanas', 'Capac', 'Cape Canaveral', 'Cape Carteret', 'Cape Charles', 'Cape Coral', 'Cape Girardeau', 'Cape May', 'Cape May Court House', 'Cape May Point', 'Cape Meares', 'Cape Neddick', 'Cape St. Claire', 'Cape Vincent', 'Capitan', 'Capitanejo', 'Capitol Heights', 'Capitola', 'Capon Bridge', 'Capron', 'Captain Cook', 'Captiva', 'Caraway', 'Carbon', 'Carbon Cliff', 'Carbon Hill', 'Carbonado', 'Carbondale', 'Cardiff', 'Cardin', 'Cardington', 'Cardwell', 'Carefree', 'Carencro', 'Carey', 'Caribou', 'Carl', 'Carl Junction', 'Carl\'s Corner', 'Carle Place', 'Carleton', 'Carlile', 'Carlin', 'Carlinville', 'Carlisle', 'Carlock', 'Carlos', 'Carlsbad', 'Carlsbad North', 'Carlsborg', 'Carlstadt', 'Carlton', 'Carlyle', 'Carlyss', 'Carmel', 'Carmel Hamlet', 'Carmel Valley Village', 'Carmel-by-the-Sea', 'Carmen', 'Carmi', 'Carmichael', 'Carmichaels', 'Carmine', 'Carmody Hills-Pepper Mill Village', 'Carnation', 'Carnegie', 'Carnesville', 'Carney', 'Carneys Point', 'Carnot-Moon', 'Carnuel', 'Caro', 'Carol City', 'Carol Stream', 'Carolina', 'Carolina Beach', 'Carolina Shores', 'Carpendale', 'Carpenter', 'Carpentersville', 'Carpinteria', 'Carpio', 'Carrabelle', 'Carrboro', 'Carriage Club', 'Carrick', 'Carrier', 'Carrier Mills', 'Carrington', 'Carrizales', 'Carrizo Hill', 'Carrizo Springs', 'Carrizozo', 'Carroll', 'Carroll Valley', 'Carrollton', 'Carrolltown', 'Carrsville', 'Carson', 'Carson City', 'Carson River Valley', 'Carsonville', 'Cartago', 'Carter', 'Carter Lake', 'Carteret', 'Cartersville', 'Carterville', 'Carthage', 'Caruthers', 'Caruthersville', 'Carver', 'Carver Ranches', 'Cary', 'Carytown', 'Caryville', 'Casa', 'Casa Colorada', 'Casa Conejo', 'Casa Grande', 'Casa de Oro-Mount Helix', 'Casar', 'Casas Adobes', 'Cascade', 'Cascade Locks', 'Cascade Valley', 'Cascade-Chipita Park', 'Cascade-Fairwood', 'Casco', 'Caseville', 'Casey', 'Caseyville', 'Cash', 'Cashiers', 'Cashion', 'Cashmere', 'Cashton', 'Cashtown-McKnightstown', 'Casnovia', 'Casper', 'Casper Mountain', 'Caspian', 'Cass City', 'Cass Lake', 'Cassadaga', 'Cassandra', 'Casselberry', 'Casselman', 'Casselton', 'Cassoday', 'Cassopolis', 'Casstown', 'Cassville', 'Castalia', 'Castana', 'Castanea', 'Castile', 'Castine', 'Castle', 'Castle Dale', 'Castle Hayne', 'Castle Hills', 'Castle Pines', 'Castle Point', 'Castle Rock', 'Castle Shannon', 'Castle Valley', 'Castleberry', 'Castleford', 'Castleton-on-Hudson', 'Castlewood', 'Castor', 'Castorland', 'Castro Valley', 'Castroville', 'Caswell Beach', 'Catalina', 'Catalina Foothills', 'Catarina', 'Catasauqua', 'Catawba', 'Catawissa', 'Cataño', 'Cathan', 'Cathay', 'Cathcart', 'Cathedral City', 'Cathlamet', 'Catlettsburg', 'Catlin', 'Cato', 'Catonsville', 'Catoosa', 'Catron', 'Catskill', 'Cattaraugus', 'Caulksville', 'Causey', 'Cavalier', 'Cave', 'Cave City', 'Cave Creek', 'Cave Junction', 'Cave Spring', 'Cave Springs', 'Cave-In-Rock', 'Cavetown', 'Cavour', 'Cawker City', 'Cayce', 'Cayey', 'Cayuco', 'Cayucos', 'Cayuga', 'Cayuga Heights', 'Cayuse', 'Cazenovia', 'Cecil', 'Cecil-Bishop', 'Cecilia', 'Cecilton', 'Cedar', 'Cedar Bluff', 'Cedar Bluffs', 'Cedar City', 'Cedar Creek', 'Cedar Crest', 'Cedar Falls', 'Cedar Fort', 'Cedar Glen Lakes', 'Cedar Glen West', 'Cedar Grove', 'Cedar Hill', 'Cedar Hill Lakes', 'Cedar Hills', 'Cedar Key', 'Cedar Lake', 'Cedar Mill', 'Cedar Mills', 'Cedar Park', 'Cedar Point', 'Cedar Rapids', 'Cedar Rock', 'Cedar Springs', 'Cedar Vale', 'Cedar Valley', 'Cedarburg', 'Cedaredge', 'Cedarhurst', 'Cedartown', 'Cedarville', 'Ceiba', 'Celada', 'Celebration', 'Celeste', 'Celina', 'Celoron', 'Cement', 'Cement City', 'Centennial', 'Center', 'Center City', 'Center Hill', 'Center Junction', 'Center Line', 'Center Moriches', 'Center Point', 'Centerburg', 'Centereach', 'Centerfield', 'Centerport', 'Centerton', 'Centertown', 'Centerview', 'Centerville', 'Centrahoma', 'Central', 'Central Aguirre', 'Central City', 'Central Falls', 'Central Gardens', 'Central Heights-Midland City', 'Central High', 'Central Islip', 'Central Lake', 'Central Manchester', 'Central Pacolet', 'Central Park', 'Central Point', 'Central Somers', 'Central Square', 'Central Valley', 'Central Waterford', 'Centralhatchee', 'Centralia', 'Centre', 'Centre Hall', 'Centre Island', 'Centreville', 'Centuria', 'Century', 'Century Village', 'Ceredo', 'Ceres', 'Ceresco', 'Cerritos', 'Cerro Gordo', 'Cesar Chavez', 'Ceylon', 'Chackbay', 'Chadbourn', 'Chadron', 'Chadwick', 'Chaffee', 'Chagrin Falls', 'Chain O\' Lakes-King', 'Chain of Rocks', 'Chain-O-Lakes', 'Chalco', 'Chalfant', 'Chalfont', 'Chalkville', 'Chalkyitsik', 'Challenge-Brownsville', 'Challis', 'Chalmers', 'Chalmette', 'Chama', 'Chamberlain', 'Chamberlayne', 'Chambers', 'Chambers Estates', 'Chambersburg', 'Chamblee', 'Chamisal', 'Chamois', 'Champ', 'Champaign', 'Champion Heights', 'Champlain', 'Champlin', 'Chance', 'Chancellor', 'Chandler', 'Chandlerville', 'Chanhassen', 'Channahon', 'Channel Islands Beach', 'Channel Lake', 'Channelview', 'Channing', 'Chantilly', 'Chanute', 'Chaparral', 'Chapel Hill', 'Chapin', 'Chapman', 'Chapmanville', 'Chappaqua', 'Chappell', 'Chardon', 'Charenton', 'Chariton', 'Charlack', 'Charleroi', 'Charles City', 'Charles Town', 'Charleston', 'Charleston Park', 'Charlestown', 'Charlevoix', 'Charlo', 'Charlotte', 'Charlotte Court House', 'Charlotte Hall', 'Charlotte Harbor', 'Charlotte Park', 'Charlottesville', 'Charter Oak', 'Chase', 'Chase City', 'Chaseburg', 'Chaska', 'Chataignier', 'Chateaugay', 'Chatfield', 'Chatham', 'Chatmoss', 'Chatom', 'Chatsworth', 'Chattahoochee', 'Chattanooga', 'Chattanooga Valley', 'Chattaroy', 'Chaumont', 'Chauncey', 'Chautauqua', 'Chauvin', 'Cheat Lake', 'Chebanse', 'Cheboygan', 'Checotah', 'Cheektowaga', 'Chefornak', 'Chehalis', 'Chehalis Village', 'Chelan', 'Chelsea', 'Chenega', 'Chenequa', 'Cheney', 'Cheneyville', 'Chenoa', 'Chenoweth', 'Cheraw', 'Cheriton', 'Cherokee', 'Cherokee Village', 'Cherry', 'Cherry Creek', 'Cherry Fork', 'Cherry Grove', 'Cherry Hill Mall', 'Cherry Hills Village', 'Cherry Tree', 'Cherry Valley', 'Cherryland', 'Cherryvale', 'Cherryville', 'Cherrywood Village', 'Chesaning', 'Chesapeake', 'Chesapeake Beach', 'Chesapeake City', 'Chesapeake Ranch Estates-Drum Point', 'Cheshire', 'Cheshire Village', 'Chesilhurst', 'Chesnee', 'Chest Springs', 'Chester', 'Chester Center', 'Chester Heights', 'Chester Hill', 'Chester Township', 'Chester-Chester Depot', 'Chesterbrook', 'Chesterfield', 'Chesterfield Court House', 'Chesterhill', 'Chesterland', 'Chesterton', 'Chestertown', 'Chesterville', 'Chestnut Ridge', 'Cheswick', 'Cheswold', 'Chetek', 'Chetopa', 'Chevak', 'Cheval', 'Cheverly', 'Cheviot', 'Chevy Chase', 'Chevy Chase Heights', 'Chevy Chase Section Five', 'Chevy Chase Section Three', 'Chevy Chase View', 'Chevy Chase Village', 'Chewelah', 'Chewey', 'Chewsville', 'Cheyenne', 'Cheyenne Wells', 'Chicago', 'Chicago Heights', 'Chicago Ridge', 'Chickaloon', 'Chickamauga', 'Chickamaw Beach', 'Chickasaw', 'Chickasha', 'Chicken', 'Chico', 'Chicopee', 'Chicora', 'Chidester', 'Chief Lake', 'Chiefland', 'Chignik', 'Chignik Lagoon', 'Chignik Lake', 'Chilchinbito', 'Chilcoot-Vinton', 'Childersburg', 'Childress', 'Chilhowee', 'Chilhowie', 'Chilili', 'Chillicothe', 'Chillum', 'Chilo', 'Chiloquin', 'Chilton', 'Chimayo', 'Chimney Rock', 'China', 'China Grove', 'China Lake Acres', 'Chincoteague', 'Chinese Camp', 'Chiniak', 'Chinle', 'Chino', 'Chino Hills', 'Chino Valley', 'Chinook', 'Chipley', 'Chippewa Falls', 'Chippewa Lake', 'Chireno', 'Chisago City', 'Chisana', 'Chisholm', 'Chistochina', 'Chitina', 'Chittenango', 'Chocowinity', 'Choctaw', 'Choctaw Lake', 'Chokio', 'Chokoloskee', 'Choteau', 'Choudrant', 'Chouteau', 'Chowchilla', 'Chrisman', 'Chrisney', 'Christiana', 'Christiansburg', 'Christie', 'Christine', 'Christmas', 'Christopher', 'Christoval', 'Chualar', 'Chuathbaluk', 'Chubbuck', 'Chugcreek', 'Chugwater', 'Chuichu', 'Chula', 'Chula Vista', 'Chula Vista-Orason', 'Chula Vista-River Spur', 'Chuluota', 'Chunky', 'Chupadero', 'Church Creek', 'Church Hill', 'Church Point', 'Church Rock', 'Churchill', 'Churchs Ferry', 'Churchville', 'Churdan', 'Churubusco', 'Ciales', 'Cibecue', 'Cibola', 'Cibolo', 'Cicero', 'Cidra', 'Cienegas Terrace', 'Cimarron', 'Cimarron City', 'Cimarron Hills', 'Cincinnati', 'Cinco Bayou', 'Cinco Ranch', 'Circle', 'Circle D-KC Estates', 'Circle Pines', 'Circleville', 'Cisco', 'Cisne', 'Cissna Park', 'Citronelle', 'Citrus', 'Citrus City', 'Citrus Heights', 'Citrus Hills', 'Citrus Park', 'Citrus Ridge', 'Citrus Springs', 'City View', 'City of The Dalles', 'Clackamas', 'Claflin', 'Claiborne', 'Claire City', 'Clairton', 'Clam Gulch', 'Clancy', 'Clanton', 'Clara City', 'Clare', 'Claremont', 'Claremore', 'Clarence', 'Clarence Center', 'Clarendon', 'Clarendon Hills', 'Clarinda', 'Clarington', 'Clarion', 'Clarissa', 'Clark', 'Clark Fork', 'Clark Mills', 'Clark\'s Point', 'Clarkdale', 'Clarkesville', 'Clarkfield', 'Clarks', 'Clarks Green', 'Clarks Grove', 'Clarks Hill', 'Clarks Summit', 'Clarksburg', 'Clarksdale', 'Clarkson', 'Clarkson Valley', 'Clarkston', 'Clarkston Heights-Vineland', 'Clarksville', 'Clarksville City', 'Clarkton', 'Claryville', 'Clatonia', 'Clatskanie', 'Claude', 'Claverack-Red Mills', 'Clawson', 'Claxton', 'Clay', 'Clay Center', 'Clay City', 'Claycomo', 'Clayhatchee', 'Claymont', 'Claypool', 'Claypool Hill', 'Claysburg', 'Claysville', 'Clayton', 'Clayville', 'Cle Elum', 'Clear Lake', 'Clear Lake Shores', 'Clear Spring', 'Clearbrook', 'Clearbrook Park', 'Clearfield', 'Clearlake', 'Clearlake Oaks', 'Clearmont', 'Clearview', 'Clearview Acres', 'Clearwater', 'Cleburne', 'Cleghorn', 'Clementon', 'Clements', 'Clemmons', 'Clemons', 'Clemson', 'Clendenin', 'Cleo Springs', 'Cleona', 'Cleora', 'Clermont', 'Cleveland', 'Cleveland Heights', 'Clever', 'Cleves', 'Clewiston', 'Cliff Village', 'Clifford', 'Cliffside Park', 'Cliffwood Beach', 'Clifton', 'Clifton Forge', 'Clifton Heights', 'Clifton Hill', 'Clifton Springs', 'Climax', 'Climax Springs', 'Clinchco', 'Clinchport', 'Clint', 'Clinton', 'Clintondale', 'Clintonville', 'Clintwood', 'Clio', 'Clitherall', 'Clive', 'Clontarf', 'Cloquet', 'Closter', 'Cloud Creek', 'Cloud Lake', 'Cloudcroft', 'Clover', 'Clover Hill', 'Cloverdale', 'Cloverleaf', 'Cloverly', 'Cloverport', 'Clovis', 'Clute', 'Clutier', 'Clyde', 'Clyde Hill', 'Clyde Park', 'Clyman', 'Clymer', 'Coachella', 'Coahoma', 'Coal Center', 'Coal City', 'Coal Creek', 'Coal Fork', 'Coal Grove', 'Coal Hill', 'Coal Run Village', 'Coal Valley', 'Coaldale', 'Coalgate', 'Coaling', 'Coalinga', 'Coalmont', 'Coalport', 'Coalton', 'Coalville', 'Coamo', 'Coates', 'Coatesville', 'Coats', 'Coatsburg', 'Cobalt', 'Cobb', 'Cobbtown', 'Cobden', 'Cobleskill', 'Coburg', 'Coburn', 'Cochiti', 'Cochituate', 'Cochran', 'Cochrane', 'Cochranton', 'Cockeysville', 'Cockrell Hill', 'Coco', 'Cocoa', 'Cocoa Beach', 'Cocoa West', 'Coconut Creek', 'Cody', 'Coeburn', 'Coeur d\'Alene', 'Coeymans', 'Coffee City', 'Coffee Springs', 'Coffeen', 'Coffeeville', 'Coffey', 'Coffeyville', 'Coffman Cove', 'Cofield', 'Coggon', 'Cogswell', 'Cohasset', 'Cohassett Beach', 'Cohocton', 'Cohoe', 'Cohoes', 'Cohutta', 'Coin', 'Cokato', 'Cokeburg', 'Cokedale', 'Coker', 'Cokesbury', 'Cokeville', 'Colbert', 'Colby', 'Colchester', 'Colcord', 'Cold Bay', 'Cold Brook', 'Cold Spring', 'Cold Spring Harbor', 'Cold Springs', 'Coldfoot', 'Coldspring', 'Coldstream', 'Coldwater', 'Cole', 'Cole Camp', 'Coleharbor', 'Coleman', 'Colerain', 'Coleraine', 'Coleridge', 'Colesburg', 'Colesville', 'Coleta', 'Colfax', 'Collbran', 'College', 'College City', 'College Corner', 'College Park', 'College Place', 'College Springs', 'College Station', 'Collegedale', 'Collegeville', 'Colleyville', 'Collier Manor-Cresthaven', 'Collierville', 'Collingdale', 'Collings Lakes', 'Collingswood', 'Collins', 'Collinston', 'Collinsville', 'Collinwood', 'Collyer', 'Colma', 'Colman', 'Colmar Manor', 'Colmesneil', 'Colo', 'Cologne', 'Coloma', 'Colome', 'Colon', 'Colona', 'Colonia', 'Colonial Beach', 'Colonial Heights', 'Colonial Park', 'Colonial Pine Hills', 'Colonie', 'Colony', 'Colorado City', 'Colorado Springs', 'Colp', 'Colquitt', 'Colstrip', 'Colt', 'Colton', 'Columbia', 'Columbia City', 'Columbia Falls', 'Columbia Heights', 'Columbiana', 'Columbiaville', 'Columbine', 'Columbine Valley', 'Columbus', 'Columbus AFB', 'Columbus City', 'Columbus Grove', 'Columbus Junction', 'Colusa', 'Colver', 'Colville', 'Colwell', 'Colwich', 'Colwyn', 'Comanche', 'Combee Settlement', 'Combes', 'Combine', 'Combined Locks', 'Comer', 'Comerío', 'Comfort', 'Comfrey', 'Commack', 'Commerce', 'Commerce City', 'Commercial Point', 'Commodore', 'Como', 'Compton', 'Comstock', 'Comstock Northwest', 'Comstock Park', 'Comunas', 'Concepcion', 'Conception Junction', 'Conconully', 'Concord', 'Concordia', 'Concow', 'Concrete', 'Conde', 'Condon', 'Conehatta', 'Conesville', 'Conetoe', 'Coney Island', 'Confluence', 'Conger', 'Congers', 'Congerville', 'Congress', 'Conley', 'Conneaut', 'Conneaut Lake', 'Conneaut Lakeshore', 'Conneautville', 'Connell', 'Connellsville', 'Connelly Springs', 'Connersville', 'Conning Towers-Nautilus Park', 'Connoquenessing', 'Conover', 'Conrad', 'Conrath', 'Conroe', 'Conshohocken', 'Constableville', 'Constantia', 'Constantine', 'Continental', 'Contoocook', 'Converse', 'Convoy', 'Conway', 'Conway Springs', 'Conyers', 'Conyngham', 'Cook', 'Cooke City-Silver Gate', 'Cookeville', 'Cooksville', 'Cool', 'Cool Valley', 'Cooleemee', 'Coolidge', 'Coolville', 'Coon Rapids', 'Coon Valley', 'Cooper', 'Cooper City', 'Cooper Landing', 'Coopersburg', 'Cooperstown', 'Coopersville', 'Cooperton', 'Coopertown', 'Coos Bay', 'Coosada', 'Cooter', 'Copake Lake', 'Copalis Beach', 'Copan', 'Cope', 'Copeland', 'Copemish', 'Copenhagen', 'Copiague', 'Coplay', 'Coppell', 'Copper Canyon', 'Copper Center', 'Copper City', 'Copperas Cove', 'Copperhill', 'Copperopolis', 'Copperville', 'Coppock', 'Coquille', 'Coquí', 'Cora', 'Coral Gables', 'Coral Hills', 'Coral Springs', 'Coral Terrace', 'Coralville', 'Coram', 'Coraopolis', 'Corazón', 'Corbin', 'Corbin City', 'Corcoran', 'Corcovado', 'Cordaville', 'Cordele', 'Corder', 'Cordes Lakes', 'Cordova', 'Corfu', 'Corinne', 'Corinth', 'Corn', 'Cornelia', 'Cornelius', 'Cornell', 'Cornersville', 'Corning', 'Cornish', 'Cornlea', 'Cornville', 'Cornwall', 'Cornwall on Hudson', 'Cornwells Heights-Eddington', 'Corona', 'Corona de Tucson', 'Coronaca', 'Coronado', 'Corozal', 'Corporation of Ranson', 'Corpus Christi', 'Corral City', 'Corrales', 'Corralitos', 'Correctionville', 'Correll', 'Corrigan', 'Corry', 'Corsica', 'Corsicana', 'Corte Madera', 'Cortez', 'Cortland', 'Cortland West', 'Corunna', 'Corvallis', 'Corwin', 'Corwith', 'Corydon', 'Cosby', 'Coshocton', 'Cosmopolis', 'Cosmos', 'Costa Mesa', 'Cotati', 'Cotesfield', 'Coto Laurel', 'Coto Norte', 'Coto de Caza', 'Cottage City', 'Cottage Grove', 'Cottage Lake', 'Cottageville', 'Cotter', 'Cottleville', 'Cotton Plant', 'Cotton Valley', 'Cottondale', 'Cottonport', 'Cottonwood', 'Cottonwood Falls', 'Cottonwood Heights', 'Cottonwood Shores', 'Cottonwood West', 'Cottonwood-Verde Village', 'Cotulla', 'Couderay', 'Coudersport', 'Coulee City', 'Coulee Dam', 'Coulter', 'Coulterville', 'Council', 'Council Bluffs', 'Council Grove', 'Council Hill', 'Country Club', 'Country Club Estates', 'Country Club Heights', 'Country Club Hills', 'Country Estates', 'Country Homes', 'Country Knolls', 'Country Lake Estates', 'Country Life Acres', 'Country Walk', 'Countryside', 'County Line', 'Coupeville', 'Courtdale', 'Courtenay', 'Courtland', 'Coushatta', 'Cove', 'Cove City', 'Cove Neck', 'Covedale', 'Covelo', 'Covenant Life', 'Coventry Lake', 'Covina', 'Covington', 'Cowan', 'Coward', 'Cowarts', 'Cowden', 'Cowen', 'Coweta', 'Cowgill', 'Cowles', 'Cowley', 'Cowlington', 'Cowpens', 'Coxsackie', 'Coy', 'Coyanosa', 'Coyle', 'Coyne Center', 'Coyote Acres', 'Coyville', 'Cozad', 'Crab Orchard', 'Crabtree', 'Crafton', 'Cragsmoor', 'Craig', 'Craig Beach', 'Craigmont', 'Craigsville', 'Crainville', 'Cramerton', 'Cranbury', 'Crandall', 'Crandon', 'Crandon Lakes', 'Crane', 'Cranesville', 'Cranfills Gap', 'Cranford', 'Cranston', 'Crary', 'Crawford', 'Crawfordsville', 'Crawfordville', 'Creal Springs', 'Creede', 'Creedmoor', 'Creekside', 'Creighton', 'Crenshaw', 'Creola', 'Cresaptown-Bel Air', 'Cresbard', 'Crescent', 'Crescent Beach', 'Crescent City', 'Crescent City North', 'Crescent Mills', 'Crescent Springs', 'Cresco', 'Cresskill', 'Cresson', 'Cressona', 'Crest', 'Crest Hill', 'Crested Butte', 'Crestline', 'Creston', 'Crestone', 'Crestview', 'Crestview Hills', 'Crestwood', 'Crestwood Village', 'Creswell', 'Crete', 'Creve Coeur', 'Crewe', 'Cricket', 'Cridersville', 'Crimora', 'Cripple Creek', 'Crisfield', 'Crittenden', 'Crivitz', 'Crocker', 'Crockett', 'Crofton', 'Croghan', 'Cromberg', 'Crompond', 'Cromwell', 'Crook', 'Crooked Creek', 'Crooked Lake Park', 'Crooks', 'Crookston', 'Crooksville', 'Crosby', 'Crosbyton', 'Cross City', 'Cross Hill', 'Cross Lanes', 'Cross Mountain', 'Cross Plains', 'Cross Roads', 'Cross Timber', 'Cross Timbers', 'Crossett', 'Crossgate', 'Crosslake', 'Crossnore', 'Crossville', 'Croswell', 'Crothersville', 'Croton-on-Hudson', 'Crouch', 'Crow Agency', 'Crowder', 'Crowell', 'Crowheart', 'Crowley', 'Crown City', 'Crown Heights', 'Crown Point', 'Crownpoint', 'Crownsville', 'Crows Nest', 'Croydon', 'Crozet', 'Cruger', 'Crugers', 'Crump', 'Crystal', 'Crystal City', 'Crystal Falls', 'Crystal Lake', 'Crystal Lake Park', 'Crystal Lakes', 'Crystal Lawns', 'Crystal River', 'Crystal Springs', 'Cuartelez', 'Cuba', 'Cuba City', 'Cube Cove', 'Cudahy', 'Cudjoe Key', 'Cuero', 'Cuevitas', 'Culbertson', 'Culdesac', 'Culebra', 'Cullen', 'Cullison', 'Cullman', 'Culloden', 'Cullom', 'Cullowhee', 'Culpeper', 'Culver', 'Culver City', 'Cumberland', 'Cumberland Center', 'Cumberland City', 'Cumberland Gap', 'Cumberland Head', 'Cumberland Hill', 'Cumby', 'Cumings', 'Cumming', 'Cundiyo', 'Cuney', 'Cunningham', 'Cupertino', 'Curlew', 'Currie', 'Curryville', 'Curtis', 'Curtiss', 'Curtisville', 'Curwensville', 'Cushing', 'Cushman', 'Cusick', 'Cusseta', 'Custar', 'Custer', 'Custer City', 'Cut Bank', 'Cut Off', 'Cut and Shoot', 'Cutchogue', 'Cuthbert', 'Cutler', 'Cutler Ridge', 'Cutlerville', 'Cutten', 'Cuyahoga Falls', 'Cuyahoga Heights', 'Cuyamungue', 'Cuyuna', 'Cygnet', 'Cylinder', 'Cynthiana', 'Cypress', 'Cypress Gardens', 'Cypress Lake', 'Cypress Lakes', 'Cypress Quarters', 'Cyril', 'Cyrus', 'D\'Iberville', 'D\'Lo', 'Dacoma', 'Dacono', 'Dacula', 'Dade City', 'Dade City North', 'Dadeville', 'Daggett', 'Dagsboro', 'Daguao', 'Dahlgren', 'Dahlonega', 'Daingerfield', 'Daisetta', 'Daisy', 'Daisytown', 'Dakota', 'Dakota City', 'Dale', 'Dale City', 'Daleville', 'Dalhart', 'Dallas', 'Dallas Center', 'Dallas City', 'Dallastown', 'Dallesport', 'Dalton', 'Dalton City', 'Dalton Gardens', 'Dalworthington Gardens', 'Daly City', 'Dalzell', 'Damar', 'Damariscotta-Newcastle', 'Damascus', 'Dames Quarter', 'Damiansville', 'Damon', 'Dana', 'Dana Point', 'Danbury', 'Dandridge', 'Dane', 'Danforth', 'Dania Beach', 'Daniel', 'Daniels', 'Danielson', 'Danielsville', 'Dannebrog', 'Dannemora', 'Dansville', 'Dante', 'Danube', 'Danvers', 'Danville', 'Daphne', 'Darby', 'Darby Township', 'Darbyville', 'Dardanelle', 'Dardenne Prairie', 'Darfur', 'Darien', 'Darlington', 'Darmstadt', 'Darnestown', 'Darrington', 'Darrouzett', 'Darwin', 'Dasher', 'Dassel', 'Datto', 'Dauphin', 'Dauphin Island', 'Davenport', 'Davey', 'David City', 'Davidson', 'Davidsville', 'Davie', 'Davis', 'Davis City', 'Davis Junction', 'Davisboro', 'Davison', 'Daviston', 'Davy', 'Dawson', 'Dawson Springs', 'Dawsonville', 'Day Heights', 'Day Valley', 'Daykin', 'Dayton', 'Dayton Lakes', 'Daytona Beach', 'Daytona Beach Shores', 'Dayville', 'Dazey', 'De Bary', 'De Beque', 'De Borgia', 'De Funiak Springs', 'De Graff', 'De Kalb', 'De Land', 'De Land Southwest', 'De Leon', 'De Leon Springs', 'De Motte', 'De Pere', 'De Pue', 'De Queen', 'De Ridder', 'De Smet', 'De Soto', 'De Tour Village', 'De Valls Bluff', 'De Witt', 'DeForest', 'DeKalb', 'DeQuincy', 'DeRuyter', 'DeSoto', 'Deadwood', 'Deal', 'Deal Island', 'Deale', 'Dean', 'Dearborn', 'Dearborn Heights', 'Dearing', 'Deary', 'Deatsville', 'Deaver', 'Decatur', 'Decatur City', 'Decaturville', 'Decherd', 'Decker', 'Deckerville', 'Declo', 'Decorah', 'Dedham', 'Deemston', 'Deenwood', 'Deep River', 'Deep River Center', 'Deephaven', 'Deepstep', 'Deepwater', 'Deer Creek', 'Deer Grove', 'Deer Lake', 'Deer Lodge', 'Deer Park', 'Deer River', 'Deer Trail', 'Deerfield', 'Deerfield Beach', 'Deering', 'Deersville', 'Deerwood', 'Deferiet', 'Defiance', 'Del Aire', 'Del City', 'Del Mar', 'Del Mar Heights', 'Del Monte Forest', 'Del Norte', 'Del Rey', 'Del Rey Oaks', 'Del Rio', 'Del Sol-Loma Linda', 'Delafield', 'Delano', 'Delanson', 'Delaplaine', 'Delavan', 'Delavan Lake', 'Delaware', 'Delaware City', 'Delaware Water Gap', 'Delbarton', 'Delcambre', 'Delevan', 'Delhi', 'Delia', 'Delight', 'Dell', 'Dell City', 'Dell Rapids', 'Delleker', 'Dellroy', 'Dellwood', 'Delmar', 'Delmont', 'Deloit', 'Delphi', 'Delphos', 'Delray Beach', 'Delta', 'Delta Junction', 'Deltana', 'Deltona', 'Delway', 'Demarest', 'Deming', 'Demopolis', 'Demorest', 'Denair', 'Dendron', 'Denham', 'Denham Springs', 'Denison', 'Denmark', 'Dennehotso', 'Denning', 'Dennis', 'Dennis Acres', 'Dennis Port', 'Dennison', 'Dent', 'Denton', 'Dentsville', 'Denver', 'Denver City', 'Depauville', 'Depew', 'Depoe Bay', 'Deport', 'Deposit', 'Derby', 'Derby Acres', 'Derby Center', 'Derby Line', 'Dering Harbor', 'Derma', 'Dermott', 'Derry', 'Des Allemands', 'Des Arc', 'Des Lacs', 'Des Moines', 'Des Peres', 'Des Plaines', 'Deschutes River Woods', 'Desert Aire', 'Desert Hills', 'Desert Hot Springs', 'Desert Shores', 'Desert View Highlands', 'Deshler', 'Desloge', 'Desoto Lakes', 'Despard', 'Destin', 'Destrehan', 'Detroit', 'Detroit Beach', 'Detroit Lakes', 'Devers', 'Deville', 'Devils Lake', 'Devine', 'Devol', 'Devola', 'Devon-Berwyn', 'Dewar', 'Deweese', 'Dewey', 'Dewey Beach', 'Dewey-Humboldt', 'Deweyville', 'Dexter', 'Dexter City', 'Diablo', 'Diagonal', 'Diamond', 'Diamond Bar', 'Diamond Beach', 'Diamond City', 'Diamond Ridge', 'Diamond Springs', 'Diamondhead', 'Diamondville', 'Diaz', 'Dibble', 'Diboll', 'Dickens', 'Dickey', 'Dickeyville', 'Dickinson', 'Dickson', 'Dickson City', 'Dicksonville', 'Diehlstadt', 'Dierks', 'Dieterich', 'Dietrich', 'Diggins', 'Dighton', 'Dike', 'Dilkon', 'Dill City', 'Dillard', 'Diller', 'Dilley', 'Dillingham', 'Dillon', 'Dillon Beach', 'Dillonvale', 'Dillsboro', 'Dillsburg', 'Dillwyn', 'Dilworth', 'Dimmitt', 'Dimock', 'Dimondale', 'Dinosaur', 'Dinuba', 'Diomede', 'Discovery Bay', 'Discovery-Spring Garden', 'Dishman', 'Disney', 'District Heights', 'Divernon', 'Dix', 'Dix Hills', 'Dixfield', 'Dixie', 'Dixie Inn', 'Dixmoor', 'Dixon', 'Dixon Lane-Meadow Creek', 'Dobbins Heights', 'Dobbs Ferry', 'Dobson', 'Dock Junction', 'Doctor Phillips', 'Dodd City', 'Doddsville', 'Dodge', 'Dodge Center', 'Dodge City', 'Dodgeville', 'Dodson', 'Doerun', 'Doffing', 'Dolan Springs', 'Doland', 'Dolgeville', 'Dollar Corner', 'Dollar Point', 'Dolliver', 'Dolores', 'Dolton', 'Domino', 'Dona Ana', 'Donahue', 'Donald', 'Donalds', 'Donaldson', 'Donaldsonville', 'Donalsonville', 'Donegal', 'Dongola', 'Doniphan', 'Donna', 'Donnellson', 'Donnelly', 'Donnelsville', 'Donnybrook', 'Donora', 'Donovan', 'Dooling', 'Doolittle', 'Dooms', 'Doon', 'Dora', 'Dorado', 'Doral', 'Doran', 'Doraville', 'Dorchester', 'Dormont', 'Dorrance', 'Dorrington', 'Dorris', 'Dortches', 'Dos Palos', 'Dot Lake', 'Dot Lake Village', 'Dothan', 'Dotyville', 'Double Oak', 'Double Springs', 'Douds', 'Dougherty', 'Douglas', 'Douglass', 'Douglass Hills', 'Douglassville', 'Douglasville', 'Dousman', 'Dove Creek', 'Dover', 'Dover Base Housing', 'Dover Beaches North', 'Dover Beaches South', 'Dover Plains', 'Dover-Foxcroft', 'Dovray', 'Dow City', 'Dowagiac', 'Dowell', 'Dowelltown', 'Downers Grove', 'Downey', 'Downieville-Lawson-Dumont', 'Downing', 'Downingtown', 'Downs', 'Downsville', 'Dows', 'Doyle', 'Doylestown', 'Doyline', 'Dozier', 'Drain', 'Drake', 'Drakes Branch', 'Drakesboro', 'Drakesville', 'Draper', 'Dravosburg', 'Drayton', 'Dresden', 'Dresser', 'Drew', 'Drexel', 'Drexel Heights', 'Drexel Hill', 'Drexel-Alvernon', 'Driftwood', 'Driggs', 'Dripping Springs', 'Driscoll', 'Druid Hills', 'Drummond', 'Drumright', 'Dry Creek', 'Dry Prong', 'Dry Ridge', 'Dry Run', 'Dryden', 'Du Bois', 'Du Pont', 'Du Quoin', 'DuBois', 'DuPont', 'Duane Lake', 'Duanesburg', 'Duarte', 'Dubach', 'Dubberly', 'Dublin', 'Dubois', 'Duboistown', 'Dubuque', 'Duchesne', 'Duchess Landing', 'Duck Hill', 'Duck Key', 'Ducktown', 'Ducor', 'Dudley', 'Dudleyville', 'Due West', 'Duenweg', 'Duffield', 'Dufur', 'Dugger', 'Dugway', 'Dulac', 'Dulce', 'Duluth', 'Dumas', 'Dumbarton', 'Dumfries', 'Dumont', 'Dunbar', 'Duncan', 'Duncannon', 'Duncansville', 'Duncanville', 'Duncombe', 'Dundalk', 'Dundarrach', 'Dundas', 'Dundee', 'Dune Acres', 'Dunean', 'Dunedin', 'Dunellen', 'Dunes City', 'Dunes Road', 'Dunfermline', 'Dungannon', 'Dunkerton', 'Dunkirk', 'Dunlap', 'Dunlevy', 'Dunmore', 'Dunn', 'Dunn Center', 'Dunn Loring', 'Dunnell', 'Dunnellon', 'Dunning', 'Dunnstown', 'Dunreith', 'Dunseith', 'Dunsmuir', 'Dunwoody', 'Dupo', 'Dupont', 'Dupree', 'Duque', 'Duquesne', 'Durand', 'Durango', 'Durant', 'Durbin', 'Durham', 'Duryea', 'Dushore', 'Duson', 'Dustin', 'Dustin Acres', 'Dutchtown', 'Dutton', 'Duvall', 'Duxbury', 'Dwight', 'Dwight Mission', 'Dycusburg', 'Dyer', 'Dyersburg', 'Dyersville', 'Dyess', 'Dysart', 'Eads', 'Eagan', 'Eagar', 'Eagarville', 'Eagle', 'Eagle Bend', 'Eagle Butte', 'Eagle Grove', 'Eagle Harbor', 'Eagle Lake', 'Eagle Mountain', 'Eagle Nest', 'Eagle Pass', 'Eagle Point', 'Eagle River', 'Eagle Village', 'Eagle-Vail', 'Eagles Mere', 'Eagleton Village', 'Eagleville', 'Eakly', 'Earl', 'Earl Park', 'Earle', 'Earlham', 'Earlimart', 'Earling', 'Earlington', 'Earlsboro', 'Earlton', 'Earlville', 'Early', 'Earth', 'Easley', 'East Alton', 'East Arcadia', 'East Atlantic Beach', 'East Aurora', 'East Bangor', 'East Bank', 'East Bend', 'East Berlin', 'East Bernard', 'East Bernstadt', 'East Berwick', 'East Bethel', 'East Blythe', 'East Brady', 'East Brainerd', 'East Brewton', 'East Bronson', 'East Brookfield', 'East Brooklyn', 'East Brunswick', 'East Butler', 'East Camden', 'East Canton', 'East Cape Girardeau', 'East Carbon', 'East Carondelet', 'East Cathlamet', 'East Chicago', 'East Cleveland', 'East Compton', 'East Conemaugh', 'East Dennis', 'East Douglas', 'East Dublin', 'East Dubuque', 'East Duke', 'East Dunbar', 'East Dundee', 'East Dunseith', 'East Ellijay', 'East End', 'East Falmouth', 'East Farmingdale', 'East Flat Rock', 'East Foothills', 'East Fork', 'East Freehold', 'East Gaffney', 'East Galesburg', 'East Garden City', 'East Germantown', 'East Gillespie', 'East Glacier Park Village', 'East Glenville', 'East Grand Forks', 'East Grand Rapids', 'East Greenbush', 'East Greenville', 'East Griffin', 'East Gull Lake', 'East Hampton', 'East Hampton North', 'East Hartford', 'East Harwich', 'East Haven', 'East Hazel Crest', 'East Helena', 'East Hemet', 'East Highland Park', 'East Hill-Meridian', 'East Hills', 'East Hodge', 'East Hope', 'East Islip', 'East Ithaca', 'East Jordan', 'East Kingston', 'East La Mirada', 'East Lake', 'East Lake-Orient Park', 'East Lansdowne', 'East Lansing', 'East Laurinburg', 'East Liverpool', 'East Los Angeles', 'East Lynne', 'East Marion', 'East Massapequa', 'East McKeesport', 'East Meadow', 'East Merrimack', 'East Millcreek', 'East Millinocket', 'East Missoula', 'East Moline', 'East Moriches', 'East Mountain', 'East Nassau', 'East New Market', 'East Newark', 'East Newnan', 'East Norriton', 'East Northport', 'East Norwich', 'East Oakdale', 'East Orange', 'East Orosi', 'East Palatka', 'East Palestine', 'East Palo Alto', 'East Pasadena', 'East Patchogue', 'East Peoria', 'East Pepperell', 'East Perrine', 'East Peru', 'East Petersburg', 'East Pittsburgh', 'East Pleasant View', 'East Point', 'East Port Orchard', 'East Porterville', 'East Prairie', 'East Prospect', 'East Providence', 'East Quincy', 'East Quogue', 'East Randolph', 'East Renton Highlands', 'East Richmond Heights', 'East Ridge', 'East Riverdale', 'East Rochester', 'East Rockaway', 'East Rockingham', 'East Rutherford', 'East Sahuarita', 'East San Gabriel', 'East Sandwich', 'East Shore', 'East Shoreham', 'East Side', 'East Sonora', 'East Sparta', 'East Spencer', 'East St. Louis', 'East Stroudsburg', 'East Sumter', 'East Syracuse', 'East Tawakoni', 'East Tawas', 'East Thermopolis', 'East Troy', 'East Uniontown', 'East Vandergrift', 'East Washington', 'East Wenatchee', 'East Wenatchee Bench', 'East Williston', 'East York', 'Eastborough', 'Eastchester', 'Eastgate', 'Easthampton', 'Eastlake', 'Eastland', 'Eastlawn Gardens', 'Eastman', 'Easton', 'Eastover', 'Eastpoint', 'Eastpointe', 'Eastport', 'Eastvale', 'Eastview', 'Eastville', 'Eastwood', 'Eaton', 'Eaton Estates', 'Eaton Rapids', 'Eatons Neck', 'Eatonton', 'Eatontown', 'Eatonville', 'Eau Claire', 'Ebensburg', 'Ebro', 'Echelon', 'Echo', 'Echo Lake', 'Eckley', 'Eclectic', 'Economy', 'Ecorse', 'Ecru', 'Ector', 'Edcouch', 'Eddystone', 'Eddyville', 'Eden', 'Eden Isle', 'Eden Prairie', 'Eden Roc', 'Eden Valley', 'Edenton', 'Edgar', 'Edgar Springs', 'Edgard', 'Edge Hill', 'Edgecliff Village', 'Edgefield', 'Edgeley', 'Edgemere', 'Edgemont', 'Edgemont Park', 'Edgemoor', 'Edgerton', 'Edgewater', 'Edgewater-Paisano', 'Edgewood', 'Edgeworth', 'Edina', 'Edinboro', 'Edinburg', 'Edinburgh', 'Edison', 'Edisto', 'Edisto Beach', 'Edmond', 'Edmonds', 'Edmondson', 'Edmonson', 'Edmonston', 'Edmonton', 'Edmore', 'Edmundson', 'Edna', 'Edna Bay', 'Edom', 'Edon', 'Edroy', 'Edwards', 'Edwards AFB', 'Edwardsburg', 'Edwardsport', 'Edwardsville', 'Eek', 'Effie', 'Effingham', 'Egan', 'Egegik', 'Egeland', 'Egg Harbor', 'Egg Harbor City', 'Eglin AFB', 'Egypt', 'Egypt Lake-Leto', 'Ehrenberg', 'Ehrenfeld', 'Ehrhardt', 'Eidson Road', 'Eielson AFB', 'Eitzen', 'Ekalaka', 'Ekron', 'Ekwok', 'El Cajon', 'El Camino Angosto', 'El Campo', 'El Cenizo', 'El Centro', 'El Cerrito', 'El Cerro-Monterey Park', 'El Dara', 'El Dorado', 'El Dorado Hills', 'El Dorado Springs', 'El Granada', 'El Indio', 'El Jebel', 'El Lago', 'El Mangó', 'El Mirage', 'El Monte', 'El Negro', 'El Ojo', 'El Paso', 'El Paso de Robles (Paso Robles)', 'El Portal', 'El Rancho', 'El Refugio', 'El Reno', 'El Rio', 'El Segundo', 'El Sobrante', 'El Valle de Arroyo Seco', 'El Verano', 'Elaine', 'Eland', 'Elba', 'Elbe', 'Elberfeld', 'Elberon', 'Elbert', 'Elberta', 'Elberton', 'Elbing', 'Elbow Lake', 'Elbridge', 'Elburn', 'Elco', 'Elderon', 'Eldersburg', 'Elderton', 'Eldon', 'Eldora', 'Eldorado', 'Eldorado Springs', 'Eldorado at Santa Fe', 'Eldred', 'Eldridge', 'Eleanor', 'Electra', 'Electric City', 'Eleele', 'Elephant Butte', 'Eleva', 'Elfers', 'Elfin Cove', 'Elgin', 'Elida', 'Elim', 'Elizabeth', 'Elizabeth City', 'Elizabethton', 'Elizabethtown', 'Elizabethville', 'Elk City', 'Elk Creek', 'Elk Falls', 'Elk Garden', 'Elk Grove', 'Elk Grove Village', 'Elk Horn', 'Elk Mound', 'Elk Mountain', 'Elk Park', 'Elk Plain', 'Elk Point', 'Elk Rapids', 'Elk Ridge', 'Elk River', 'Elk Run Heights', 'Elkader', 'Elkhart', 'Elkhart Lake', 'Elkhorn', 'Elkhorn City', 'Elkin', 'Elkins', 'Elkland', 'Elkmont', 'Elko', 'Elkport', 'Elkridge', 'Elkton', 'Elkview', 'Elkville', 'Ellaville', 'Ellenboro', 'Ellendale', 'Ellensburg', 'Ellenton', 'Ellenville', 'Ellerbe', 'Ellettsville', 'Ellicott City', 'Ellicottville', 'Ellijay', 'Ellington', 'Ellinwood', 'Elliott', 'Ellis', 'Ellis Grove', 'Ellisburg', 'Elliston', 'Elliston-Lafayette', 'Ellisville', 'Elloree', 'Ellport', 'Ellsinore', 'Ellston', 'Ellsworth', 'Ellsworth AFB', 'Ellwood City', 'Elm City', 'Elm Creek', 'Elm Grove', 'Elm Springs', 'Elma', 'Elma Center', 'Elmdale', 'Elmendorf', 'Elmer', 'Elmer City', 'Elmhurst', 'Elmira', 'Elmira Heights', 'Elmo', 'Elmont', 'Elmore', 'Elmore City', 'Elmsford', 'Elmwood', 'Elmwood Park', 'Elmwood Place', 'Elnora', 'Elon College', 'Eloy', 'Elrod', 'Elrosa', 'Elroy', 'Elsa', 'Elsah', 'Elsberry', 'Elsie', 'Elsinore', 'Elsmere', 'Elsmore', 'Elton', 'Elvaston', 'Elverson', 'Elwood', 'Elwood-Magnolia', 'Ely', 'Elyria', 'Elysburg', 'Elysian', 'Emajagua', 'Embarrass', 'Emden', 'Emelle', 'Emerado', 'Emerald Beach', 'Emerald Isle', 'Emerald Lake Hills', 'Emerson', 'Emery', 'Emeryville', 'Emhouse', 'Emigsville', 'Emily', 'Eminence', 'Emington', 'Emlenton', 'Emma', 'Emmaus', 'Emmet', 'Emmetsburg', 'Emmett', 'Emmitsburg', 'Emmonak', 'Emmons', 'Emory', 'Emory-Meadow View', 'Empire', 'Empire City', 'Emporia', 'Emporium', 'Emsworth', 'Encantada-Ranchito El Calaboz', 'Enchanted Oaks', 'Encinal', 'Encinitas', 'Encino', 'Endeavor', 'Enderlin', 'Endicott', 'Endwell', 'Energy', 'Enfield', 'England', 'Englewood', 'Englewood Cliffs', 'English', 'Englishtown', 'Enid', 'Enigma', 'Ennis', 'Enoch', 'Enochville', 'Enola', 'Enon', 'Enon Valley', 'Enosburg Falls', 'Ensign', 'Ensley', 'Enterprise', 'Entiat', 'Enumclaw', 'Enville', 'Eola', 'Eolia', 'Epes', 'Ephesus', 'Ephraim', 'Ephrata', 'Epping', 'Epps', 'Epworth', 'Equality', 'Erath', 'Erda', 'Erhard', 'Erick', 'Ericson', 'Erie', 'Erin', 'Erin Springs', 'Erlands Point-Kitsap Lake', 'Erlanger', 'Erlton-Ellisburg', 'Erma', 'Ernest', 'Eros', 'Erskine', 'Erwin', 'Esbon', 'Escalante', 'Escalon', 'Escanaba', 'Escatawpa', 'Eschbach', 'Escobares', 'Escondido', 'Eskridge', 'Esmond', 'Espanola', 'Esparto', 'Esperance', 'Esperanza', 'Espino', 'Espy', 'Essex', 'Essex Fells', 'Essex Junction', 'Essex Village', 'Essexville', 'Estacada', 'Estancia', 'Estates of Fort Lauderdale', 'Estell Manor', 'Estelle', 'Estelline', 'Ester', 'Esterbrook', 'Estero', 'Estes Park', 'Estherville', 'Estherwood', 'Estill', 'Estill Springs', 'Esto', 'Estral Beach', 'Ethan', 'Ethel', 'Ethelsville', 'Ethete', 'Ethridge', 'Etna', 'Etna Green', 'Eton', 'Etowah', 'Ettrick', 'Eubank', 'Euclid', 'Eudora', 'Eufaula', 'Eugene', 'Euharlee', 'Euless', 'Eunice', 'Eunola', 'Eupora', 'Eureka', 'Eureka Mill', 'Eureka Springs', 'Eustace', 'Eustis', 'Eutaw', 'Eutawville', 'Eva', 'Evadale', 'Evan', 'Evans', 'Evans City', 'Evans Mills', 'Evansburg', 'Evansdale', 'Evanston', 'Evansville', 'Evant', 'Evaro', 'Evart', 'Evarts', 'Eveleth', 'Evendale', 'Evening Shade', 'Everest', 'Everett', 'Everetts', 'Everglades', 'Evergreen', 'Evergreen Park', 'Everly', 'Everman', 'Everson', 'Everton', 'Ewa Beach', 'Ewa Gentry', 'Ewa Villages', 'Ewing', 'Excel', 'Excelsior', 'Excelsior Estates', 'Excelsior Springs', 'Excursion Inlet', 'Exeland', 'Exeter', 'Exira', 'Exline', 'Exmore', 'Experiment', 'Export', 'Exton', 'Eyers Grove', 'Eyota', 'Fabens', 'Fabius', 'Factoryville', 'Fair Bluff', 'Fair Grove', 'Fair Haven', 'Fair Lawn', 'Fair Oaks', 'Fair Oaks Ranch', 'Fair Plain', 'Fair Play', 'Fairbank', 'Fairbanks', 'Fairbanks Ranch', 'Fairborn', 'Fairburn', 'Fairbury', 'Fairchance', 'Fairchild', 'Fairchild AFB', 'Fairchilds', 'Fairdale', 'Fairfax', 'Fairfield', 'Fairfield Bay', 'Fairfield Beach', 'Fairfield Glade', 'Fairfield Harbour', 'Fairgrove', 'Fairhope', 'Fairland', 'Fairlawn', 'Fairlea', 'Fairless Hills', 'Fairmeade', 'Fairmont', 'Fairmont City', 'Fairmount', 'Fairmount Heights', 'Fairplains', 'Fairplay', 'Fairport', 'Fairport Harbor', 'Fairton', 'Fairview', 'Fairview Beach', 'Fairview Heights', 'Fairview Lanes', 'Fairview Park', 'Fairview Shores', 'Fairview-Ferndale', 'Fairwater', 'Fairway', 'Fairwood', 'Faison', 'Faith', 'Fajardo', 'Falcon', 'Falcon Heights', 'Falcon Lake Estates', 'Falcon Mesa', 'Falcon Village', 'Falconer', 'Falfurrias', 'Falkland', 'Falkner', 'Falkville', 'Fall Branch', 'Fall City', 'Fall Creek', 'Fall River', 'Fall River Mills', 'Fallbrook', 'Falling Spring', 'Fallis', 'Fallon', 'Fallon Station', 'Falls Church', 'Falls City', 'Falls Creek', 'Fallston', 'Falman-County Acres', 'Falmouth', 'Falmouth Foreside', 'False Pass', 'Fancy Gap', 'Fanning Springs', 'Fanshawe', 'Fanwood', 'Far Hills', 'Farber', 'Fargo', 'Faribault', 'Farina', 'Farley', 'Farm Loop', 'Farmer', 'Farmer City', 'Farmers Branch', 'Farmersburg', 'Farmersville', 'Farmerville', 'Farmingdale', 'Farmington', 'Farmington Hills', 'Farmingville', 'Farmland', 'Farmville', 'Farnam', 'Farnham', 'Farnhamville', 'Farr West', 'Farragut', 'Farrell', 'Farson', 'Farwell', 'Fate', 'Faulkton', 'Faunsdale', 'Fawn Grove', 'Faxon', 'Fayette', 'Fayette City', 'Fayetteville', 'Faysville', 'Fearrington', 'Feasterville-Trevose', 'Feather Sound', 'Federal Dam', 'Federal Heights', 'Federal Way', 'Federalsburg', 'Felicity', 'Felida', 'Fellows', 'Fellsmere', 'Felsenthal', 'Felton', 'Fennimore', 'Fennville', 'Fenton', 'Fenwick', 'Fenwick Island', 'Fenwood', 'Ferdinand', 'Fergus Falls', 'Ferguson', 'Fern Acres', 'Fern Creek', 'Fern Forest', 'Fern Park', 'Fernan Lake Village', 'Fernandina Beach', 'Ferndale', 'Fernley', 'Fernville', 'Fernway', 'Ferrelview', 'Ferriday', 'Ferris', 'Ferron', 'Ferrum', 'Ferry', 'Ferry Pass', 'Ferrysburg', 'Ferryville', 'Fertile', 'Fessenden', 'Festus', 'Fetters Hot Springs-Agua Caliente', 'Fidelity', 'Fieldale', 'Fielding', 'Fieldon', 'Fieldsboro', 'Fife', 'Fife Lake', 'Fifth Street', 'Fifty Lakes', 'Fifty-Six', 'Filer', 'Filley', 'Fillmore', 'Fincastle', 'Findlay', 'Fingal', 'Finger', 'Finlayson', 'Finley', 'Finley Point', 'Finleyville', 'Finneytown', 'Fircrest', 'Fire Island', 'Firebaugh', 'Firestone', 'First Mesa', 'Firth', 'Firthcliffe', 'Fish Hawk', 'Fisher', 'Fisher Island', 'Fishers', 'Fishers Island', 'Fishersville', 'Fishhook', 'Fishkill', 'Fisk', 'Fiskdale', 'Fitchburg', 'Fithian', 'Fitzgerald', 'Fitzhugh', 'Five Corners', 'Five Forks', 'Five Points', 'Flagler', 'Flagler Beach', 'Flagstaff', 'Flanagan', 'Flanders', 'Flandreau', 'Flasher', 'Flat', 'Flat Rock', 'Flatonia', 'Flatwoods', 'Flaxton', 'Flaxville', 'Fleetwood', 'Fleischmanns', 'Fleming', 'Fleming-Neon', 'Flemingsburg', 'Flemington', 'Flensburg', 'Fletcher', 'Flint', 'Flint Creek', 'Flint Hill', 'Flippin', 'Flomaton', 'Floodwood', 'Flora', 'Flora Vista', 'Floral City', 'Floral Park', 'Florala', 'Flordell Hills', 'Florence', 'Florence-Graham', 'Florence-Roebling', 'Floresville', 'Florham Park', 'Florida', 'Florida City', 'Florida Ridge', 'Florien', 'Florin', 'Floris', 'Florissant', 'Flossmoor', 'Flourtown', 'Flovilla', 'Flowella', 'Flower Hill', 'Flower Mound', 'Flowery Branch', 'Flowing Wells', 'Flowood', 'Floyd', 'Floydada', 'Flushing', 'Flute Springs', 'Flying Hills', 'Folcroft', 'Foley', 'Folkston', 'Follansbee', 'Follett', 'Folly Beach', 'Folsom', 'Fond du Lac', 'Fonda', 'Fontana', 'Fontana-on-Geneva Lake', 'Fontanelle', 'Fontenelle', 'Foosland', 'Foothill Farms', 'Foothill Ranch', 'Footville', 'Forada', 'Foraker', 'Forbes', 'Ford', 'Ford City', 'Ford Cliff', 'Ford Heights', 'Fordland', 'Fordoche', 'Fords', 'Fords Prairie', 'Fordsville', 'Fordville', 'Fordyce', 'Foreman', 'Forest', 'Forest Acres', 'Forest City', 'Forest Glen', 'Forest Grove', 'Forest Heights', 'Forest Hill', 'Forest Hills', 'Forest Home', 'Forest Lake', 'Forest Meadows', 'Forest Oaks', 'Forest Park', 'Forest River', 'Forest View', 'Forestbrook', 'Forestdale', 'Foresthill', 'Foreston', 'Forestville', 'Forgan', 'Foristell', 'Forked River', 'Forkland', 'Forks', 'Forksville', 'Forman', 'Formoso', 'Forney', 'Forrest', 'Forrest City', 'Forreston', 'Forrestville', 'Forsan', 'Forsyth', 'Fort Ann', 'Fort Ashby', 'Fort Atkinson', 'Fort Belknap Agency', 'Fort Belvoir', 'Fort Benning South', 'Fort Benton', 'Fort Bliss', 'Fort Bragg', 'Fort Branch', 'Fort Bridger', 'Fort Calhoun', 'Fort Campbell North', 'Fort Carson', 'Fort Chiswell', 'Fort Cobb', 'Fort Coffee', 'Fort Collins', 'Fort Davis', 'Fort Defiance', 'Fort Deposit', 'Fort Devens', 'Fort Dix', 'Fort Dodge', 'Fort Drum', 'Fort Duchesne', 'Fort Edward', 'Fort Fairfield', 'Fort Gaines', 'Fort Garland', 'Fort Gay', 'Fort Gibson', 'Fort Greely', 'Fort Hall', 'Fort Hancock', 'Fort Hood', 'Fort Hunt', 'Fort Indiantown Gap', 'Fort Jennings', 'Fort Johnson', 'Fort Jones', 'Fort Kent', 'Fort Knox', 'Fort Laramie', 'Fort Lauderdale', 'Fort Lawn', 'Fort Lee', 'Fort Leonard Wood', 'Fort Lewis', 'Fort Loramie', 'Fort Lupton', 'Fort Madison', 'Fort McKinley', 'Fort Meade', 'Fort Mill', 'Fort Mitchell', 'Fort Montgomery', 'Fort Morgan', 'Fort Myers', 'Fort Myers Beach', 'Fort Myers Shores', 'Fort Oglethorpe', 'Fort Payne', 'Fort Peck', 'Fort Pierce', 'Fort Pierce North', 'Fort Pierce South', 'Fort Pierre', 'Fort Plain', 'Fort Polk North', 'Fort Polk South', 'Fort Ransom', 'Fort Recovery', 'Fort Riley North', 'Fort Riley-Camp Whiteside', 'Fort Ripley', 'Fort Ritchie', 'Fort Rucker', 'Fort Salonga', 'Fort Scott', 'Fort Shaw', 'Fort Shawnee', 'Fort Smith', 'Fort Stewart', 'Fort Stockton', 'Fort Sumner', 'Fort Supply', 'Fort Thomas', 'Fort Thompson', 'Fort Totten', 'Fort Towson', 'Fort Valley', 'Fort Walton Beach', 'Fort Washakie', 'Fort Washington', 'Fort Wayne', 'Fort White', 'Fort Worth', 'Fort Wright', 'Fort Yates', 'Fort Yukon', 'Fortescue', 'Fortine', 'Fortuna', 'Fortuna Foothills', 'Fortville', 'Forty Fort', 'Foss', 'Fossil', 'Fosston', 'Foster', 'Foster City', 'Fostoria', 'Fouke', 'Foundryville', 'Fountain', 'Fountain City', 'Fountain Green', 'Fountain Hill', 'Fountain Hills', 'Fountain Inn', 'Fountain Lake', 'Fountain N\' Lakes', 'Fountain Run', 'Fountain Springs', 'Fountain Valley', 'Fountainbleau', 'Fountainhead-Orchard Hills', 'Four Bears Village', 'Four Corners', 'Four Mile Road', 'Four Oaks', 'Fourche', 'Fowler', 'Fowlerton', 'Fowlerville', 'Fox', 'Fox Chapel', 'Fox Chase', 'Fox Farm-College', 'Fox Island', 'Fox Lake', 'Fox Lake Hills', 'Fox Point', 'Fox River', 'Fox River Grove', 'Fox River Valley Gardens', 'Fox Run', 'Foxborough', 'Foxburg', 'Foxfield', 'Foxfire', 'Foxhome', 'Foyil', 'Frackville', 'Framingham', 'Francesville', 'Francis', 'Francis Creek', 'Francisco', 'Franconia', 'Frankenmuth', 'Frankford', 'Frankfort', 'Frankfort Springs', 'Frankfort Square', 'Franklin', 'Franklin Furnace', 'Franklin Grove', 'Franklin Lakes', 'Franklin Park', 'Franklin Springs', 'Franklin Square', 'Franklinton', 'Franklintown', 'Franklinville', 'Frankston', 'Franksville', 'Frankton', 'Franktown', 'Frannie', 'Fraser', 'Frazee', 'Frazer', 'Frazeysburg', 'Frazier Park', 'Frederic', 'Frederica', 'Frederick', 'Fredericksburg', 'Frederickson', 'Fredericktown', 'Fredericktown-Millsboro', 'Frederika', 'Fredonia', 'Fredonia (Biscoe)', 'Free Soil', 'Freeborn', 'Freeburg', 'Freedom', 'Freehold', 'Freeland', 'Freeman', 'Freeman Spur', 'Freemansburg', 'Freeport', 'Freer', 'Freeville', 'Freistatt', 'Fremd Village-Padgett Island', 'Fremont', 'Fremont Hills', 'French Camp', 'French Gulch', 'French Island', 'French Lick', 'French Settlement', 'Frenchburg', 'Frenchtown', 'Frenchtown-Rumbly', 'Fresno', 'Frewsburg', 'Friant', 'Friars Point', 'Friday Harbor', 'Fridley', 'Friedens', 'Friedensburg', 'Friend', 'Friendly', 'Friendship', 'Friendship Village', 'Friendsville', 'Friendswood', 'Fries', 'Friesland', 'Friona', 'Frisco', 'Frisco City', 'Fritch', 'Fritz Creek', 'Frohna', 'Froid', 'Fromberg', 'Front Royal', 'Frontenac', 'Frontier', 'Fronton', 'Frost', 'Frostburg', 'Frostproof', 'Fruit Cove', 'Fruit Heights', 'Fruit Hill', 'Fruita', 'Fruitdale', 'Fruithurst', 'Fruitland', 'Fruitland Park', 'Fruitport', 'Fruitvale', 'Fruitville', 'Fryeburg', 'Fránquez', 'Fuig', 'Fulda', 'Fullerton', 'Fulshear', 'Fulton', 'Fultondale', 'Fultonham', 'Fultonville', 'Fults', 'Funk', 'Funkley', 'Funkstown', 'Funny River', 'Funston', 'Fuquay-Varina', 'Furman', 'Furnace Creek', 'Fussels Corner', 'Fyffe', 'G. L. García', 'Gaastra', 'Gabbs', 'Gackle', 'Gadsden', 'Gaffney', 'Gage', 'Gages Lake', 'Gagetown', 'Gahanna', 'Gaines', 'Gainesboro', 'Gainesville', 'Gaithersburg', 'Gakona', 'Galateo', 'Galatia', 'Galax', 'Galena', 'Galena Park', 'Galesburg', 'Galestown', 'Galesville', 'Galeton', 'Galeville', 'Galien', 'Galion', 'Galisteo', 'Gallatin', 'Gallaway', 'Galliano', 'Gallipolis', 'Gallitzin', 'Gallup', 'Galt', 'Galva', 'Galveston', 'Galway', 'Gamaliel', 'Gambell', 'Gambier', 'Game Creek', 'Gamewell', 'Ganado', 'Gandy', 'Gang Mills', 'Gann', 'Gans', 'Gantt', 'Gantts Quarry', 'Gap', 'Garber', 'Garceno', 'Garden', 'Garden Acres', 'Garden City', 'Garden City Park', 'Garden City South', 'Garden Grove', 'Garden Home-Whitford', 'Garden Plain', 'Garden Ridge', 'Garden View', 'Gardena', 'Gardendale', 'Gardere', 'Gardiner', 'Gardner', 'Gardnertown', 'Gardnerville', 'Gardnerville Ranchos', 'Garfield', 'Garfield Heights', 'Garibaldi', 'Garland', 'Garnavillo', 'Garner', 'Garnett', 'Garretson', 'Garrett', 'Garrett Park', 'Garrettsville', 'Garrison', 'Garrochales', 'Garvin', 'Garwin', 'Garwood', 'Gary', 'Gary City', 'Garysburg', 'Garyville', 'Gas', 'Gas City', 'Gasconade', 'Gascoyne', 'Gasport', 'Gassaway', 'Gassville', 'Gaston', 'Gastonia', 'Gastonville', 'Gate', 'Gate City', 'Gates', 'Gates Mills', 'Gates-North Gates', 'Gatesville', 'Gateway', 'Gatlinburg', 'Gattman', 'Gauley Bridge', 'Gautier', 'Gay', 'Gayle Mill', 'Gaylesville', 'Gaylord', 'Gays', 'Gays Mills', 'Gayville', 'Gazelle', 'Gearhart', 'Geary', 'Geddes', 'Geiger', 'Geistown', 'Gem', 'Gem Lake', 'Gene Autry', 'Genesee', 'Geneseo', 'Geneva', 'Geneva-on-the-Lake', 'Genoa', 'Genoa City', 'Genola', 'Gentry', 'Gentryville', 'George', 'George West', 'Georgetown', 'Georgiana', 'Gerald', 'Geraldine', 'Gerber-Las Flores', 'Gering', 'Gerlach-Empire', 'German Valley', 'Germantown', 'Germantown Hills', 'Geronimo', 'Gerster', 'Gerty', 'Gervais', 'Gettysburg', 'Geuda Springs', 'Ghent', 'Gholson', 'Gibbon', 'Gibbs', 'Gibbsboro', 'Gibbstown', 'Gibraltar', 'Gibsland', 'Gibson', 'Gibsonburg', 'Gibsonia', 'Gibsonton', 'Gibsonville', 'Giddings', 'Gideon', 'Gifford', 'Gig Harbor', 'Gila Bend', 'Gilbert', 'Gilbert Creek', 'Gilberton', 'Gilbertown', 'Gilberts', 'Gilbertsville', 'Gilbertville', 'Gilboa', 'Gilby', 'Gilcrest', 'Gildford', 'Gilead', 'Gilgo-Oak Beach-Captree', 'Gillespie', 'Gillett', 'Gillett Grove', 'Gillette', 'Gillham', 'Gilliam', 'Gillsville', 'Gilman', 'Gilman City', 'Gilmer', 'Gilmore', 'Gilmore City', 'Gilroy', 'Gilt Edge', 'Giltner', 'Girard', 'Girardville', 'Girdletree', 'Gisela', 'Glacier', 'Glacier View', 'Gladbrook', 'Glade', 'Glade Spring', 'Gladeview', 'Gladewater', 'Gladstone', 'Gladwin', 'Glandorf', 'Glasco', 'Glasford', 'Glasgow', 'Glasgow Village', 'Glassboro', 'Glassport', 'Glastonbury Center', 'Gleason', 'Gleed', 'Glen', 'Glen Allen', 'Glen Alpine', 'Glen Avon', 'Glen Burnie', 'Glen Campbell', 'Glen Carbon', 'Glen Cove', 'Glen Dale', 'Glen Echo', 'Glen Echo Park', 'Glen Elder', 'Glen Ellen', 'Glen Ellyn', 'Glen Flora', 'Glen Gardner', 'Glen Head', 'Glen Hope', 'Glen Lyn', 'Glen Lyon', 'Glen Park', 'Glen Raven', 'Glen Ridge', 'Glen Rock', 'Glen Rose', 'Glen St. Mary', 'Glen Ullin', 'Glenaire', 'Glenarden', 'Glenbeulah', 'Glenburn', 'Glencoe', 'Glendale', 'Glendale Heights', 'Glendive', 'Glendo', 'Glendon', 'Glendora', 'Gleneagle', 'Glenfield', 'Glenford', 'Glenham', 'Glenmont', 'Glenmoor', 'Glenmora', 'Glenn Dale', 'Glenn Heights', 'Glennallen', 'Glenns Ferry', 'Glennville', 'Glenolden', 'Glenpool', 'Glenrock', 'Glens Falls', 'Glens Falls North', 'Glenside', 'Glenvar Heights', 'Glenview', 'Glenview Hills', 'Glenview Manor', 'Glenvil', 'Glenville', 'Glenwillow', 'Glenwood', 'Glenwood City', 'Glenwood Landing', 'Glenwood Springs', 'Glidden', 'Glide', 'Globe', 'Gloria Glens Park', 'Glorieta', 'Gloster', 'Gloucester', 'Gloucester City', 'Gloucester Courthouse', 'Gloucester Point', 'Glouster', 'Gloversville', 'Gloverville', 'Glyndon', 'Gnadenhutten', 'Gobles', 'Goddard', 'Godfrey', 'Godfrey Road', 'Godley', 'Godwin', 'Goehner', 'Goessel', 'Goff', 'Golconda', 'Gold Bar', 'Gold Beach', 'Gold Camp', 'Gold Hill', 'Gold River', 'Golden', 'Golden Beach', 'Golden City', 'Golden Gate', 'Golden Glades', 'Golden Grove', 'Golden Heights', 'Golden Hills', 'Golden Lakes', 'Golden Meadow', 'Golden Triangle', 'Golden Valley', 'Golden\'s Bridge', 'Goldendale', 'Goldenrod', 'Goldfield', 'Goldonna', 'Goldsboro', 'Goldsby', 'Goldsmith', 'Goldston', 'Goldthwaite', 'Goldville', 'Goleta', 'Golf', 'Golf Manor', 'Goliad', 'Golinda', 'Golovin', 'Goltry', 'Golva', 'Gonvick', 'Gonzales', 'Gonzalez', 'Good Hope', 'Good Thunder', 'Goodell', 'Goodfield', 'Goodhue', 'Gooding', 'Goodings Grove', 'Goodland', 'Goodlettsville', 'Goodlow', 'Goodman', 'Goodnews Bay', 'Goodrich', 'Goodridge', 'Goodsprings', 'Goodview', 'Goodwater', 'Goodwell', 'Goodwin', 'Goodyear', 'Goose Creek', 'Goose Lake', 'Gopher Flats', 'Gordo', 'Gordon', 'Gordon Heights', 'Gordonsville', 'Gordonville', 'Gore', 'Goree', 'Goreville', 'Gorham', 'Gorman', 'Goshen', 'Gosnell', 'Gosport', 'Gotebo', 'Gotha', 'Gothenburg', 'Gould', 'Goulding', 'Goulds', 'Gouverneur', 'Govan', 'Gove City', 'Gowanda', 'Gower', 'Gowrie', 'Grabill', 'Grace', 'Grace City', 'Gracemont', 'Graceville', 'Grady', 'Graeagle', 'Graettinger', 'Graf', 'Graford', 'Grafton', 'Graham', 'Grain Valley', 'Grainfield', 'Grainola', 'Grambling', 'Gramercy', 'Grampian', 'Granada', 'Granbury', 'Granby', 'Grand Acres', 'Grand Bay', 'Grand Beach', 'Grand Blanc', 'Grand Cane', 'Grand Canyon Village', 'Grand Coteau', 'Grand Coulee', 'Grand Encampment', 'Grand Falls Plaza', 'Grand Forks', 'Grand Forks AFB', 'Grand Haven', 'Grand Island', 'Grand Isle', 'Grand Junction', 'Grand Lake', 'Grand Lake Towne', 'Grand Ledge', 'Grand Marais', 'Grand Meadow', 'Grand Mound', 'Grand Pass', 'Grand Prairie', 'Grand Rapids', 'Grand Ridge', 'Grand River', 'Grand Rivers', 'Grand Ronde', 'Grand Saline', 'Grand Terrace', 'Grand Tower', 'Grand View', 'Grand View Estates', 'Grand View-on-Hudson', 'Grandfalls', 'Grandfather', 'Grandfield', 'Grandin', 'Grandview', 'Grandview Heights', 'Grandview Plaza', 'Grandville', 'Grandwood Park', 'Granger', 'Grangeville', 'Granite', 'Granite Bay', 'Granite City', 'Granite Falls', 'Granite Hills', 'Granite Quarry', 'Granite Shoals', 'Graniteville-East Barre', 'Granjeno', 'Grannis', 'Grano', 'Grant', 'Grant City', 'Grant Park', 'Grant Town', 'Grantfork', 'Grantley', 'Granton', 'Grants', 'Grants Pass', 'Grantsburg', 'Grantsville', 'Grantville', 'Grantwood Village', 'Granville', 'Granville South', 'Grape Creek', 'Grapeland', 'Grapeville', 'Grapevine', 'Grasonville', 'Grass Lake', 'Grass Range', 'Grass Valley', 'Grasston', 'Gratiot', 'Gratis', 'Graton', 'Gratz', 'Gravel Ridge', 'Gravette', 'Gravity', 'Gravois Mills', 'Gray', 'Gray Court', 'Gray Summit', 'Grayland', 'Grayling', 'Graymoor-Devondale', 'Grays Prairie', 'Grayslake', 'Grayson', 'Grayson Valley', 'Graysville', 'Grayville', 'Greasewood', 'Greasy', 'Great Barrington', 'Great Bend', 'Great Falls', 'Great Meadows-Vienna', 'Great Neck', 'Great Neck Estates', 'Great Neck Gardens', 'Great Neck Plaza', 'Great River', 'Greater Carrollwood', 'Greater Galesburg', 'Greater Landover', 'Greater Northdale', 'Greater Sun Center', 'Greater Upper Marlboro', 'Greatwood', 'Greece', 'Greeley', 'Greeley Center', 'Greeleyville', 'Green', 'Green Acres', 'Green Bay', 'Green Camp', 'Green City', 'Green Cove Springs', 'Green Forest', 'Green Grass', 'Green Harbor-Cedar Crest', 'Green Haven', 'Green Hill', 'Green Hills', 'Green Island', 'Green Isle', 'Green Lake', 'Green Lane', 'Green Level', 'Green Meadow', 'Green Meadows', 'Green Mountain Falls', 'Green Oaks', 'Green Park', 'Green Ridge', 'Green River', 'Green Spring', 'Green Springs', 'Green Tree', 'Green Valley', 'Green Valley Farms', 'Greenacres', 'Greenback', 'Greenbelt', 'Greenbrier', 'Greenbush', 'Greencastle', 'Greendale', 'Greene', 'Greenevers', 'Greeneville', 'Greenfield', 'Greenhills', 'Greenhorn', 'Greenland', 'Greenlawn', 'Greenleaf', 'Greenport', 'Greenport West', 'Greens Fork', 'Greensboro', 'Greensburg', 'Greentop', 'Greentown', 'Greentree', 'Greenup', 'Greenvale', 'Greenview', 'Greenville', 'Greenwald', 'Greenwater', 'Greenway', 'Greenwich', 'Greenwood', 'Greenwood Lake', 'Greenwood Village', 'Greer', 'Greers Ferry', 'Gregory', 'Greilickville', 'Grenada', 'Grenola', 'Grenora', 'Grenville', 'Gresham', 'Gresham Park', 'Gretna', 'Grey Eagle', 'Grey Forest', 'Greybull', 'Greycliff', 'Gridley', 'Grier City-Park Crest', 'Griffin', 'Griffith', 'Griffithville', 'Grifton', 'Griggsville', 'Grimes', 'Grimesland', 'Grindstone-Rowes Run', 'Grinnell', 'Grissom AFB', 'Griswold', 'Groesbeck', 'Groom', 'Gross', 'Grosse Ile', 'Grosse Pointe', 'Grosse Pointe Farms', 'Grosse Pointe Park', 'Grosse Pointe Shores', 'Grosse Pointe Woods', 'Grosse Tete', 'Groton', 'Groton Long Point', 'Grottoes', 'Grove', 'Grove City', 'Grove Hill', 'Groveland', 'Groveland-Big Oak Flat', 'Groveport', 'Grover', 'Grover Beach', 'Grover Hill', 'Groves', 'Groveton', 'Grovetown', 'Grubbs', 'Gruetli-Laager', 'Grundy', 'Grundy Center', 'Gruver', 'Grygla', 'Gu-Win', 'Guadalupe', 'Guayabal', 'Guayama', 'Guayanilla', 'Guaynabo', 'Guerneville', 'Guernsey', 'Guerra', 'Gueydan', 'Guide Rock', 'Guilford', 'Guilford Center', 'Guin', 'Guion', 'Gulf Breeze', 'Gulf Gate Estates', 'Gulf Hills', 'Gulf Park Estates', 'Gulf Port', 'Gulf Shores', 'Gulf Stream', 'Gulfport', 'Gulivoire Park', 'Gulkana', 'Gully', 'Gum Springs', 'Gumbranch', 'Gumlog', 'Gun Barrel City', 'Gun Club Estates', 'Gunbarrel', 'Gunn City', 'Gunnison', 'Gunter', 'Guntersville', 'Guntown', 'Gurabo', 'Gurdon', 'Gurley', 'Gurnee', 'Gustavus', 'Gustine', 'Guthrie', 'Guthrie Center', 'Guttenberg', 'Guy', 'Guymon', 'Guys', 'Guys Mills', 'Guyton', 'Guánica', 'Gwinn', 'Gwinner', 'Gypsum', 'H. Rivera Colón', 'Hacienda Heights', 'Hackberry', 'Hackensack', 'Hackett', 'Hackettstown', 'Hackleburg', 'Hadar', 'Haddam', 'Haddon Heights', 'Haddonfield', 'Hadley', 'Hagaman', 'Hagan', 'Hagerman', 'Hagerstown', 'Hague', 'Hahira', 'Hahnville', 'Haigler', 'Haiku-Pauwela', 'Hailey', 'Haileyville', 'Haines', 'Haines City', 'Hainesville', 'Halaula', 'Halawa', 'Halbur', 'Halchita', 'Hale', 'Hale Center', 'Haleburg', 'Haledon', 'Haleiwa', 'Hales Corners', 'Halesite', 'Haleyville', 'Half Moon', 'Half Moon Bay', 'Halfway', 'Halfway House', 'Halibut Cove', 'Halifax', 'Haliimaile', 'Hall Park', 'Hall Summit', 'Hallam', 'Hallandale', 'Hallett', 'Hallettsville', 'Halliday', 'Hallock', 'Hallowell', 'Halls', 'Halls Crossing', 'Hallsburg', 'Hallstead', 'Hallsville', 'Halltown', 'Hallwood', 'Halma', 'Halsey', 'Halstad', 'Halstead', 'Haltom City', 'Ham Lake', 'Hamberg', 'Hambleton', 'Hamburg', 'Hamden', 'Hamel', 'Hamer', 'Hamersville', 'Hamill', 'Hamilton', 'Hamilton Branch', 'Hamilton City', 'Hamler', 'Hamlet', 'Hamlin', 'Hammon', 'Hammond', 'Hammondsport', 'Hammondville', 'Hammonton', 'Hampden', 'Hampden Sydney', 'Hampshire', 'Hampstead', 'Hampton', 'Hampton Bays', 'Hampton Manor', 'Hampton Township', 'Hamptons at Boca Raton', 'Hamtramck', 'Hana', 'Hanaford', 'Hanahan', 'Hanalei', 'Hanamaulu', 'Hanapepe', 'Hanceville', 'Hancock', 'Handley', 'Hanford', 'Hanging Rock', 'Hankinson', 'Hanley Falls', 'Hanley Hills', 'Hanlontown', 'Hanna', 'Hanna City', 'Hannaford', 'Hannah', 'Hannahs Mill', 'Hannibal', 'Hanover', 'Hanover Park', 'Hanoverton', 'Hansboro', 'Hansell', 'Hansen', 'Hanska', 'Hanson', 'Hanston', 'Hapeville', 'Happy', 'Happy Valley', 'Harahan', 'Haralson', 'Harbeck-Fruitdale', 'Harbine', 'Harbison Canyon', 'Harbor', 'Harbor Beach', 'Harbor Bluffs', 'Harbor Hills', 'Harbor Isle', 'Harbor Springs', 'Harbor View', 'Harbour Heights', 'Harcourt', 'Hardeeville', 'Hardesty', 'Hardin', 'Harding', 'Harding-Birch Lakes', 'Hardinsburg', 'Hardtner', 'Hardwick', 'Hardy', 'Harker Heights', 'Harkers Island', 'Harlan', 'Harlem', 'Harlem Heights', 'Harleysville', 'Harleyville', 'Harlingen', 'Harlowton', 'Harman', 'Harmon', 'Harmonsburg', 'Harmony', 'Harmony Township', 'Harper', 'Harper Woods', 'Harpers Ferry', 'Harpersville', 'Harpster', 'Harrah', 'Harrell', 'Harrells', 'Harrellsville', 'Harrietta', 'Harriman', 'Harrington', 'Harrington Park', 'Harris', 'Harris Hill', 'Harrisburg', 'Harrison', 'Harrison City', 'Harrison Township', 'Harrisonburg', 'Harrisonville', 'Harristown', 'Harrisville', 'Harrod', 'Harrodsburg', 'Harrogate-Shawanee', 'Harrold', 'Hart', 'Hartford', 'Hartford City', 'Hartington', 'Hartland', 'Hartleton', 'Hartley', 'Hartline', 'Hartly', 'Hartman', 'Hartrandt', 'Harts', 'Hartsburg', 'Hartsdale', 'Hartselle', 'Hartshorne', 'Hartstown', 'Hartsville', 'Hartville', 'Hartwell', 'Hartwick', 'Harvard', 'Harvel', 'Harvest', 'Harvey', 'Harvey Cedars', 'Harveys Lake', 'Harveysburg', 'Harveyville', 'Harwich Center', 'Harwich Port', 'Harwood', 'Harwood Heights', 'Hasbrouck Heights', 'Haskell', 'Haskins', 'Haslet', 'Haslett', 'Hassell', 'Hasson Heights', 'Hastings', 'Hastings-on-Hudson', 'Haswell', 'Hatboro', 'Hatch', 'Hatfield', 'Hatillo', 'Hatley', 'Hato Arriba', 'Hato Candal', 'Hattiesburg', 'Hatton', 'Haubstadt', 'Haugen', 'Haughton', 'Hauppauge', 'Hauser', 'Hauula', 'Havana', 'Havelock', 'Haven', 'Havensville', 'Haverhill', 'Haverstraw', 'Haviland', 'Havre', 'Havre North', 'Havre de Grace', 'Haw River', 'Hawaiian Acres', 'Hawaiian Beaches', 'Hawaiian Gardens', 'Hawaiian Ocean View', 'Hawaiian Paradise Park', 'Hawarden', 'Hawesville', 'Hawi', 'Hawk Cove', 'Hawk Point', 'Hawk Springs', 'Hawkeye', 'Hawkins', 'Hawkinsville', 'Hawley', 'Haworth', 'Hawthorn', 'Hawthorn Woods', 'Hawthorne', 'Haxtun', 'Hay Springs', 'Hayden', 'Hayden Lake', 'Hayes Center', 'Hayesville', 'Hayfield', 'Hayfork', 'Haymarket', 'Haynes', 'Haynesville', 'Hayneville', 'Hays', 'Haysi', 'Haysville', 'Hayti', 'Hayti Heights', 'Hayward', 'Haywood City', 'Hazard', 'Hazardville', 'Hazel', 'Hazel Crest', 'Hazel Dell North', 'Hazel Dell South', 'Hazel Green', 'Hazel Park', 'Hazel Run', 'Hazelton', 'Hazelwood', 'Hazen', 'Hazlehurst', 'Hazleton', 'Head of the Harbor', 'Headland', 'Headrick', 'Healdsburg', 'Healdton', 'Healy', 'Healy Lake', 'Hearne', 'Heart Butte', 'Heartwell', 'Heath', 'Heath Springs', 'Heathcote', 'Heathrow', 'Heavener', 'Hebbronville', 'Heber', 'Heber Springs', 'Heber-Overgaard', 'Hebo', 'Hebron', 'Hebron Estates', 'Hecker', 'Heckscherville', 'Hecla', 'Hector', 'Hedgesville', 'Hedley', 'Hedrick', 'Hedwig Village', 'Heeia', 'Heflin', 'Heidelberg', 'Heilwood', 'Helen', 'Helena', 'Helena Valley Northeast', 'Helena Valley Northwest', 'Helena Valley Southeast', 'Helena Valley West Central', 'Helena West Side', 'Helenville', 'Helenwood', 'Helix', 'Hellertown', 'Helmetta', 'Helotes', 'Helper', 'Hemby Bridge', 'Hemet', 'Hemingford', 'Hemingway', 'Hemlock', 'Hemphill', 'Hempstead', 'Henagar', 'Henderson', 'Hendersonville', 'Hendley', 'Hendricks', 'Hendrix', 'Hendron', 'Hendrum', 'Henefer', 'Henlopen Acres', 'Hennepin', 'Hennessey', 'Henniker', 'Henning', 'Henrietta', 'Henriette', 'Henrieville', 'Henry', 'Henryetta', 'Henryville', 'Hensley', 'Hepburn', 'Hephzibah', 'Hepler', 'Heppner', 'Herald Harbor', 'Herculaneum', 'Hercules', 'Hereford', 'Herington', 'Heritage Hills', 'Heritage Village', 'Herkimer', 'Herman', 'Hermann', 'Hermantown', 'Herminie', 'Hermiston', 'Hermitage', 'Hermleigh', 'Hermon', 'Hermosa', 'Hermosa Beach', 'Hernando', 'Hernando Beach', 'Herndon', 'Heron', 'Heron Lake', 'Herreid', 'Herrick', 'Herricks', 'Herriman', 'Herrin', 'Herrings', 'Herron', 'Herscher', 'Hersey', 'Hershey', 'Hertford', 'Hesperia', 'Hessmer', 'Hesston', 'Hetland', 'Hettick', 'Hettinger', 'Heuvelton', 'Hewitt', 'Hewlett', 'Hewlett Bay Park', 'Hewlett Harbor', 'Hewlett Neck', 'Heyburn', 'Heyworth', 'Hi-Nella', 'Hialeah', 'Hialeah Gardens', 'Hiawassee', 'Hiawatha', 'Hibbing', 'Hickam Housing', 'Hickman', 'Hickory', 'Hickory Creek', 'Hickory Flat', 'Hickory Grove', 'Hickory Hill', 'Hickory Hills', 'Hickory Ridge', 'Hickory Valley', 'Hickory Withe', 'Hicksville', 'Hico', 'Hidalgo', 'Hidden Hills', 'Hidden Meadows', 'Hidden Valley', 'Hidden Valley Lake', 'Higbee', 'Higden', 'Higganum', 'Higgins', 'Higginson', 'Higginsport', 'Higginsville', 'Higgston', 'High Bridge', 'High Falls', 'High Hill', 'High Point', 'High Ridge', 'High Shoals', 'High Springs', 'Highfield-Cascade', 'Highfill', 'Highgrove', 'Highland', 'Highland Acres', 'Highland Beach', 'Highland City', 'Highland Falls', 'Highland Haven', 'Highland Heights', 'Highland Hills', 'Highland Lake', 'Highland Mills', 'Highland Park', 'Highland Springs', 'Highland Village', 'Highlands', 'Highlands Ranch', 'Highlands-Baywood Park', 'Highlandville', 'Highmore', 'Highspire', 'Hightstown', 'Hightsville', 'Highview', 'Highwood', 'Hiland Park', 'Hilbert', 'Hilda', 'Hildale', 'Hildebran', 'Hildreth', 'Hill \'n Dale', 'Hill City', 'Hill Country Village', 'Hill View Heights', 'Hillandale', 'Hillburn', 'Hillcrest', 'Hillcrest Heights', 'Hiller', 'Hilliard', 'Hillman', 'Hillrose', 'Hills', 'Hills and Dales', 'Hillsboro', 'Hillsboro Beach', 'Hillsboro Pines', 'Hillsboro Ranches', 'Hillsborough', 'Hillsdale', 'Hillside', 'Hillside Lake', 'Hillsmere Shores', 'Hillsview', 'Hillsville', 'Hilltop', 'Hillview', 'Hilmar-Irwin', 'Hilo', 'Hilshire Village', 'Hilton', 'Hilton Head Island', 'Hiltonia', 'Hinckley', 'Hindman', 'Hindsboro', 'Hindsville', 'Hines', 'Hinesville', 'Hingham', 'Hinsdale', 'Hinton', 'Hiram', 'Hiseville', 'Hitchcock', 'Hitchita', 'Hitterdal', 'Hixton', 'Ho-Ho-Kus', 'Hoback', 'Hobart', 'Hobart Bay', 'Hobbs', 'Hobe Sound', 'Hoberg', 'Hobgood', 'Hoboken', 'Hobson', 'Hobson City', 'Hockessin', 'Hockinson', 'Hodge', 'Hodgenville', 'Hodges', 'Hodgkins', 'Hoffman', 'Hoffman Estates', 'Hogansville', 'Hohenwald', 'Hoisington', 'Hokah', 'Hokendauqua', 'Hokes Bluff', 'Holbrook', 'Holcomb', 'Holden', 'Holden Beach', 'Holden Heights', 'Holdenville', 'Holdingford', 'Holdrege', 'Holgate', 'Holiday', 'Holiday City', 'Holiday City South', 'Holiday City-Berkeley', 'Holiday Heights', 'Holiday Hills', 'Holiday Lakes', 'Holiday Valley', 'Holladay', 'Holland', 'Holland Patent', 'Hollandale', 'Hollansburg', 'Hollenberg', 'Holley', 'Holliday', 'Hollidaysburg', 'Hollins', 'Hollis', 'Hollister', 'Holloman AFB', 'Hollow Creek', 'Hollow Rock', 'Holloway', 'Hollowayville', 'Holly', 'Holly Grove', 'Holly Hill', 'Holly Pond', 'Holly Ridge', 'Holly Springs', 'Hollyvilla', 'Hollywood', 'Hollywood Park', 'Holmen', 'Holmes Beach', 'Holmesville', 'Holstein', 'Holt', 'Holton', 'Holts Summit', 'Holtsville', 'Holtville', 'Holualoa', 'Holy Cross', 'Holyoke', 'Holyrood', 'Homa Hills', 'Home Garden', 'Home Gardens', 'Homeacre-Lyndora', 'Homecroft', 'Homedale', 'Homeland', 'Homeland Park', 'Homer', 'Homer City', 'Homerville', 'Homestead', 'Homestead Base', 'Homestead Meadows North', 'Homestead Meadows South', 'Homestown', 'Hometown', 'Homewood', 'Homewood Canyon-Valley Wells', 'Hominy', 'Homosassa', 'Homosassa Springs', 'Honaker', 'Honalo', 'Honaunau-Napoopoo', 'Hondo', 'Honea Path', 'Honeoye Falls', 'Honesdale', 'Honey Brook', 'Honey Grove', 'Honeyville', 'Honokaa', 'Honolulu', 'Honomu', 'Honor', 'Hood River', 'Hooker', 'Hookerton', 'Hooks', 'Hooksett', 'Hookstown', 'Hoonah', 'Hooper', 'Hooper Bay', 'Hoopeston', 'Hoople', 'Hooppole', 'Hoosick Falls', 'Hoot Owl', 'Hoover', 'Hooverson Heights', 'Hooversville', 'Hop Bottom', 'Hopatcong', 'Hope', 'Hope Mills', 'Hope Valley', 'Hopedale', 'Hopewell', 'Hopewell Junction', 'Hopkins', 'Hopkins Park', 'Hopkinsville', 'Hopkinton', 'Hopwood', 'Hoquiam', 'Horace', 'Horatio', 'Hordville', 'Horicon', 'Horine', 'Horizon City', 'Hormigueros', 'Horn Hill', 'Horn Lake', 'Hornbeak', 'Hornbeck', 'Hornbrook', 'Hornell', 'Hornersville', 'Hornick', 'Hornsby', 'Horntown', 'Horse Cave', 'Horse Pasture', 'Horseheads', 'Horseheads North', 'Horseshoe Bay', 'Horseshoe Beach', 'Horseshoe Bend', 'Horseshoe Lake', 'Horsham', 'Horton', 'Hortonville', 'Hoschton', 'Hoskins', 'Hosmer', 'Hospers', 'Hosston', 'Hot Springs', 'Hot Springs Village', 'Hot Sulphur Springs', 'Hotchkiss', 'Hotevilla-Bacavi', 'Houck', 'Houghton', 'Houghton Lake', 'Houlton', 'Houma', 'Housatonic', 'House', 'Houserville', 'Houston', 'Houston Acres', 'Houston Lake', 'Houstonia', 'Houtzdale', 'Hove Mobile Park', 'Hoven', 'Howard', 'Howard City', 'Howard Lake', 'Howards Grove', 'Howardville', 'Howardwick', 'Howe', 'Howell', 'Howells', 'Howey-in-the-Hills', 'Howland', 'Howland Center', 'Hoxie', 'Hoyleton', 'Hoyt', 'Hoyt Lakes', 'Hoytville', 'Huachuca City', 'Hubbard', 'Hubbard Lake', 'Hubbardston', 'Hubbell', 'Huber Heights', 'Huber Ridge', 'Hudson', 'Hudson Bend', 'Hudson Falls', 'Hudson Oaks', 'Hudsonville', 'Huerfano', 'Huetter', 'Huey', 'Hueytown', 'Hughes', 'Hughes Springs', 'Hughestown', 'Hughesville', 'Hughson', 'Hugo', 'Hugoton', 'Huguley', 'Hulbert', 'Hulett', 'Hull', 'Hulmeville', 'Humacao', 'Humansville', 'Humble', 'Humboldt', 'Humboldt Hill', 'Hume', 'Humeston', 'Hummels Wharf', 'Hummelstown', 'Humnoke', 'Humphrey', 'Humphreys', 'Humptulips', 'Hundred', 'Hungerford', 'Hungry Horse', 'Hunker', 'Hunnewell', 'Hunter', 'Hunters Creek', 'Hunters Creek Village', 'Hunters Hollow', 'Huntersville', 'Huntertown', 'Hunting Valley', 'Huntingburg', 'Huntingdon', 'Huntington', 'Huntington Bay', 'Huntington Beach', 'Huntington Park', 'Huntington Station', 'Huntington Woods', 'Huntingtown', 'Huntland', 'Huntleigh', 'Huntley', 'Hunts Point', 'Huntsville', 'Hurdland', 'Hurdsfield', 'Hurley', 'Hurlock', 'Huron', 'Hurricane', 'Hurst', 'Hurstbourne', 'Hurstbourne Acres', 'Hurt', 'Hurtsboro', 'Huslia', 'Hustisford', 'Hustler', 'Hustonville', 'Hutchins', 'Hutchinson', 'Hutchinson Island South', 'Hutsonville', 'Huttig', 'Hutto', 'Huttonsville', 'Huxley', 'Hyannis', 'Hyattsville', 'Hyattville', 'Hybla Valley', 'Hydaburg', 'Hyde', 'Hyde Park', 'Hyden', 'Hyder', 'Hydesville', 'Hydetown', 'Hydro', 'Hymera', 'Hyndman', 'Hypoluxo', 'Hyrum', 'Hysham', 'Hytop', 'Iaeger', 'Iatan', 'Iberia', 'Icard', 'Ida', 'Ida Grove', 'Idabel', 'Idaho City', 'Idaho Falls', 'Idaho Springs', 'Idalou', 'Idanha', 'Ideal', 'Ider', 'Idyllwild-Pine Cove', 'Idylwood', 'Igiugig', 'Ignacio', 'Ihlen', 'Ila', 'Iliamna', 'Iliff', 'Ilion', 'Illiopolis', 'Ilwaco', 'Imbler', 'Imboden', 'Imbéry', 'Imlay City', 'Immokalee', 'Imogene', 'Impact', 'Imperial', 'Imperial Beach', 'Imperial-Enlow', 'Ina', 'Inchelium', 'Incline Village-Crystal Bay', 'Independence', 'Index', 'India Hook', 'Indiahoma', 'Indialantic', 'Indian Beach', 'Indian Creek', 'Indian Falls', 'Indian Harbour Beach', 'Indian Head', 'Indian Head Park', 'Indian Heights', 'Indian Hills', 'Indian Lake', 'Indian Point', 'Indian River', 'Indian River Estates', 'Indian River Shores', 'Indian Rocks Beach', 'Indian Shores', 'Indian Springs', 'Indian Springs Village', 'Indian Trail', 'Indian Village', 'Indian Wells', 'Indiana', 'Indianapolis', 'Indianola', 'Indiantown', 'Indio', 'Indios', 'Industry', 'Inez', 'Ingalls', 'Ingalls Park', 'Ingenio', 'Ingleside', 'Ingleside on the Bay', 'Inglewood', 'Inglewood-Finn Hill', 'Inglis', 'Ingold', 'Ingram', 'Inkom', 'Inkster', 'Inman', 'Inman Mills', 'Inniswold', 'Innsbrook', 'Inola', 'Interior', 'Interlachen', 'Interlaken', 'International Falls', 'Inver Grove Heights', 'Inverness', 'Inverness Highlands North', 'Inverness Highlands South', 'Inwood', 'Inyokern', 'Iola', 'Iona', 'Ione', 'Ionia', 'Iota', 'Iowa', 'Iowa City', 'Iowa Colony', 'Iowa Falls', 'Iowa Park', 'Ipava', 'Ipswich', 'Iraan', 'Iredell', 'Irena', 'Irene', 'Ireton', 'Irmo', 'Iron City', 'Iron Gate', 'Iron Horse', 'Iron Junction', 'Iron Mountain', 'Iron Mountain Lake', 'Iron Post', 'Iron Ridge', 'Iron River', 'Irondale', 'Irondequoit', 'Ironton', 'Ironwood', 'Iroquois', 'Iroquois Point', 'Irrigon', 'Irvine', 'Irving', 'Irvington', 'Irvona', 'Irwin', 'Irwindale', 'Irwinton', 'Isabel', 'Isabela', 'Isanti', 'Iselin', 'Ishpeming', 'Isla Vista', 'Islamorada, Village of Islands', 'Island', 'Island City', 'Island Heights', 'Island Lake', 'Island Park', 'Island Pond', 'Islandia', 'Isle', 'Isle of Hope', 'Isle of Palms', 'Isleta Village Proper', 'Isleton', 'Islip', 'Islip Terrace', 'Ismay', 'Isola', 'Issaquah', 'Istachatta', 'Italy', 'Itasca', 'Ithaca', 'Itta Bena', 'Iuka', 'Iva', 'Ivanhoe', 'Ivanhoe Estates', 'Ivanof Bay', 'Ives Estates', 'Ivesdale', 'Ivey', 'Ivins', 'Ivor', 'Ivyland', 'Ixonia', 'JAARS', 'Jacinto City', 'Jacksboro', 'Jackson', 'Jackson Center', 'Jackson Junction', 'Jacksonburg', 'Jacksonport', 'Jacksons\' Gap', 'Jacksonville', 'Jacksonville Beach', 'Jacob City', 'Jacobus', 'Jaconita', 'Jaffrey', 'Jagual', 'Jakin', 'Jal', 'Jamaica', 'Jamaica Beach', 'James City', 'James Town', 'Jamesburg', 'Jameson', 'Jamesport', 'Jamestown', 'Jamestown West', 'Jamesville', 'Jamison City', 'Jamul', 'Jan Phyl Village', 'Jane Lew', 'Janesville', 'Jansen', 'Jarales', 'Jarratt', 'Jarrettsville', 'Jasmine Estates', 'Jasonville', 'Jasper', 'Jauca', 'Java', 'Jay', 'Jayton', 'Jayuya', 'Jean Lafitte', 'Jeanerette', 'Jeannette', 'Jeddito', 'Jeddo', 'Jeffers', 'Jefferson', 'Jefferson City', 'Jefferson Heights', 'Jefferson Hills', 'Jefferson Valley-Yorktown', 'Jeffersontown', 'Jeffersonville', 'Jeffrey City', 'Jeisyville', 'Jellico', 'Jemez Pueblo', 'Jemez Springs', 'Jemison', 'Jena', 'Jenera', 'Jenison', 'Jenkins', 'Jenkinsburg', 'Jenkintown', 'Jenks', 'Jennerstown', 'Jennette', 'Jennings', 'Jennings Lodge', 'Jensen Beach', 'Jericho', 'Jerico Springs', 'Jermyn', 'Jerome', 'Jeromesville', 'Jerry City', 'Jersey', 'Jersey City', 'Jersey Shore', 'Jersey Village', 'Jerseytown', 'Jerseyville', 'Jerusalem', 'Jessup', 'Jesup', 'Jet', 'Jetmore', 'Jette', 'Jewell', 'Jewell Junction', 'Jewett', 'Jewett City', 'Jim Thorpe', 'Joanna', 'Joaquin', 'Jobos', 'Johannesburg', 'John Day', 'John Sam Lake', 'Johnsburg', 'Johnson', 'Johnson City', 'Johnson Creek', 'Johnson Lane', 'Johnsonburg', 'Johnsonville', 'Johnston', 'Johnston City', 'Johnstown', 'Johnsville', 'Joice', 'Joiner', 'Joliet', 'Jolivue', 'Jolley', 'Jolly', 'Jollyville', 'Jones', 'Jones Creek', 'Jonesboro', 'Jonesborough', 'Jonesburg', 'Jonestown', 'Jonesville', 'Joplin', 'Joppa', 'Joppatowne', 'Jordan', 'Jordan Road-Canyon Creek', 'Jordan Valley', 'Joseph', 'Josephine', 'Josephville', 'Joshua', 'Joshua Tree', 'Jourdanton', 'Joy', 'Juana Díaz', 'Jud', 'Judith Gap', 'Judson', 'Judsonia', 'Julesburg', 'Juliaetta', 'Julian', 'Jumpertown', 'Juncal', 'Juncos', 'Junction', 'Junction City', 'June Park', 'Juneau', 'Juneau city and', 'Juniata', 'Juniata Terrace', 'Junior', 'Juno Beach', 'Juno Ridge', 'Jupiter', 'Jupiter Inlet Colony', 'Jupiter Island', 'Justice', 'Justin', 'K-Bar Ranch', 'K. I. Sawyer AFB', 'Kaaawa', 'Kaanapali', 'Kachemak', 'Kachina Village', 'Kadoka', 'Kahaluu', 'Kahaluu-Keauhou', 'Kahlotus', 'Kahoka', 'Kahuku', 'Kahului', 'Kaibab', 'Kaibito', 'Kailua', 'Kake', 'Kaktovik', 'Kalaheo', 'Kalama', 'Kalamazoo', 'Kalaoa', 'Kaleva', 'Kalida', 'Kalifornsky', 'Kalihiwai', 'Kalispell', 'Kalkaska', 'Kalona', 'Kaltag', 'Kamas', 'Kamiah', 'Kampsville', 'Kamrar', 'Kanab', 'Kanarraville', 'Kanawha', 'Kandiyohi', 'Kane', 'Kaneohe', 'Kaneohe Station', 'Kangley', 'Kankakee', 'Kannapolis', 'Kanopolis', 'Kanorado', 'Kanosh', 'Kansas', 'Kansas City', 'Kapaa', 'Kapaau', 'Kapalua', 'Kaplan', 'Kappa', 'Karlsruhe', 'Karlstad', 'Karluk', 'Karnak', 'Karnes City', 'Karns City', 'Kasaan', 'Kaser', 'Kasigluk', 'Kasilof', 'Kaskaskia', 'Kasota', 'Kasson', 'Kathleen', 'Kathryn', 'Katy', 'Kaufman', 'Kaukauna', 'Kaumakani', 'Kaunakakai', 'Kaw City', 'Kawela Bay', 'Kaycee', 'Kayenta', 'Kaylor', 'Kaysville', 'Keaau', 'Keachi', 'Kealakekua', 'Keams Canyon', 'Keansburg', 'Kearney', 'Kearns', 'Kearny', 'Kechi', 'Keddie', 'Keedysville', 'Keego Harbor', 'Keeler', 'Keene', 'Keeneland', 'Keener', 'Keenes', 'Keenesburg', 'Keensburg', 'Keeseville', 'Keewatin', 'Keiser', 'Keithsburg', 'Keizer', 'Kekaha', 'Kekoskee', 'Kelford', 'Kell', 'Keller', 'Kellerton', 'Kelley', 'Kelleys Island', 'Kelliher', 'Kellnersville', 'Kellogg', 'Kelly', 'Kellyville', 'Kelseyville', 'Kelso', 'Kemah', 'Kemmerer', 'Kemp', 'Kemp Mill', 'Kempner', 'Kempton', 'Ken Caryl', 'Kenai', 'Kenansville', 'Kenbridge', 'Kendale Lakes', 'Kendall', 'Kendall Green', 'Kendall Park', 'Kendall West', 'Kendallville', 'Kendleton', 'Kendrick', 'Kenedy', 'Kenefic', 'Kenefick', 'Kenesaw', 'Kenhorst', 'Kenilworth', 'Kenly', 'Kenmare', 'Kenmore', 'Kennan', 'Kennard', 'Kennebec', 'Kennebunk', 'Kennebunkport', 'Kennedale', 'Kennedy', 'Kennedy Township', 'Kenner', 'Kennesaw', 'Kenneth', 'Kenneth City', 'Kennett', 'Kennett Square', 'Kennewick', 'Kenney', 'Kenny Lake', 'Kenosha', 'Kenova', 'Kensal', 'Kensett', 'Kensington', 'Kensington Park', 'Kent', 'Kent Acres', 'Kent City', 'Kent Narrows', 'Kentfield', 'Kentland', 'Kenton', 'Kenton Vale', 'Kentwood', 'Kenwood', 'Kenyon', 'Keo', 'Keokee', 'Keokuk', 'Keomah Village', 'Keosauqua', 'Keota', 'Kerens', 'Kerhonkson', 'Kerkhoven', 'Kerman', 'Kermit', 'Kernersville', 'Kernville', 'Kerr', 'Kerrick', 'Kerrville', 'Kersey', 'Kershaw', 'Keshena', 'Keswick', 'Ketchikan', 'Ketchum', 'Kettering', 'Kettle Falls', 'Kettle River', 'Kettleman City', 'Kettlersville', 'Kevil', 'Kevin', 'Kewanee', 'Kewanna', 'Kewaskum', 'Kewaunee', 'Key Biscayne', 'Key Colony Beach', 'Key Largo', 'Key West', 'Keyes', 'Keyesport', 'Keyport', 'Keys', 'Keyser', 'Keystone', 'Keystone Heights', 'Keysville', 'Keytesville', 'Kiana', 'Kiawah Island', 'Kibler', 'Kicking Horse', 'Kidder', 'Kief', 'Kiefer', 'Kiel', 'Kiester', 'Kihei', 'Kilauea', 'Kilbourne', 'Kildare', 'Kildeer', 'Kilgore', 'Kilkenny', 'Kill Devil Hills', 'Killbuck', 'Killdeer', 'Killeen', 'Killen', 'Killian', 'Killona', 'Kilmarnock', 'Kilmichael', 'Kiln', 'Kim', 'Kimball', 'Kimballton', 'Kimberling City', 'Kimberly', 'Kimbolton', 'Kimmswick', 'Kinbrae', 'Kincaid', 'Kinde', 'Kinder', 'Kinderhook', 'Kindred', 'King', 'King City', 'King Cove', 'King Salmon', 'King of Prussia', 'Kingdom City', 'Kingfisher', 'Kingman', 'Kings Bay Base', 'Kings Beach', 'Kings Grant', 'Kings Mountain', 'Kings Park', 'Kings Point', 'Kingsburg', 'Kingsbury', 'Kingsford', 'Kingsford Heights', 'Kingsgate', 'Kingsland', 'Kingsley', 'Kingsport', 'Kingston', 'Kingston Mines', 'Kingston Springs', 'Kingstown', 'Kingstree', 'Kingsville', 'Kingwood', 'Kinloch', 'Kinmundy', 'Kinnelon', 'Kinney', 'Kinross', 'Kinsey', 'Kinsley', 'Kinsman', 'Kinston', 'Kinta', 'Kiowa', 'Kipnuk', 'Kipton', 'Kirby', 'Kirbyville', 'Kirkersville', 'Kirkland', 'Kirklin', 'Kirkman', 'Kirkpatrick', 'Kirksville', 'Kirkville', 'Kirkwood', 'Kiron', 'Kirtland', 'Kirtland Hills', 'Kirvin', 'Kirwin', 'Kiryas Joel', 'Kismet', 'Kissimmee', 'Kistler', 'Kit Carson', 'Kite', 'Kittanning', 'Kittery', 'Kittery Point', 'Kittitas', 'Kittredge', 'Kittrell', 'Kitty Hawk', 'Kitzmiller', 'Kivalina', 'Klamath', 'Klamath Falls', 'Klawock', 'Klein', 'Klemme', 'Klickitat', 'Kline', 'Klingerstown', 'Klukwan', 'Knapp', 'Knierim', 'Knife River', 'Knightdale', 'Knightsen', 'Knightstown', 'Knightsville', 'Knik River', 'Knik-Fairview', 'Knippa', 'Knob Noster', 'Knobel', 'Knollwood', 'Knowles', 'Knox', 'Knox City', 'Knoxville', 'Kobuk', 'Kodiak', 'Kodiak Station', 'Kohler', 'Kokhanok', 'Kokomo', 'Koliganek', 'Koloa', 'Konawa', 'Kongiganak', 'Koontz Lake', 'Koosharem', 'Kooskia', 'Kootenai', 'Koppel', 'Kosciusko', 'Koshkonong', 'Kosse', 'Kossuth', 'Kotlik', 'Kotzebue', 'Kountze', 'Kouts', 'Koyuk', 'Koyukuk', 'Kramer', 'Kranzburg', 'Kratzerville', 'Kreamer', 'Krebs', 'Kremlin', 'Kremmling', 'Kress', 'Krotz Springs', 'Krugerville', 'Krum', 'Krupp', 'Kualapuu', 'Kukuihaele', 'Kulm', 'Kulpmont', 'Kulpsville', 'Kuna', 'Kupreanof', 'Kure Beach', 'Kurtistown', 'Kuttawa', 'Kutztown', 'Kwethluk', 'Kwigillingok', 'Kykotsmovi Village', 'Kyle', 'L\'Anse', 'La Alianza', 'La Barge', 'La Belle', 'La Blanca', 'La Bolt', 'La Canada Flintridge', 'La Casita-Garciasville', 'La Center', 'La Cienega', 'La Conner', 'La Crescent', 'La Crescenta-Montrose', 'La Croft', 'La Crosse', 'La Cygne', 'La Dolores', 'La Due', 'La Farge', 'La Fargeville', 'La Fayette', 'La Feria', 'La Feria North', 'La Fermina', 'La Follette', 'La Fontaine', 'La Grande', 'La Grange', 'La Grange Park', 'La Grulla', 'La Habra', 'La Habra Heights', 'La Harpe', 'La Homa', 'La Jara', 'La Joya', 'La Junta', 'La Luisa', 'La Luz', 'La Marque', 'La Mesa', 'La Mirada', 'La Moille', 'La Monte', 'La Motte', 'La Palma', 'La Paloma', 'La Paloma-Lost Creek', 'La Parguera', 'La Paz', 'La Pine', 'La Plant', 'La Plata', 'La Playa', 'La Plena', 'La Porte', 'La Porte City', 'La Prairie', 'La Presa', 'La Pryor', 'La Puebla', 'La Puente', 'La Puerta', 'La Quinta', 'La Riviera', 'La Rose', 'La Rosita', 'La Rue', 'La Russell', 'La Sal', 'La Salle', 'La Tour', 'La Vale', 'La Valle', 'La Vergne', 'La Verkin', 'La Verne', 'La Vernia', 'La Veta', 'La Victoria', 'La Villa', 'La Vista', 'La Ward', 'LaCoste', 'LaFayette', 'LaGrange', 'LaMoure', 'Labadieville', 'Labelle', 'Labette', 'Labish Village', 'Lac La Belle', 'Lac du Flambeau', 'Lacey', 'Laceyville', 'Lackawanna', 'Lackland AFB', 'Laclede', 'Lacombe', 'Lacon', 'Lacona', 'Laconia', 'Lacoochee', 'Lacy-Lakeview', 'Ladd', 'Laddonia', 'Ladera Heights', 'Ladoga', 'Ladonia', 'Ladora', 'Ladson', 'Ladue', 'Lady Lake', 'Ladysmith', 'Lafayette', 'Lafe', 'Lafitte', 'Laflin', 'Lago', 'Lago Vista', 'Lagrange', 'Lagro', 'Laguna', 'Laguna Beach', 'Laguna Heights', 'Laguna Hills', 'Laguna Niguel', 'Laguna Seca', 'Laguna Vista', 'Laguna West-Lakeside', 'Laguna Woods', 'Lagunitas-Forest Knolls', 'Lahaina', 'Lahoma', 'Laie', 'Laingsburg', 'Lajas', 'Lake', 'Lake Alfred', 'Lake Almanor Country Club', 'Lake Almanor Peninsula', 'Lake Almanor West', 'Lake Aluma', 'Lake Andes', 'Lake Angelus', 'Lake Ann', 'Lake Annette', 'Lake Arbor', 'Lake Arrowhead', 'Lake Arthur', 'Lake Barcroft', 'Lake Barrington', 'Lake Belvedere Estates', 'Lake Benton', 'Lake Bluff', 'Lake Bosworth', 'Lake Bridgeport', 'Lake Bronson', 'Lake Brownwood', 'Lake Buena Vista', 'Lake Butler', 'Lake Butter', 'Lake Carmel', 'Lake Catherine', 'Lake Cavanaugh', 'Lake Charles', 'Lake City', 'Lake Clarke Shores', 'Lake Crystal', 'Lake Dalecarlia', 'Lake Dallas', 'Lake Darby', 'Lake Davis', 'Lake Delton', 'Lake Elmo', 'Lake Elsinore', 'Lake Erie Beach', 'Lake Fenton', 'Lake Forest', 'Lake Forest Park', 'Lake Geneva', 'Lake George', 'Lake Goodwin', 'Lake Grove', 'Lake Hamilton', 'Lake Harbor', 'Lake Hart', 'Lake Havasu City', 'Lake Helen', 'Lake Henry', 'Lake Heritage', 'Lake Isabella', 'Lake Jackson', 'Lake Junaluska', 'Lake Kathryn', 'Lake Katrine', 'Lake Ketchum', 'Lake Kiowa', 'Lake Koshkonong', 'Lake Lac La Belle', 'Lake Lafayette', 'Lake Lillian', 'Lake Linden', 'Lake Lindsey', 'Lake Lorraine', 'Lake Los Angeles', 'Lake Lotawana', 'Lake Louise', 'Lake Lucerne', 'Lake Lure', 'Lake Luzerne-Hadley', 'Lake Mack-Forest Hills', 'Lake Magdalene', 'Lake Marcel-Stillwater', 'Lake Mary', 'Lake McMurray', 'Lake Meade', 'Lake Michigan Beach', 'Lake Mills', 'Lake Minchumina', 'Lake Mohawk', 'Lake Mohegan', 'Lake Montezuma', 'Lake Monticello', 'Lake Morton-Berrydale', 'Lake Murray of Richland', 'Lake Mykee Town', 'Lake Nacimiento', 'Lake Nebagamon', 'Lake Norden', 'Lake Norman of Catawba', 'Lake Odessa', 'Lake Orion', 'Lake Oswego', 'Lake Ozark', 'Lake Panasoffkee', 'Lake Park', 'Lake Placid', 'Lake Pocotopaug', 'Lake Preston', 'Lake Providence', 'Lake Purdy', 'Lake Quivira', 'Lake Ridge', 'Lake Ripley', 'Lake Roesiger', 'Lake Ronkonkoma', 'Lake San Marcos', 'Lake Santeetlah', 'Lake Sarasota', 'Lake Secession', 'Lake Shangrila', 'Lake Shore', 'Lake St. Croix Beach', 'Lake St. Louis', 'Lake Station', 'Lake Stevens', 'Lake Success', 'Lake Summerset', 'Lake Sumner', 'Lake Tanglewood', 'Lake Tansi', 'Lake Tapawingo', 'Lake Telemark', 'Lake View', 'Lake Villa', 'Lake Village', 'Lake Waccamaw', 'Lake Wales', 'Lake Waukomis', 'Lake Wazeecha', 'Lake Wildwood', 'Lake Wilson', 'Lake Winnebago', 'Lake Wisconsin', 'Lake Wissota', 'Lake Worth', 'Lake Worth Corridor', 'Lake Wylie', 'Lake Wynonah', 'Lake Zurich', 'Lake in the Hills', 'Lake of the Pines', 'Lake of the Woods', 'Lakefield', 'Lakehead-Lakeshore', 'Lakehills', 'Lakehurst', 'Lakeland', 'Lakeland Highlands', 'Lakeland North', 'Lakeland Shores', 'Lakeland South', 'Lakeland Village', 'Lakeline', 'Lakemoor', 'Lakemore', 'Lakeport', 'Lakes', 'Lakes by the Bay', 'Lakes of the Four Seasons', 'Lakeshire', 'Lakeshore Gardens-Hidden Acres', 'Lakeside', 'Lakeside City', 'Lakeside Green', 'Lakeside Park', 'Lakesite', 'Laketown', 'Lakeview', 'Lakeview Estates', 'Lakeview Heights', 'Lakeview North', 'Lakeville', 'Lakeway', 'Lakewood', 'Lakewood Club', 'Lakewood Park', 'Lakewood Shores', 'Lakewood Village', 'Lakin', 'Lakota', 'Lamar', 'Lamar Heights', 'Lambert', 'Lamberton', 'Lambertville', 'Lamboglia', 'Lambs Grove', 'Lame Deer', 'Lamesa', 'Lamoni', 'Lamont', 'Lampasas', 'Lamy', 'Lanagan', 'Lanai City', 'Lanare', 'Lanark', 'Lancaster', 'Lancaster Mill', 'Lance Creek', 'Land O\' Lakes', 'Landa', 'Landen', 'Lander', 'Landfall', 'Landingville', 'Landis', 'Landisburg', 'Landover Hills', 'Landrum', 'Lane', 'Lanesboro', 'Lanesville', 'Lanett', 'Langdon', 'Langdon Place', 'Langford', 'Langhorne', 'Langhorne Manor', 'Langley', 'Langley Park', 'Langston', 'Lanham-Seabrook', 'Lankin', 'Lannon', 'Lansdale', 'Lansdowne', 'Lansdowne-Baltimore Highlands', 'Lansford', 'Lansing', 'Lantana', 'Lapeer', 'Lapel', 'Laplace', 'Laporte', 'Lapwai', 'Laramie', 'Larchmont', 'Larchwood', 'Laredo', 'Laredo Ranchettes', 'Lares', 'Larga Vista', 'Largo', 'Larimore', 'Larkfield-Wikiup', 'Larkspur', 'Larksville', 'Larned', 'Larose', 'Larrabee', 'Larsen Bay', 'Larson', 'Larwill', 'Las Animas', 'Las Colonias', 'Las Cruces', 'Las Flores', 'Las Lomas', 'Las Lomitas', 'Las Marías', 'Las Ochenta', 'Las Ollas', 'Las Palmas-Juarez', 'Las Piedras', 'Las Quintas Fronterizas', 'Las Vegas', 'Lasana', 'Lasara', 'Lasker', 'Lastrup', 'Latah', 'Latexo', 'Latham', 'Lathrop', 'Lathrup Village', 'Latimer', 'Laton', 'Latonia Lakes', 'Latrobe', 'Latta', 'Lattimore', 'Lattingtown', 'Latty', 'Lauderdale', 'Lauderdale Lakes', 'Lauderdale-by-the-Sea', 'Lauderhill', 'Laughlin', 'Laughlin AFB', 'Laupahoehoe', 'Laura', 'Laurel', 'Laurel Bay', 'Laurel Hill', 'Laurel Hollow', 'Laurel Lake', 'Laurel Mountain', 'Laurel Park', 'Laurel Run', 'Laurel Springs', 'Laureldale', 'Laureles', 'Laurelville', 'Laurence Harbor', 'Laurens', 'Laurie', 'Laurinburg', 'Laurium', 'Lava Hot Springs', 'Lavaca', 'Lavallette', 'Lavelle-Locustdale', 'Laverne', 'Lavina', 'Lavon', 'Lavonia', 'Lawai', 'Lawler', 'Lawn', 'Lawndale', 'Lawnside', 'Lawnton', 'Lawrence', 'Lawrence Creek', 'Lawrence Park', 'Lawrenceburg', 'Lawrenceville', 'Lawson', 'Lawson Heights', 'Lawtey', 'Lawton', 'Laymantown', 'Layton', 'Laytonsville', 'Laytonville', 'Lazy Lake', 'Lazy Mountain', 'Le Center', 'Le Claire', 'Le Flore', 'Le Grand', 'Le Mars', 'Le Raysville', 'Le Roy', 'Le Sueur', 'Lea Hill', 'Leach', 'Leachville', 'Leacock-Leola-Bareville', 'Lead', 'Lead Hill', 'Leadington', 'Leadore', 'Leadville', 'Leadville North', 'Leadwood', 'Leaf River', 'League City', 'Leakesville', 'Leakey', 'Leal', 'Leamington', 'Leander', 'Leando', 'Learned', 'Leary', 'Leasburg', 'Leavenworth', 'Leavittsburg', 'Leawood', 'Lebam', 'Lebanon', 'Lebanon Junction', 'Lebanon South', 'Lebec', 'Lebo', 'Lecanto', 'Lechee', 'Lecompte', 'Lecompton', 'Ledbetter', 'Ledyard', 'Lee', 'Lee\'s Summit', 'Leechburg', 'Leedey', 'Leeds', 'Leesburg', 'Leesport', 'Leesville', 'Leeton', 'Leetonia', 'Leetsdale', 'Lefors', 'Legend Lake', 'Leggett', 'Lehi', 'Lehigh', 'Lehigh Acres', 'Lehighton', 'Lehr', 'Leicester', 'Leigh', 'Leighton', 'Leilani Estates', 'Leipsic', 'Leisure City', 'Leisure Knoll', 'Leisure Village', 'Leisure Village East', 'Leisure Village West-Pine Lake Park', 'Leisuretowne', 'Leisureville', 'Leitchfield', 'Leitersburg', 'Leith', 'Leith-Hatfield', 'Leland', 'Leland Grove', 'Lely', 'Lely Resort', 'Lemay', 'Lemmon', 'Lemmon Valley-Golden Valley', 'Lemon Cove', 'Lemon Grove', 'Lemont', 'Lemoore', 'Lemoore Station', 'Lemoyne', 'Lena', 'Lenapah', 'Lenape Heights', 'Lenexa', 'Lengby', 'Lenhartsville', 'Lennon', 'Lennox', 'Lenoir', 'Lenoir City', 'Lenora', 'Lenox', 'Lenwood', 'Lenzburg', 'Leo-Cedarville', 'Leola', 'Leominster', 'Leon', 'Leon Valley', 'Leona', 'Leonard', 'Leonardo', 'Leonardtown', 'Leonardville', 'Leonia', 'Leonidas', 'Leonore', 'Leonville', 'Leota', 'Leoti', 'Lepanto', 'Lerna', 'Leroy', 'Leshara', 'Leslie', 'Lesslie', 'Lester', 'Lester Prairie', 'Lesterville', 'Letcher', 'Letona', 'Letts', 'Leupp', 'Levan', 'Levasy', 'Level Park-Oak Park', 'Level Plains', 'Levelland', 'Levelock', 'Levittown', 'Lewellen', 'Lewes', 'Lewis', 'Lewis Run', 'Lewis and Clark Village', 'Lewisberry', 'Lewisburg', 'Lewisport', 'Lewiston', 'Lewiston Woodville', 'Lewistown', 'Lewistown Heights', 'Lewisville', 'Lexa', 'Lexington', 'Lexington Hills', 'Lexington Park', 'Libby', 'Liberal', 'Liberty', 'Liberty Center', 'Liberty City', 'Liberty Hill', 'Liberty Lake', 'Libertyville', 'Liborio Negrón Torres', 'Licking', 'Lidderdale', 'Lidgerwood', 'Lido Beach', 'Liebenthal', 'Light Oak', 'Lighthouse Point', 'Lightstreet', 'Lignite', 'Ligonier', 'Lihue', 'Lilbourn', 'Lilburn', 'Lilesville', 'Lillie', 'Lillington', 'Lilly', 'Lily', 'Lily Lake', 'Lilydale', 'Lima', 'Limaville', 'Lime Lake-Machias', 'Lime Ridge', 'Lime Springs', 'Lime Village', 'Limestone', 'Limestone Creek', 'Limon', 'Lincoln', 'Lincoln Beach', 'Lincoln Center', 'Lincoln City', 'Lincoln Heights', 'Lincoln Park', 'Lincoln Village', 'Lincolndale', 'Lincolnia', 'Lincolnshire', 'Lincolnton', 'Lincolnville', 'Lincolnwood', 'Lincroft', 'Lind', 'Linda', 'Lindale', 'Linden', 'Lindenhurst', 'Lindenwold', 'Lindon', 'Lindsay', 'Lindsborg', 'Lindsey', 'Lindstrom', 'Linesville', 'Lineville', 'Linganore-Bartonsville', 'Lingle', 'Linglestown', 'Linn', 'Linn Creek', 'Linn Grove', 'Linn Valley', 'Linndale', 'Linneus', 'Linntown', 'Lino Lakes', 'Linthicum', 'Linton', 'Linton Hall', 'Linwood', 'Lionville-Marchwood', 'Lipan', 'Lipscomb', 'Lisbon', 'Lisbon Falls', 'Liscomb', 'Lisle', 'Lisman', 'Lismore', 'Litchfield', 'Litchfield Park', 'Litchville', 'Lithia Springs', 'Lithium', 'Lithonia', 'Lithopolis', 'Lititz', 'Little America', 'Little Canada', 'Little Chute', 'Little Cottonwood Creek Valley', 'Little Creek', 'Little Eagle', 'Little Elm', 'Little Falls', 'Little Falls-South Windham', 'Little Ferry', 'Little Flock', 'Little Grass Valley', 'Little Meadows', 'Little Mountain', 'Little River', 'Little River-Academy', 'Little Rock', 'Little Round Lake', 'Little Silver', 'Little Sioux', 'Little Valley', 'Little York', 'Littlefield', 'Littlefork', 'Littleport', 'Littlerock', 'Littlestown', 'Littleton', 'Littleton Common', 'Littletown', 'Littleville', 'Live Oak', 'Livengood', 'Livermore', 'Livermore Falls', 'Liverpool', 'Livingston', 'Livingston Manor', 'Livonia', 'Lizton', 'Llano', 'Llano Grande', 'Lloyd Harbor', 'Lluveras', 'Loa', 'Loachapoka', 'Loami', 'Lobelville', 'Loch Arbour', 'Loch Lomond', 'Loch Lynn Heights', 'Lochbuie', 'Lochearn', 'Lochmoor Waterway Estates', 'Lochsloy', 'Lock Haven', 'Lock Springs', 'Lockbourne', 'Lockeford', 'Lockesburg', 'Lockhart', 'Lockington', 'Lockland', 'Lockney', 'Lockport', 'Lockridge', 'Lockwood', 'Loco', 'Locust', 'Locust Fork', 'Locust Grove', 'Locust Valley', 'Locustdale', 'Loda', 'Lodge', 'Lodge Grass', 'Lodge Pole', 'Lodgepole', 'Lodi', 'Log Cabin', 'Log Lane Village', 'Logan', 'Logan Elm Village', 'Logansport', 'Loganton', 'Loganville', 'Loghill Village', 'Lohman', 'Lohrville', 'Lolita', 'Lolo', 'Loma', 'Loma Linda', 'Loma Linda East', 'Loma Rica', 'Lomas', 'Lomax', 'Lombard', 'Lometa', 'Lomira', 'Lomita', 'Lompoc', 'Lonaconing', 'London', 'London Mills', 'Londonderry', 'Londontowne', 'Lone Elm', 'Lone Grove', 'Lone Jack', 'Lone Oak', 'Lone Pine', 'Lone Rock', 'Lone Star', 'Lone Tree', 'Lone Wolf', 'Lonepine', 'Lonerock', 'Lonetree', 'Long', 'Long Beach', 'Long Branch', 'Long Creek', 'Long Grove', 'Long Hill', 'Long Island', 'Long Lake', 'Long Neck', 'Long Pine', 'Long Point', 'Long Prairie', 'Long Valley', 'Long View', 'Longboat Key', 'Longdale', 'Longford', 'Longmeadow', 'Longmont', 'Longport', 'Longstreet', 'Longton', 'Longtown', 'Longview', 'Longview Heights', 'Longville', 'Longwood', 'Lonoke', 'Lonsdale', 'Loogootee', 'Lookeba', 'Lookout Mountain', 'Loomis', 'Lopeno', 'Lopezville', 'Lorain', 'Loraine', 'Lorane', 'Lordsburg', 'Lordstown', 'Lore City', 'Loreauville', 'Lorena', 'Lorenz Park', 'Lorenzo', 'Loretto', 'Lorimor', 'Loring AFB', 'Loris', 'Lorraine', 'Lorton', 'Los Alamitos', 'Los Alamos', 'Los Altos', 'Los Altos Hills', 'Los Alvarez', 'Los Angeles', 'Los Angeles Subdivision', 'Los Banos', 'Los Cerrillos', 'Los Chaves', 'Los Ebanos', 'Los Fresnos', 'Los Gatos', 'Los Indios', 'Los Llanos', 'Los Lunas', 'Los Molinos', 'Los Ranchos de Albuquerque', 'Los Trujillos-Gabaldon', 'Los Villareales', 'Los Ybanez', 'Losantville', 'Lost City', 'Lost Creek', 'Lost Hills', 'Lost Lake Woods', 'Lost Nation', 'Lost River', 'Lost Springs', 'Lostant', 'Lostine', 'Lotsee', 'Lott', 'Louann', 'Loudon', 'Loudonville', 'Loughman', 'Louin', 'Louisa', 'Louisburg', 'Louise', 'Louisiana', 'Louisville', 'Loup City', 'Louviers', 'Love Valley', 'Lovejoy', 'Lovelady', 'Loveland', 'Loveland Park', 'Lovell', 'Lovelock', 'Loves Park', 'Lovettsville', 'Lovilia', 'Loving', 'Lovington', 'Low Moor', 'Lowden', 'Lowell', 'Lowell Point', 'Lowellville', 'Lower Allen', 'Lower Brule', 'Lower Burrell', 'Lower Grand Lagoon', 'Lower Kalskag', 'Lower Lake', 'Lower Salem', 'Lowesville', 'Lowndesboro', 'Lowndesville', 'Lowry', 'Lowry City', 'Lowry Crossing', 'Lowrys', 'Lowville', 'Loxley', 'Loyal', 'Loyall', 'Loyalton', 'Loyola', 'Lozano', 'Loíza', 'Lu Verne', 'Luana', 'Lubbock', 'Lubeck', 'Lublin', 'Lucama', 'Lucan', 'Lucas', 'Lucas Valley-Marinwood', 'Lucasville', 'Lucedale', 'Lucerne', 'Lucerne Mines', 'Luck', 'Luckey', 'Lucky', 'Ludden', 'Ludington', 'Ludlow', 'Ludlow Falls', 'Ludowici', 'Lueders', 'Lufkin', 'Lugoff', 'Luis Lloréns Torres', 'Luis M. Cintrón', 'Lukachukai', 'Luke', 'Lula', 'Luling', 'Lumber Bridge', 'Lumber City', 'Lumberport', 'Lumberton', 'Lumpkin', 'Luna Pier', 'Lunenburg', 'Lupus', 'Luquillo', 'Luray', 'Lusby', 'Lushton', 'Lusk', 'Lutak', 'Lutcher', 'Luther', 'Luthersville', 'Lutherville-Timonium', 'Luttrell', 'Lutz', 'Luverne', 'Luxemburg', 'Luxora', 'Luyando', 'Luzerne', 'Lydia', 'Lyerly', 'Lyford', 'Lyford South', 'Lykens', 'Lyle', 'Lyman', 'Lynbrook', 'Lynch', 'Lynchburg', 'Lyncourt', 'Lynd', 'Lynden', 'Lyndhurst', 'Lyndon', 'Lyndon Station', 'Lyndonville', 'Lynn', 'Lynn Haven', 'Lynndyl', 'Lynnfield', 'Lynnview', 'Lynnville', 'Lynnwood', 'Lynnwood-Pricedale', 'Lynwood', 'Lynxville', 'Lyon', 'Lyon Mountain', 'Lyons', 'Lyons Falls', 'Lyons Switch', 'Lytle', 'Lytton', 'Maalaea', 'Mabank', 'Mabel', 'Maben', 'Mableton', 'Mabscott', 'Mabton', 'MacArthur', 'Macclenny', 'Macclesfield', 'Macdoel', 'Macedon', 'Macedonia', 'Machesney Park', 'Machias', 'Mack North', 'Mack South', 'Mackay', 'Mackenzie', 'Mackey', 'Mackinac Island', 'Mackinaw', 'Mackinaw City', 'Macks Creek', 'Macksburg', 'Macksville', 'Mackville', 'Macomb', 'Macon', 'Macungie', 'Macy', 'Madawaska', 'Maddock', 'Madeira', 'Madeira Beach', 'Madelia', 'Madera', 'Madera Acres', 'Madill', 'Madison', 'Madison Center', 'Madison Heights', 'Madison Lake', 'Madison Park', 'Madisonburg', 'Madisonville', 'Madras', 'Madrid', 'Maeser', 'Maeystown', 'Magalia', 'Magas Arriba', 'Magazine', 'Magdalena', 'Magee', 'Maggie Valley', 'Magna', 'Magness', 'Magnet', 'Magnetic Springs', 'Magnolia', 'Mahaffey', 'Mahanoy City', 'Mahaska', 'Mahnomen', 'Mahomet', 'Mahopac', 'Mahtomedi', 'Maiden', 'Maiden Rock', 'Maili', 'Maineville', 'Mainville', 'Maitland', 'Maize', 'Makaha', 'Makaha Valley', 'Makakilo City', 'Makanda', 'Makawao', 'Makoti', 'Malabar', 'Malad City', 'Malakoff', 'Malcolm', 'Malcom', 'Malden', 'Malibu', 'Malin', 'Malinta', 'Mallard', 'Mallory', 'Malmo', 'Malmstrom AFB', 'Malone', 'Malone-Porter', 'Maloy', 'Malta', 'Malta Bend', 'Maltby', 'Malvern', 'Malverne', 'Malverne Park Oaks', 'Mamaroneck', 'Mammoth', 'Mammoth Lakes', 'Mammoth Spring', 'Mamou', 'Man', 'Manahawkin', 'Manalapan', 'Manasota Key', 'Manasquan', 'Manassa', 'Manassas', 'Manassas Park', 'Manattee Road', 'Manatí', 'Manawa', 'Mancelona', 'Manchester', 'Manchester Center', 'Mancos', 'Mandan', 'Mandaree', 'Manderson', 'Manderson-White Horse Creek', 'Mandeville', 'Mangham', 'Mango', 'Mangonia Park', 'Mangum', 'Manhasset', 'Manhasset Hills', 'Manhattan', 'Manhattan Beach', 'Manheim', 'Manila', 'Manilla', 'Manistee', 'Manistique', 'Manito', 'Manitou', 'Manitou Beach-Devils Lake', 'Manitou Springs', 'Manitowoc', 'Mankato', 'Manley', 'Manley Hot Springs', 'Manlius', 'Manly', 'Mannford', 'Manning', 'Mannington', 'Manns Choice', 'Mannsville', 'Manokotak', 'Manor', 'Manor Creek', 'Manorhaven', 'Manorville', 'Mansfield', 'Mansfield Center', 'Manson', 'Mansura', 'Mantachie', 'Mantador', 'Manteca', 'Mantee', 'Manteno', 'Manteo', 'Manter', 'Manti', 'Mantoloking', 'Manton', 'Mantorville', 'Mantua', 'Manvel', 'Manville', 'Many', 'Many Farms', 'Manzanita', 'Manzano', 'Manzanola', 'Maple Bluff', 'Maple Falls', 'Maple Glen', 'Maple Grove', 'Maple Heights', 'Maple Heights-Lake Desire', 'Maple Hill', 'Maple Lake', 'Maple Park', 'Maple Plain', 'Maple Rapids', 'Maple Ridge', 'Maple Valley', 'Maplesville', 'Mapleton', 'Mapleview', 'Maplewood', 'Maplewood Park', 'Maquoketa', 'Maquon', 'Mar-Mac', 'Maramec', 'Marana', 'Marathon', 'Marathon City', 'Marble', 'Marble City', 'Marble City Community', 'Marble Cliff', 'Marble Falls', 'Marble Hill', 'Marble Rock', 'Marblehead', 'Marblemount', 'Marbleton', 'Marceline', 'Marcellus', 'March AFB', 'Marco Island', 'Marcus', 'Marcus Hook', 'Mardela Springs', 'Marengo', 'Marfa', 'Margaret', 'Margaretville', 'Margate', 'Margate City', 'Marianna', 'Mariano Colón', 'Mariaville Lake', 'Maribel', 'Maricao', 'Maricopa', 'Marie', 'Mariemont', 'Marietta', 'Marietta-Alderwood', 'Marina', 'Marina del Rey', 'Marine', 'Marine City', 'Marine on St. Croix', 'Marineland', 'Marinette', 'Maringouin', 'Marion', 'Marion Center', 'Marion Heights', 'Marionville', 'Mariposa', 'Marissa', 'Mark', 'Marked Tree', 'Markesan', 'Markham', 'Markle', 'Markleeville', 'Marklesburg', 'Markleville', 'Markleysburg', 'Marks', 'Marksville', 'Marland', 'Marlboro', 'Marlborough', 'Marlette', 'Marlin', 'Marlinton', 'Marlow', 'Marlow Heights', 'Marlton', 'Marmaduke', 'Marmarth', 'Marmet', 'Marne', 'Maroa', 'Marquand', 'Marquette', 'Marquette Heights', 'Marquez', 'Marrero', 'Marriott-Slaterville', 'Marrowstone', 'Mars', 'Mars Hill', 'Mars Hill-Blaine', 'Marseilles', 'Marshall', 'Marshall Creek', 'Marshallton', 'Marshalltown', 'Marshallville', 'Marshfield', 'Marshfield Hills', 'Marshville', 'Marsing', 'Marston', 'Mart', 'Martelle', 'Martensdale', 'Martha', 'Martha Lake', 'Marthasville', 'Martin', 'Martin City', 'Martin\'s Additions', 'Martindale', 'Martinez', 'Martins Ferry', 'Martinsburg', 'Martinsville', 'Martinton', 'Martorell', 'Marty', 'Marueño', 'Marvell', 'Marvin', 'Mary Esther', 'Marydel', 'Maryetta', 'Maryhill', 'Maryhill Estates', 'Maryland City', 'Maryland Heights', 'Marysvale', 'Marysville', 'Maryville', 'María Antonia', 'Masaryktown', 'Mascot', 'Mascotte', 'Mascoutah', 'Mashpee Neck', 'Maskell', 'Mason', 'Mason City', 'Masonboro', 'Masontown', 'Masonville', 'Massac', 'Massanutten', 'Massapequa', 'Massapequa Park', 'Massena', 'Massillon', 'Mastic', 'Mastic Beach', 'Masury', 'Matador', 'Matamoras', 'Matawan', 'Matewan', 'Matfield Green', 'Matherville', 'Mathews', 'Mathis', 'Mathiston', 'Matinecock', 'Matlacha', 'Matlacha Isles-Matlacha Shores', 'Matlock', 'Matoaca', 'Matoaka', 'Mattapoisett Center', 'Mattawa', 'Mattawan', 'Matteson', 'Matthews', 'Mattituck', 'Mattoon', 'Mattydale', 'Mauckport', 'Maud', 'Maugansville', 'Mauldin', 'Maumee', 'Maumelle', 'Maunabo', 'Maunaloa', 'Maunawili', 'Maunie', 'Maupin', 'Maurice', 'Mauriceville', 'Maury City', 'Mauston', 'Max', 'Max Meadows', 'Maxbass', 'Maxeys', 'Maxton', 'Maxwell', 'May', 'May Creek', 'Mayagüez', 'Maybee', 'Maybrook', 'Mayer', 'Mayersville', 'Mayesville', 'Mayetta', 'Mayfield', 'Mayfield Heights', 'Mayflower', 'Mayflower Village', 'Maynard', 'Maynardville', 'Mayo', 'Mayodan', 'Maypearl', 'Mays Chapel', 'Mays Landing', 'Maysville', 'Maytown', 'Mayview', 'Mayville', 'Maywood', 'Maywood Park', 'Maza', 'Mazeppa', 'Mazie', 'Mazomanie', 'Mazon', 'Mc Nutt', 'McAdenville', 'McAdoo', 'McAlester', 'McAlisterville', 'McAllen', 'McAlmont', 'McArthur', 'McBain', 'McBaine', 'McBee', 'McBride', 'McCall', 'McCallsburg', 'McCamey', 'McCammon', 'McCandless Township', 'McCarthy', 'McCaskill', 'McCausland', 'McCaysville', 'McChesneytown-Loyalhanna', 'McChord AFB', 'McCleary', 'McClelland', 'McClellanville', 'McCloud', 'McClure', 'McClusky', 'McColl', 'McComb', 'McConnells', 'McConnellsburg', 'McConnelsville', 'McCook', 'McCool', 'McCool Junction', 'McCord', 'McCord Bend', 'McCordsville', 'McCormick', 'McCracken', 'McCrory', 'McCullom Lake', 'McCune', 'McCurtain', 'McDermitt', 'McDonald', 'McDonald Chapel', 'McDonough', 'McDougal', 'McEwen', 'McEwensville', 'McFall', 'McFarlan', 'McFarland', 'McGehee', 'McGill', 'McGovern', 'McGrath', 'McGraw', 'McGregor', 'McGrew', 'McGuffey', 'McGuire AFB', 'McHenry', 'McIntire', 'McIntosh', 'McIntyre', 'McKean', 'McKeansburg', 'McKee', 'McKees Rocks', 'McKeesport', 'McKenney', 'McKenzie', 'McKey', 'McKinley', 'McKinley Park', 'McKinleyville', 'McKinney', 'McKinnon', 'McKittrick', 'McLain', 'McLaughlin', 'McLean', 'McLeansboro', 'McLeansville', 'McLemoresville', 'McLendon-Chisholm', 'McLoud', 'McLouth', 'McMechen', 'McMinnville', 'McMullen', 'McMurray', 'McNab', 'McNabb', 'McNary', 'McNeil', 'McPherson', 'McQueeney', 'McRae', 'McRoberts', 'McSherrystown', 'McVeytown', 'McVille', 'Mead', 'Meade', 'Meadow', 'Meadow Acres', 'Meadow Bridge', 'Meadow Glade', 'Meadow Grove', 'Meadow Lake', 'Meadow Lakes', 'Meadow Lark Lake', 'Meadow Vale', 'Meadow Valley', 'Meadow Vista', 'Meadow Woods', 'Meadowbrook', 'Meadowbrook Farm', 'Meadowlakes', 'Meadowlands', 'Meadowood', 'Meadows Place', 'Meadowview Estates', 'Meadville', 'Meansville', 'Mebane', 'Mecca', 'Mechanic Falls', 'Mechanicsburg', 'Mechanicstown', 'Mechanicsville', 'Mechanicville', 'Mecosta', 'Medaryville', 'Medfield', 'Medford', 'Medford Lakes', 'Media', 'Mediapolis', 'Medical Lake', 'Medicine Bow', 'Medicine Lake', 'Medicine Lodge', 'Medicine Park', 'Medina', 'Medley', 'Medon', 'Medora', 'Medulla', 'Medusa', 'Meeker', 'Meeteetse', 'Megargel', 'Meggett', 'Mehama', 'Mehlville', 'Meigs', 'Meiners Oaks', 'Meire Grove', 'Mekoryuk', 'Melba', 'Melbeta', 'Melbourne', 'Melbourne Beach', 'Melbourne Village', 'Melcher-Dallas', 'Melfa', 'Melissa', 'Mellen', 'Mellette', 'Mellott', 'Melody Hill', 'Melrose', 'Melrose Park', 'Melstone', 'Melvern', 'Melville', 'Melvin', 'Melvina', 'Melvindale', 'Memphis', 'Mena', 'Menahga', 'Menan', 'Menands', 'Menard', 'Menasha', 'Mendeltna', 'Mendenhall', 'Mendham', 'Mendocino', 'Mendon', 'Mendota', 'Mendota Heights', 'Menifee', 'Menlo', 'Menlo Park', 'Menno', 'Meno', 'Menominee', 'Menomonee Falls', 'Menomonie', 'Mentasta Lake', 'Mentone', 'Mentor', 'Mentor-on-the-Lake', 'Mequon', 'Mer Rouge', 'Meraux', 'Merced', 'Mercedes', 'Mercer', 'Mercer Island', 'Mercersburg', 'Mercerville-Hamilton Square', 'Merchantville', 'Meredith', 'Meredosia', 'Meriden', 'Meridian', 'Meridian Hills', 'Meridian Station', 'Meridianville', 'Merigold', 'Merino', 'Merkel', 'Mermentau', 'Merna', 'Merom', 'Merriam', 'Merriam Woods', 'Merrick', 'Merrifield', 'Merrill', 'Merrillan', 'Merrillville', 'Merrimac', 'Merriman', 'Merrionette Park', 'Merritt Island', 'Merrydale', 'Merryville', 'Mertens', 'Merton', 'Mertzon', 'Merwin', 'Mesa', 'Mesa Vista', 'Mescalero', 'Meservey', 'Meshoppen', 'Mesic', 'Mesick', 'Mesilla', 'Mesita', 'Mesquite', 'Mesquite Creek', 'Meta', 'Metairie', 'Metaline', 'Metaline Falls', 'Metamora', 'Metcalf', 'Metcalfe', 'Methuen', 'Metlakatla', 'Metolius', 'Metropolis', 'Mettawa', 'Metter', 'Mettler', 'Metuchen', 'Metz', 'Metzger', 'Mexia', 'Mexican Hat', 'Mexico', 'Mexico Beach', 'Meyers Chuck', 'Meyers Lake', 'Meyersdale', 'Mi-Wuk Village', 'Miami', 'Miami Beach', 'Miami Gardens', 'Miami Lakes', 'Miami Shores', 'Miami Springs', 'Miamisburg', 'Micanopy', 'Micco', 'Michiana', 'Michiana Shores', 'Michie', 'Michigamme', 'Michigan Center', 'Michigan City', 'Michigantown', 'Micro', 'Middle Island', 'Middle Point', 'Middle River', 'Middle Valley', 'Middle Village', 'Middleborough Center', 'Middlebourne', 'Middleburg', 'Middleburg Heights', 'Middleburgh', 'Middlebury', 'Middlefield', 'Middleport', 'Middlesborough', 'Middlesex', 'Middleton', 'Middletown', 'Middleville', 'Midfield', 'Midland', 'Midland City', 'Midland Park', 'Midlothian', 'Midtown', 'Midvale', 'Midville', 'Midway', 'Midway North', 'Midway South', 'Midway-Hardwick', 'Midwest', 'Midwest City', 'Miesville', 'Mifflin', 'Mifflinburg', 'Mifflintown', 'Mifflinville', 'Mignon', 'Mila Doce', 'Milaca', 'Milam', 'Milan', 'Milano', 'Milbank', 'Milburn', 'Mildred', 'Miles', 'Miles City', 'Milesburg', 'Milford', 'Milford Center', 'Milford Mill', 'Mililani Town', 'Mill City', 'Mill Creek', 'Mill Hall', 'Mill Neck', 'Mill Plain', 'Mill Shoals', 'Mill Spring', 'Mill Valley', 'Mill Village', 'Milladore', 'Millard', 'Millbourne', 'Millbrae', 'Millbrook', 'Millburn', 'Millbury', 'Millcreek', 'Milledgeville', 'Millen', 'Miller', 'Miller City', 'Miller Landing', 'Miller Place', 'Miller\'s Cove', 'Millers Creek', 'Millers Falls', 'Millersburg', 'Millersport', 'Millerstown', 'Millersville', 'Millerton', 'Millerville', 'Millheim', 'Millhousen', 'Millican', 'Milligan', 'Milliken', 'Millington', 'Millinocket', 'Millis-Clicquot', 'Millport', 'Millry', 'Mills', 'Millsap', 'Millsboro', 'Millstadt', 'Millstone', 'Milltown', 'Millvale', 'Millville', 'Millwood', 'Milner', 'Milnor', 'Milo', 'Milpitas', 'Milroy', 'Milton', 'Milton Center', 'Milton-Freewater', 'Miltona', 'Miltonsburg', 'Miltonvale', 'Milwaukee', 'Milwaukie', 'Mims', 'Minatare', 'Minburn', 'Minco', 'Minden', 'Minden City', 'Mindenmines', 'Mineola', 'Miner', 'Mineral', 'Mineral City', 'Mineral Hills', 'Mineral Point', 'Mineral Ridge', 'Mineral Springs', 'Mineral Wells', 'Mineralwells', 'Minersville', 'Minerva', 'Minerva Park', 'Minetto', 'Mineville-Witherbee', 'Mingo', 'Mingo Junction', 'Mingus', 'Minidoka', 'Minier', 'Minneapolis', 'Minnehaha', 'Minneiska', 'Minneola', 'Minneota', 'Minnesota City', 'Minnesota Lake', 'Minnesott Beach', 'Minnetonka', 'Minnetonka Beach', 'Minnetrista', 'Minnewaukan', 'Minoa', 'Minong', 'Minonk', 'Minooka', 'Minor', 'Minor Hill', 'Minor Lane Heights', 'Minot', 'Minot AFB', 'Minster', 'Mint Hill', 'Minto', 'Minturn', 'Mio', 'Mira Loma', 'Mira Monte', 'Miramar', 'Miramar Beach', 'Miramiguoa Park', 'Miranda', 'Mirando City', 'Mirrormont', 'Mishawaka', 'Mishicot', 'Mission', 'Mission Bay', 'Mission Bend', 'Mission Canyon', 'Mission Hill', 'Mission Hills', 'Mission Viejo', 'Mission Woods', 'Missoula', 'Missouri City', 'Missouri Valley', 'Mitchell', 'Mitchell Heights', 'Mitchellville', 'Mize', 'Mizpah', 'Moab', 'Moapa Town', 'Moapa Valley', 'Mobeetie', 'Moberly', 'Mobile', 'Mobile City', 'Mobridge', 'Moca', 'Mockingbird Valley', 'Mocksville', 'Moclips', 'Modale', 'Modena', 'Modesto', 'Modoc', 'Moenkopi', 'Moffat', 'Moffett', 'Mogadore', 'Mohall', 'Mohave Valley', 'Mohawk', 'Mohawk Vista', 'Mohnton', 'Mojave', 'Mojave Ranch Estates', 'Mokane', 'Mokelumne Hill', 'Mokena', 'Mokuleia', 'Molalla', 'Molena', 'Moline', 'Moline Acres', 'Molino', 'Momence', 'Momeyer', 'Mona', 'Monaca', 'Monahans', 'Monango', 'Monarch Mill', 'Moncks Corner', 'Mondamin', 'Mondovi', 'Monee', 'Monessen', 'Monett', 'Monetta', 'Monette', 'Monfort Heights East', 'Monfort Heights South', 'Monmouth', 'Monmouth Beach', 'Monmouth Junction', 'Mono Vista', 'Monomoscoy Island', 'Monon', 'Monona', 'Monongah', 'Monongahela', 'Monowi', 'Monroe', 'Monroe City', 'Monroeville', 'Monrovia', 'Monserrate', 'Monsey', 'Monson Center', 'Mont Alto', 'Mont Belvieu', 'Montague', 'Montana City', 'Montara', 'Montauk', 'Montcalm', 'Montclair', 'Monte Alto', 'Monte Grande', 'Monte Rio', 'Monte Sereno', 'Monte Vista', 'Monteagle', 'Montebello', 'Montecito', 'Montegut', 'Montello', 'Monterey', 'Monterey Park', 'Montesano', 'Montevallo', 'Montevideo', 'Montezuma', 'Montezuma Creek', 'Montfort', 'Montgomery', 'Montgomery City', 'Montgomery Creek', 'Montgomery Village', 'Montgomeryville', 'Monticello', 'Montour', 'Montour Falls', 'Montoursville', 'Montpelier', 'Montreal', 'Montreat', 'Montrose', 'Montrose-Ghent', 'Montross', 'Montvale', 'Montverde', 'Montz', 'Monument', 'Monument Beach', 'Moodus', 'Moody', 'Moody AFB', 'Mooers', 'Moonachie', 'Moorcroft', 'Moore', 'Moore Haven', 'Moore Station', 'Moorefield', 'Mooreland', 'Moores Hill', 'Moores Mill', 'Mooresboro', 'Moorestown-Lenola', 'Mooresville', 'Mooreton', 'Moorhead', 'Mooringsport', 'Moorland', 'Moorpark', 'Moose Creek', 'Moose Lake', 'Moose Pass', 'Moose Wilson Road', 'Moosic', 'Moosup', 'Mora', 'Morada', 'Moraga', 'Moraine', 'Morales-Sanchez', 'Moran', 'Moravia', 'Moravian Falls', 'Moreauville', 'Morehead', 'Morehead City', 'Morehouse', 'Moreland', 'Moreland Hills', 'Morenci', 'Moreno Valley', 'Morgan', 'Morgan City', 'Morgan Farm Area', 'Morgan Hill', 'Morgan\'s Point', 'Morgan\'s Point Resort', 'Morganfield', 'Morganton', 'Morgantown', 'Morganville', 'Morganza', 'Moriarty', 'Moriches', 'Morland', 'Morley', 'Morning Glory', 'Morning Sun', 'Morningside', 'Moro', 'Morocco', 'Morongo Valley', 'Moroni', 'Morovis', 'Morral', 'Morrice', 'Morrill', 'Morrilton', 'Morris', 'Morris Plains', 'Morrison', 'Morrison Bluff', 'Morrisonville', 'Morristown', 'Morrisville', 'Morro Bay', 'Morrow', 'Morrowville', 'Morse', 'Morse Bluff', 'Morton', 'Morton Grove', 'Mortons Gap', 'Morven', 'Mosby', 'Moscow', 'Moscow Mills', 'Moses Lake', 'Moses Lake North', 'Mosheim', 'Mosier', 'Mosinee', 'Mosquero', 'Mosquito Lake', 'Moss Beach', 'Moss Bluff', 'Moss Landing', 'Moss Point', 'Mosses', 'Mossyrock', 'Motley', 'Mott', 'Moulton', 'Moultrie', 'Mound', 'Mound Bayou', 'Mound City', 'Mound Station', 'Mound Valley', 'Moundridge', 'Mounds', 'Mounds View', 'Moundsville', 'Moundville', 'Mount Aetna', 'Mount Airy', 'Mount Angel', 'Mount Arlington', 'Mount Auburn', 'Mount Ayr', 'Mount Blanchard', 'Mount Calm', 'Mount Calvary', 'Mount Carbon', 'Mount Carmel', 'Mount Carroll', 'Mount Charleston', 'Mount Clare', 'Mount Clemens', 'Mount Cobb', 'Mount Cory', 'Mount Crawford', 'Mount Crested Butte', 'Mount Croghan', 'Mount Dora', 'Mount Eaton', 'Mount Enterprise', 'Mount Ephraim', 'Mount Erie', 'Mount Etna', 'Mount Gay-Shamrock', 'Mount Gilead', 'Mount Gretna', 'Mount Gretna Heights', 'Mount Healthy', 'Mount Healthy Heights', 'Mount Hebron', 'Mount Holly', 'Mount Holly Springs', 'Mount Hood Village', 'Mount Hope', 'Mount Horeb', 'Mount Ida', 'Mount Ivy', 'Mount Jackson', 'Mount Jewett', 'Mount Joy', 'Mount Juliet', 'Mount Kisco', 'Mount Lebanon', 'Mount Lena', 'Mount Leonard', 'Mount Moriah', 'Mount Morris', 'Mount Olive', 'Mount Oliver', 'Mount Olivet', 'Mount Olympus', 'Mount Orab', 'Mount Penn', 'Mount Pleasant', 'Mount Pleasant Mills', 'Mount Plymouth', 'Mount Pocono', 'Mount Prospect', 'Mount Pulaski', 'Mount Rainier', 'Mount Repose', 'Mount Shasta', 'Mount Sinai', 'Mount Sterling', 'Mount Summit', 'Mount Union', 'Mount Vernon', 'Mount Victory', 'Mount Vista', 'Mount Washington', 'Mount Wolf', 'Mount Zion', 'Mountain', 'Mountain Brook', 'Mountain City', 'Mountain Grove', 'Mountain Home', 'Mountain Home AFB', 'Mountain Iron', 'Mountain Lake', 'Mountain Lake Park', 'Mountain Lakes', 'Mountain Mesa', 'Mountain Park', 'Mountain Pine', 'Mountain Ranch', 'Mountain Top', 'Mountain View', 'Mountain View Acres', 'Mountain Village', 'Mountainair', 'Mountainaire', 'Mountainboro', 'Mountainburg', 'Mountainhome', 'Mountainside', 'Mountlake Terrace', 'Mountville', 'Moville', 'Moweaqua', 'Mowrystown', 'Moxee', 'Moyie Springs', 'Mucarabones', 'Mud Bay', 'Mud Lake', 'Muddy', 'Muenster', 'Muir', 'Muir Beach', 'Mukilteo', 'Mukwonago', 'Mulberry', 'Mulberry Grove', 'Muldraugh', 'Muldrow', 'Mule Barn', 'Muleshoe', 'Mulga', 'Mulhall', 'Mullan', 'Mullen', 'Mullens', 'Mullica Hill', 'Mulliken', 'Mullin', 'Mullins', 'Mullinville', 'Mulvane', 'Muncie', 'Muncy', 'Munday', 'Mundelein', 'Munden', 'Munds Park', 'Munford', 'Munfordville', 'Munhall', 'Munich', 'Municipality of Monroeville', 'Municipality of Murrysville', 'Munising', 'Muniz', 'Munnsville', 'Munroe Falls', 'Munsey Park', 'Munsons Corners', 'Munster', 'Murchison', 'Murdo', 'Murdock', 'Murfreesboro', 'Murphy', 'Murphys', 'Murphys Estates', 'Murphysboro', 'Murray', 'Murray City', 'Murray Hill', 'Murraysville', 'Murrayville', 'Murrells Inlet', 'Murrieta', 'Murrieta Hot Springs', 'Murtaugh', 'Muscatine', 'Muscle Shoals', 'Muscoda', 'Muscotah', 'Muscoy', 'Muskego', 'Muskegon', 'Muskegon Heights', 'Muskogee', 'Musselshell', 'Mustang', 'Mustang Ridge', 'Muttontown', 'Mutual', 'Myers Corner', 'Myerstown', 'Myersville', 'Mylo', 'Myrtle', 'Myrtle Beach', 'Myrtle Creek', 'Myrtle Grove', 'Myrtle Point', 'Myrtletown', 'Myrtlewood', 'Mystic', 'Mystic Island', 'Myton', 'Naalehu', 'Naches', 'Naco', 'Nacogdoches', 'Nageezi', 'Nags Head', 'Naguabo', 'Nahant', 'Nahunta', 'Nakaibito', 'Naknek', 'Nampa', 'Nanakuli', 'Nanawale Estates', 'Nanticoke', 'Nantucket', 'Nanty-Glo', 'Nanuet', 'Nanwalek', 'Napa', 'Napakiak', 'Napanoch', 'Napaskiak', 'Napavine', 'Napeague', 'Naper', 'Naperville', 'Napi HQ', 'Napier Field', 'Napili-Honokowai', 'Naplate', 'Naples', 'Naples Manor', 'Naples Park', 'Napoleon', 'Napoleonville', 'Naponee', 'Nappanee', 'Naranja', 'Naranjito', 'Narberth', 'Narcissa', 'Narka', 'Narragansett Pier', 'Narrows', 'Narrowsburg', 'Naschitti', 'Naselle', 'Nash', 'Nashotah', 'Nashua', 'Nashville', 'Nashwauk', 'Nason', 'Nassau', 'Nassau Bay', 'Nassau Village-Ratliff', 'Nassawadox', 'Natalbany', 'Natalia', 'Natchez', 'Natchitoches', 'National City', 'National Park', 'Natoma', 'Natural Bridge', 'Naturita', 'Naugatuck', 'Naukati Bay', 'Nauvoo', 'Navajo', 'Navajo Mountain', 'Naval Academy', 'Navarre', 'Navarro', 'Navasota', 'Navassa', 'Navesink', 'Navy Yard City', 'Naylor', 'Naytahwaush', 'Nazareth', 'Nazlini', 'Neah Bay', 'Nebo', 'Nebo Center', 'Nebraska City', 'Necedah', 'Neche', 'Neck City', 'Nectar', 'Nederland', 'Nedrow', 'Needham', 'Needles', 'Needville', 'Neelyville', 'Neenah', 'Neeses', 'Neffs', 'Negaunee', 'Nehalem', 'Nehawka', 'Neihart', 'Neillsville', 'Neilton', 'Nekoma', 'Nekoosa', 'Nelchina', 'Neligh', 'Nellie', 'Nellieburg', 'Nellis AFB', 'Nelliston', 'Nelson', 'Nelson Lagoon', 'Nelsonville', 'Nemacolin', 'Nemaha', 'Nenahnezad', 'Nenana', 'Nenzel', 'Neodesha', 'Neoga', 'Neola', 'Neopit', 'Neosho', 'Neosho Falls', 'Neosho Rapids', 'Nephi', 'Neponset', 'Neptune Beach', 'Neptune City', 'Nerstrand', 'Nesbitt', 'Nesconset', 'Nescopeck', 'Neshkoro', 'Neskowin', 'Nespelem', 'Nespelem Community', 'Nesquehoning', 'Ness City', 'Netarts', 'Netawaka', 'Netcong', 'Nether Providence Township', 'Nettleton', 'Neuse Forest', 'Nevada', 'Nevada City', 'Neville', 'Nevis', 'New Albany', 'New Albin', 'New Alexandria', 'New Allakaket', 'New Alluwe', 'New Amsterdam', 'New Athens', 'New Auburn', 'New Augusta', 'New Baden', 'New Baltimore', 'New Bavaria', 'New Beaver', 'New Bedford', 'New Berlin', 'New Bern', 'New Bethlehem', 'New Bloomfield', 'New Bloomington', 'New Boston', 'New Boston-Morea', 'New Braunfels', 'New Bremen', 'New Brighton', 'New Britain', 'New Brockton', 'New Brunswick', 'New Buffalo', 'New Burnside', 'New Cambria', 'New Canton', 'New Carlisle', 'New Carrollton', 'New Cassel', 'New Castle', 'New Castle Northwest', 'New Centerville', 'New Chapel Hill', 'New Chicago', 'New City', 'New Columbus', 'New Concord', 'New Cordell', 'New Cumberland', 'New Deal', 'New Douglas', 'New Eagle', 'New Effington', 'New Egypt', 'New Ellenton', 'New England', 'New Era', 'New Eucha', 'New Fairview', 'New Falcon', 'New Florence', 'New Franklin', 'New Freedom', 'New Galilee', 'New Germany', 'New Glarus', 'New Grand Chain', 'New Hampton', 'New Harmony', 'New Hartford', 'New Hartford Center', 'New Haven', 'New Hebron', 'New Hempstead', 'New Holland', 'New Holstein', 'New Home', 'New Hope', 'New Houlka', 'New Hyde Park', 'New Iberia', 'New Johnsonville', 'New Kensington', 'New Kingman-Butler', 'New Kingstown', 'New Knoxville', 'New Lebanon', 'New Leipzig', 'New Lenox', 'New Lexington', 'New Liberty', 'New Lisbon', 'New Llano', 'New London', 'New Lothrop', 'New Madison', 'New Madrid', 'New Market', 'New Martinsville', 'New Meadows', 'New Melle', 'New Miami', 'New Middletown', 'New Milford', 'New Millford', 'New Minden', 'New Morgan', 'New Munich', 'New Orleans', 'New Oxford', 'New Palestine', 'New Paltz', 'New Paris', 'New Pekin', 'New Philadelphia', 'New Plymouth', 'New Port Richey', 'New Port Richey East', 'New Post', 'New Prague', 'New Preston', 'New Providence', 'New Richland', 'New Richmond', 'New Riegel', 'New Ringgold', 'New River', 'New Roads', 'New Rochelle', 'New Rockford', 'New Rome', 'New Ross', 'New Salem', 'New Salem-Buffington', 'New Sarpy', 'New Seabury', 'New Sharon', 'New Site', 'New Smyrna Beach', 'New Square', 'New Stanton', 'New Straitsville', 'New Strawn', 'New Stuyahok', 'New Suffolk', 'New Summerfield', 'New Tazewell', 'New Territory', 'New Town', 'New Trier', 'New Tulsa', 'New Ulm', 'New Underwood', 'New Vienna', 'New Virginia', 'New Washington', 'New Waterford', 'New Waverly', 'New Weston', 'New Whiteland', 'New Wilmington', 'New Windsor', 'New Witten', 'New York', 'New York Mills', 'Newark', 'Newark Valley', 'Newaygo', 'Newberg', 'Newbern', 'Newberry', 'Newborn', 'Newburg', 'Newburgh', 'Newburgh Heights', 'Newbury', 'Newburyport', 'Newcastle', 'Newcomb', 'Newcomerstown', 'Newdale', 'Newell', 'Newellton', 'Newfane', 'Newfield', 'Newfield Hamlet', 'Newfolden', 'Newhalen', 'Newhall', 'Newington', 'Newkirk', 'Newland', 'Newman', 'Newman Grove', 'Newmanstown', 'Newmarket', 'Newnan', 'Newpoint', 'Newport', 'Newport Beach', 'Newport Coast', 'Newport East', 'Newport News', 'Newry', 'Newsoms', 'Newtok', 'Newton', 'Newton Falls', 'Newton Grove', 'Newton Hamilton', 'Newtonia', 'Newtonsville', 'Newtown', 'Newtown Grant', 'Newville', 'Ney', 'Neylandville', 'Nezperce', 'Niagara', 'Niagara Falls', 'Niangua', 'Niantic', 'Niarada', 'Nibley', 'Nice', 'Niceville', 'Nicholasville', 'Nicholls', 'Nichols', 'Nichols Hills', 'Nicholson', 'Nickelsville', 'Nickerson', 'Nicollet', 'Nicoma Park', 'Niederwald', 'Nielsville', 'Nightmute', 'Nikiski', 'Nikolaevsk', 'Nikolai', 'Nikolski', 'Niland', 'Niles', 'Nilwood', 'Nimmons', 'Nimrod', 'Ninety Six', 'Ninilchik', 'Ninnekah', 'Niobrara', 'Niota', 'Niotaze', 'Nipomo', 'Niskayuna', 'Nisland', 'Nisqually Indian Community', 'Nissequogue', 'Nisswa', 'Nitro', 'Niverville', 'Niwot', 'Nixa', 'Nixon', 'Noank', 'Noatak', 'Noble', 'Noblesville', 'Nobleton', 'Nocona', 'Nodaway', 'Noel', 'Nogales', 'Nokesville', 'Nokomis', 'Nolanville', 'Nolensville', 'Noma', 'Nome', 'Nondalton', 'Nooksack', 'Noonan', 'Noonday', 'Noorvik', 'Nora', 'Nora Springs', 'Norborne', 'Norbourne Estates', 'Norcatur', 'Norco', 'Norcross', 'Nordheim', 'Norfolk', 'Norfork', 'Norge', 'Norland', 'Norlina', 'Normal', 'Norman', 'Norman Park', 'Normandy', 'Normandy Park', 'Normangee', 'Normanna', 'Norphlet', 'Norridge', 'Norridgewock', 'Norris', 'Norris City', 'Norristown', 'North', 'North Acomita Village', 'North Adams', 'North Alamo', 'North Amherst', 'North Amityville', 'North Andrews Gardens', 'North Apollo', 'North Arlington', 'North Atlanta', 'North Attleborough Center', 'North Auburn', 'North Augusta', 'North Aurora', 'North Babylon', 'North Ballston Spa', 'North Baltimore', 'North Barrington', 'North Bay', 'North Bay Shore', 'North Bay Village', 'North Beach', 'North Beach Haven', 'North Belle Vernon', 'North Bellmore', 'North Bellport', 'North Bend', 'North Bennington', 'North Berwick', 'North Bethesda', 'North Bibb', 'North Bonneville', 'North Boston', 'North Braddock', 'North Branch', 'North Brentwood', 'North Brookfield', 'North Brooksville', 'North Browning', 'North Brunswick Township', 'North Buena Vista', 'North Caldwell', 'North Canton', 'North Cape May', 'North Carrollton', 'North Catasauqua', 'North Charleroi', 'North Charleston', 'North Chevy Chase', 'North Chicago', 'North City', 'North Cleveland', 'North College Hill', 'North Collins', 'North Conway', 'North Corbin', 'North Courtland', 'North Creek', 'North Crossett', 'North Crows Nest', 'North De Land', 'North Decatur', 'North Druid Hills', 'North Eagle Butte', 'North East', 'North Eastham', 'North Edwards', 'North El Monte', 'North English', 'North Enid', 'North Escobares', 'North Fair Oaks', 'North Fairfield', 'North Falmouth', 'North Fond du Lac', 'North Fork Village', 'North Fort Myers', 'North Freedom', 'North Granby', 'North Great River', 'North Grosvenor Dale', 'North Haledon', 'North Hampton', 'North Hartsville', 'North Haven', 'North Henderson', 'North High Shoals', 'North Highlands', 'North Hills', 'North Hodge', 'North Hornell', 'North Hudson', 'North Irwin', 'North Johns', 'North Judson', 'North Kansas City', 'North Kensington', 'North Key Largo', 'North Kingsville', 'North Lakeport', 'North Lakeville', 'North Las Vegas', 'North Lauderdale', 'North Laurel', 'North Lewisburg', 'North Liberty', 'North Lilbourn', 'North Lindenhurst', 'North Little Rock', 'North Logan', 'North Loup', 'North Lynbrook', 'North Madison', 'North Manchester', 'North Mankato', 'North Marysville', 'North Massapequa', 'North Merrick', 'North Miami', 'North Miami Beach', 'North Middletown', 'North Muskegon', 'North Myrtle Beach', 'North New Hyde Park', 'North Newton', 'North Oaks', 'North Ogden', 'North Olmsted', 'North Omak', 'North Palm Beach', 'North Patchogue', 'North Pearsall', 'North Pekin', 'North Pembroke', 'North Perry', 'North Philipsburg', 'North Plainfield', 'North Plains', 'North Platte', 'North Plymouth', 'North Pole', 'North Port', 'North Potomac', 'North Powder', 'North Prairie', 'North Providence', 'North Randall', 'North Redington Beach', 'North Richland Hills', 'North Ridgeville', 'North River', 'North River Shores', 'North Riverside', 'North Robinson', 'North Rock Springs', 'North Royalton', 'North Salem', 'North Salt Lake', 'North San Pedro', 'North Sarasota', 'North Scituate', 'North Sea', 'North Seekonk', 'North Shore', 'North Sioux City', 'North Snyderville Basin', 'North Spearfish', 'North Springfield', 'North St. Paul', 'North Stanwood', 'North Star', 'North Sultan', 'North Syracuse', 'North Terre Haute', 'North Tonawanda', 'North Topsail Beach', 'North Troy', 'North Tunica', 'North Utica', 'North Vacherie', 'North Valley', 'North Valley Stream', 'North Vandergrift-Pleasant View', 'North Vernon', 'North Versailles', 'North Wales', 'North Wantagh', 'North Wardell', 'North Washington', 'North Webster', 'North Weeki Wachee', 'North Westminster', 'North Westport', 'North Wildwood', 'North Wilkesboro', 'North Windham', 'North Woodbridge', 'North Yelm', 'North York', 'North Zanesville', 'Northampton', 'Northboro', 'Northborough', 'Northbrook', 'Northcliff', 'Northeast Ithaca', 'Northern Cambria', 'Northfield', 'Northfork', 'Northgate', 'Northglenn', 'Northlake', 'Northlakes', 'Northmoor', 'Northome', 'Northport', 'Northridge', 'Northrop', 'Northumberland', 'Northvale', 'Northview', 'Northville', 'Northway', 'Northway Junction', 'Northway Village', 'Northwest', 'Northwest Harbor', 'Northwest Harborcreek', 'Northwest Harwich', 'Northwest Harwinton', 'Northwest Ithaca', 'Northwest Snohomish', 'Northwood', 'Northwoods', 'Norton', 'Norton Center', 'Norton Shores', 'Nortonville', 'Norwalk', 'Norway', 'Norwich', 'Norwood', 'Norwood Court', 'Norwood Young America', 'Notasulga', 'Notchietown', 'Notus', 'Novato', 'Novelty', 'Novi', 'Novice', 'Novinger', 'Nowata', 'Noxapater', 'Noxon', 'Noyack', 'Nuangola', 'Nucla', 'Nuevo', 'Nuiqsut', 'Nulato', 'Numa', 'Numidia', 'Nunapitchuk', 'Nunda', 'Nunez', 'Nunn', 'Nuremberg', 'Nurillo', 'Nutley', 'Nutter Fort', 'Nyack', 'Nyssa', 'O\'Brien', 'O\'Donnell', 'O\'Fallon', 'O\'Hara Township', 'O\'Kean', 'O\'Neill', 'Oacoma', 'Oak', 'Oak Brook', 'Oak City', 'Oak Creek', 'Oak Forest', 'Oak Grove', 'Oak Grove Heights', 'Oak Harbor', 'Oak Hill', 'Oak Hills', 'Oak Hills Place', 'Oak Island', 'Oak Lawn', 'Oak Leaf', 'Oak Level', 'Oak Park', 'Oak Park Heights', 'Oak Point', 'Oak Ridge', 'Oak Ridge North', 'Oak Trail Shores', 'Oak Valley', 'Oak View', 'Oakboro', 'Oakbrook', 'Oakbrook Terrace', 'Oakdale', 'Oakes', 'Oakesdale', 'Oakfield', 'Oakford', 'Oakhaven', 'Oakhurst', 'Oakland', 'Oakland Acres', 'Oakland City', 'Oakland Park', 'Oaklawn-Sunview', 'Oakley', 'Oaklyn', 'Oakman', 'Oakmont', 'Oakport', 'Oakridge', 'Oaks', 'Oakton', 'Oaktown', 'Oakvale', 'Oakview', 'Oakville', 'Oakwood', 'Oakwood Hills', 'Oakwood Park', 'Oatfield', 'Oberlin', 'Oberon', 'Obert', 'Obetz', 'Obion', 'Oblong', 'Ocala', 'Occidental', 'Occoquan', 'Ocean Acres', 'Ocean Beach', 'Ocean Bluff-Brant Rock', 'Ocean Breeze Park', 'Ocean City', 'Ocean Gate', 'Ocean Grove', 'Ocean Isle Beach', 'Ocean Park', 'Ocean Pines', 'Ocean Ridge', 'Ocean Shores', 'Ocean Springs', 'Ocean View', 'Oceana', 'Oceano', 'Oceanport', 'Oceanside', 'Ochelata', 'Ocheyedan', 'Ochlocknee', 'Ocilla', 'Ocoee', 'Oconee', 'Oconomowoc', 'Oconomowoc Lake', 'Oconto', 'Oconto Falls', 'Ocotillo', 'Ocracoke', 'Octa', 'Octavia', 'Odanah', 'Odebolt', 'Odell', 'Odem', 'Oden', 'Odenton', 'Odenville', 'Odessa', 'Odin', 'Odon', 'Odum', 'Oelrichs', 'Oelwein', 'Offerle', 'Offerman', 'Offutt AFB', 'Ogallala', 'Ogden', 'Ogden Dunes', 'Ogdensburg', 'Ogema', 'Ogilvie', 'Oglala', 'Oglesby', 'Oglethorpe', 'Ohatchee', 'Ohio', 'Ohio City', 'Ohiopyle', 'Ohioville', 'Ohiowa', 'Ohlman', 'Oil City', 'Oil Trough', 'Oildale', 'Oilton', 'Ojai', 'Ojo Amarillo', 'Ojus', 'Okabena', 'Okahumpka', 'Okanogan', 'Okarche', 'Okaton', 'Okauchee Lake', 'Okawville', 'Okay', 'Okeechobee', 'Okeene', 'Okemah', 'Okemos', 'Oketo', 'Oklahoma', 'Oklahoma City', 'Oklee', 'Okmulgee', 'Okoboji', 'Okolona', 'Oktaha', 'Ola', 'Olancha', 'Olanta', 'Olar', 'Olathe', 'Olcott', 'Old Agency', 'Old Appleton', 'Old Bennington', 'Old Bethpage', 'Old Bridge', 'Old Brookville', 'Old Brownsboro Place', 'Old Eucha', 'Old Field', 'Old Forge', 'Old Fort', 'Old Harbor', 'Old Jefferson', 'Old Mill Creek', 'Old Monroe', 'Old Mystic', 'Old Orchard', 'Old Orchard Beach', 'Old Ripley', 'Old River-Winfree', 'Old Saybrook Center', 'Old Shawneetown', 'Old Tappan', 'Old Town', 'Old Washington', 'Old Westbury', 'Olde West Chester', 'Oldenburg', 'Oldham', 'Olds', 'Oldsmar', 'Oldtown', 'Olean', 'Olga', 'Olimpo', 'Olin', 'Olivarez', 'Olive Branch', 'Olive Hill', 'Olivehurst', 'Oliver', 'Oliver Springs', 'Olivet', 'Olivette', 'Olivia', 'Oljato-Monument Valley', 'Olla', 'Ollie', 'Olmito', 'Olmitz', 'Olmos Park', 'Olmsted', 'Olmsted Falls', 'Olney', 'Olney Springs', 'Olpe', 'Olsburg', 'Olton', 'Olustee', 'Olympia', 'Olympia Fields', 'Olympia Heights', 'Olympian Village', 'Olyphant', 'Omaha', 'Omak', 'Omao', 'Omega', 'Omer', 'Omro', 'Onaga', 'Onaka', 'Onalaska', 'Onamia', 'Onancock', 'Onarga', 'Onawa', 'Onaway', 'Oneida', 'Oneida Castle', 'Onekama', 'Oneonta', 'Ong', 'Onida', 'Onion Creek', 'Onley', 'Onset', 'Onslow', 'Onsted', 'Ontario', 'Ontonagon', 'Onward', 'Onycha', 'Onyx', 'Oolitic', 'Oologah', 'Ooltewah', 'Oostburg', 'Opa-locka', 'Opa-locka North', 'Opal', 'Opal Cliffs', 'Opdyke West', 'Opelika', 'Opelousas', 'Opheim', 'Ophir', 'Opp', 'Oppelo', 'Opportunity', 'Optima', 'Oquawka', 'Oquirrh', 'Oracle', 'Oradell', 'Oran', 'Orange', 'Orange Beach', 'Orange City', 'Orange Cove', 'Orange Grove', 'Orange Lake', 'Orange Park', 'Orangeburg', 'Orangetree', 'Orangevale', 'Orangeville', 'Orbisonia', 'Orchard', 'Orchard City', 'Orchard Grass Hills', 'Orchard Hill', 'Orchard Hills', 'Orchard Homes', 'Orchard Lake Village', 'Orchard Mesa', 'Orchard Park', 'Orchards', 'Orchid', 'Orchidlands Estates', 'Orcutt', 'Ord', 'Orderville', 'Ordway', 'Ore City', 'Oreana', 'Oregon', 'Oregon City', 'Oreland', 'Orem', 'Orestes', 'Orfordville', 'Orient', 'Oriental', 'Orinda', 'Orion', 'Oriska', 'Oriskany', 'Oriskany Falls', 'Orland', 'Orland Hills', 'Orland Park', 'Orlando', 'Orleans', 'Orlinda', 'Orlovista', 'Orme', 'Ormond Beach', 'Ormond-By-The-Sea', 'Ormsby', 'Oro Valley', 'Orocovis', 'Orofino', 'Orono', 'Oronoco', 'Oronogo', 'Orosi', 'Oroville', 'Oroville East', 'Orr', 'Orrick', 'Orrstown', 'Orrtanna', 'Orrum', 'Orrville', 'Orting', 'Ortley', 'Ortonville', 'Orwell', 'Orwigsburg', 'Osage', 'Osage Beach', 'Osage City', 'Osakis', 'Osawatomie', 'Osborn', 'Osborne', 'Osburn', 'Oscarville', 'Osceola', 'Osceola Mills', 'Oscoda', 'Osgood', 'Oshkosh', 'Oskaloosa', 'Oslo', 'Osmond', 'Osnabrock', 'Oso', 'Osprey', 'Osseo', 'Ossian', 'Ossineke', 'Ossining', 'Osterdock', 'Ostrander', 'Oswayo', 'Oswego', 'Osyka', 'Otego', 'Othello', 'Otho', 'Otis', 'Otis Orchards-East Farms', 'Otisville', 'Oto', 'Otoe', 'Otsego', 'Ottawa', 'Ottawa Hills', 'Otter Creek', 'Otter Lake', 'Otterbein', 'Ottertail', 'Otterville', 'Ottosen', 'Ottoville', 'Ottumwa', 'Otway', 'Ouray', 'Outlook', 'Ouzinkie', 'Ovando', 'Overbrook', 'Overland', 'Overland Park', 'Overlea', 'Overly', 'Overton', 'Ovid', 'Oviedo', 'Ovilla', 'Owaneco', 'Owasa', 'Owasso', 'Owatonna', 'Owego', 'Owen', 'Owendale', 'Owens Cross Roads', 'Owensboro', 'Owensville', 'Owenton', 'Owings', 'Owings Mills', 'Owingsville', 'Owl Creek', 'Owl Ranch-Amargosa', 'Owosso', 'Owyhee', 'Oxbow', 'Oxford', 'Oxford Junction', 'Oxnard', 'Oxoboxo River', 'Oxon Hill-Glassmanor', 'Oyehut-Hogans Corner', 'Oyens', 'Oyster Bay', 'Oyster Bay Cove', 'Oyster Creek', 'Ozan', 'Ozark', 'Ozawkie', 'Ozona', 'Paauilo', 'Pablo', 'Pace', 'Pacheco', 'Pachuta', 'Pacific', 'Pacific City', 'Pacific Grove', 'Pacific Junction', 'Pacifica', 'Packwood', 'Pacolet', 'Paddock Lake', 'Paden', 'Paden City', 'Padroni', 'Paducah', 'Page', 'Page Park', 'Pagedale', 'Pageland', 'Pagosa Springs', 'Paguate', 'Pahala', 'Pahoa', 'Pahokee', 'Pahrump', 'Paia', 'Paincourtville', 'Paine Field-Lake Stickney', 'Painesville', 'Paint', 'Paint Rock', 'Painted Post', 'Painter', 'Paintsville', 'Paisley', 'Pajaro', 'Pajonal', 'Pakala Village', 'Palacios', 'Palatine', 'Palatine Bridge', 'Palatka', 'Palco', 'Palenville', 'Palermo', 'Palestine', 'Palisade', 'Palisades', 'Palisades Park', 'Palm Aire', 'Palm Bay', 'Palm Beach', 'Palm Beach Gardens', 'Palm Beach Shores', 'Palm City', 'Palm Coast', 'Palm Desert', 'Palm Harbor', 'Palm River-Clair Mel', 'Palm Shores', 'Palm Springs', 'Palm Springs North', 'Palm Valley', 'Palmarejo', 'Palmas', 'Palmdale', 'Palmer', 'Palmer Heights', 'Palmer Lake', 'Palmerton', 'Palmetto', 'Palmetto Estates', 'Palmhurst', 'Palmona Park', 'Palmview', 'Palmview South', 'Palmyra', 'Palo', 'Palo Alto', 'Palo Cedro', 'Palo Seco', 'Palo Verde', 'Palomas', 'Palos Heights', 'Palos Hills', 'Palos Park', 'Palos Verdes Estates', 'Palouse', 'Pampa', 'Pamplico', 'Pamplin City', 'Pana', 'Panama', 'Panama City', 'Panama City Beach', 'Pandora', 'Pangburn', 'Panguitch', 'Panhandle', 'Panola', 'Panora', 'Panorama Park', 'Panorama Village', 'Pantego', 'Panthersville', 'Paola', 'Paoli', 'Paonia', 'Papaikou', 'Papillion', 'Papineau', 'Parachute', 'Paradis', 'Paradise', 'Paradise Heights', 'Paradise Hill', 'Paradise Valley', 'Paragon', 'Paragonah', 'Paragould', 'Paraje', 'Paramount', 'Paramount-Long Meadow', 'Paramus', 'Parc', 'Parcelas La Milagrosa', 'Parcelas Nuevas', 'Parcelas Peñuelas', 'Parchment', 'Pardeeville', 'Paris', 'Parish', 'Park', 'Park City', 'Park Falls', 'Park Forest', 'Park Forest Village', 'Park Hill', 'Park Hills', 'Park Lake', 'Park Layne', 'Park Rapids', 'Park Ridge', 'Park River', 'Park View', 'Parkdale', 'Parker', 'Parker City', 'Parker School', 'Parker Strip', 'Parkers Crossroads', 'Parkers Prairie', 'Parkers-Iron Springs', 'Parkersburg', 'Parkerville', 'Parkesburg', 'Parkin', 'Parkland', 'Parkline', 'Parkman', 'Parks', 'Parksdale', 'Parkside', 'Parksley', 'Parkston', 'Parksville', 'Parkton', 'Parkville', 'Parkway', 'Parkway Village', 'Parkway-South Sacramento', 'Parkwood', 'Parlier', 'Parma', 'Parma Heights', 'Parmele', 'Parmelee', 'Parnell', 'Parole', 'Parowan', 'Parral', 'Parris Island', 'Parrish', 'Parrott', 'Parrottsville', 'Parryville', 'Parshall', 'Parsons', 'Partridge', 'Pasadena', 'Pasadena Hills', 'Pasadena Park', 'Pascagoula', 'Pasco', 'Pascoag', 'Pascola', 'Pass Christian', 'Passaic', 'Pastos', 'Patagonia', 'Pataskala', 'Patch Grove', 'Patchogue', 'Pateros', 'Paterson', 'Patillas', 'Patmos', 'Patoka', 'Paton', 'Patrick', 'Patrick Springs', 'Patriot', 'Patterson', 'Patterson Heights', 'Patterson Springs', 'Patterson Township', 'Pattersonville-Rotterdam Junction', 'Pattison', 'Patton', 'Patton Village', 'Pattonsburg', 'Paukaa', 'Paul', 'Paulden', 'Paulding', 'Paullina', 'Pauls Valley', 'Paulsboro', 'Pavillion', 'Pavo', 'Paw Paw', 'Paw Paw Lake', 'Pawcatuck', 'Pawhuska', 'Pawleys Island', 'Pawling', 'Pawnee', 'Pawnee City', 'Pawnee Rock', 'Pawtucket', 'Pax', 'Paxico', 'Paxson', 'Paxtang', 'Paxton', 'Paxtonia', 'Paxtonville', 'Paxville', 'Payette', 'Payne', 'Payne Springs', 'Paynesville', 'Payson', 'Pe Ell', 'Pea Ridge', 'Peabody', 'Peaceful Valley', 'Peach Lake', 'Peach Orchard', 'Peach Springs', 'Peachland', 'Peachtree City', 'Peak', 'Peapack and Gladstone', 'Pearisburg', 'Pearl', 'Pearl Beach', 'Pearl City', 'Pearl River', 'Pearland', 'Pearlington', 'Pearsall', 'Pearson', 'Pearsonville', 'Pease', 'Peavine', 'Pebble Creek', 'Pecan Acres', 'Pecan Gap', 'Pecan Grove', 'Pecan Hill', 'Pecan Plantation', 'Pecatonica', 'Peck', 'Peconic', 'Pecos', 'Peculiar', 'Pedley', 'Pedro Bay', 'Peebles', 'Peekskill', 'Peeples Valley', 'Peetz', 'Peever', 'Pegram', 'Pekin', 'Pelahatchie', 'Peletier', 'Pelham', 'Pelham Manor', 'Pelican', 'Pelican Bay', 'Pelican Rapids', 'Pelion', 'Pell City', 'Pell Lake', 'Pella', 'Pellston', 'Pelzer', 'Pemberton', 'Pemberton Heights', 'Pemberville', 'Pembina', 'Pembroke', 'Pembroke Park', 'Pembroke Pines', 'Pen Argyl', 'Pena Blanca', 'Penalosa', 'Penasco', 'Penbrook', 'Pender', 'Pendergrass', 'Pendleton', 'Penelope', 'Penermon', 'Penhook', 'Peninsula', 'Penitas', 'Penn', 'Penn Hills', 'Penn Lake Park', 'Penn Valley', 'Penn Wynne', 'Penn Yan', 'Penndel', 'Penney Farms', 'Pennington', 'Pennington Gap', 'Pennock', 'Penns Creek', 'Penns Grove', 'Pennsauken', 'Pennsboro', 'Pennsburg', 'Pennsbury Village', 'Pennsville', 'Pennville', 'Penrose', 'Pensacola', 'Pentwater', 'Peoria', 'Peoria Heights', 'Peosta', 'Peotone', 'Pepeekeo', 'Pepin', 'Pepper Pike', 'Pepperell', 'Pequot Lakes', 'Peralta', 'Percy', 'Perham', 'Peridot', 'Perkasie', 'Perkins', 'Perkinsville', 'Perla', 'Perley', 'Pernitas Point', 'Perrinton', 'Perris', 'Perry', 'Perry Hall', 'Perry Heights', 'Perry Park', 'Perryman', 'Perryopolis', 'Perrysburg', 'Perrysville', 'Perryton', 'Perrytown', 'Perryville', 'Persia', 'Perth', 'Perth Amboy', 'Peru', 'Peshtigo', 'Pesotum', 'Petal', 'Petaluma', 'Peter', 'Peterborough', 'Petersburg', 'Peterson', 'Peterstown', 'Petersville', 'Petoskey', 'Petrey', 'Petrolia', 'Petronila', 'Pettibone', 'Pettit', 'Pettus', 'Pevely', 'Pewamo', 'Pewaukee', 'Pewee Valley', 'Peña Pobre', 'Peñuelas', 'Pflugerville', 'Pharr', 'Phelps', 'Phenix', 'Phenix City', 'Phil Campbell', 'Philadelphia', 'Philip', 'Philippi', 'Philipsburg', 'Phillips', 'Phillipsburg', 'Phillipstown', 'Philmont', 'Philo', 'Philomath', 'Phoenicia', 'Phoenix', 'Phoenix Lake-Cedar Ridge', 'Phoenixville', 'Picayune', 'Picher', 'Pick City', 'Pickens', 'Pickensville', 'Pickering', 'Pickerington', 'Pickrell', 'Pickstown', 'Picnic Point-North Lynnwood', 'Pico Rivera', 'Picture Rocks', 'Picuris Pueblo', 'Piedmont', 'Piedra Gorda', 'Pierce', 'Pierce City', 'Pierceton', 'Piermont', 'Pierpont', 'Pierre', 'Pierre Part', 'Pierron', 'Pierson', 'Pierz', 'Pigeon', 'Pigeon Creek', 'Pigeon Falls', 'Pigeon Forge', 'Piggott', 'Pike', 'Pike Creek', 'Pike Road', 'Pikesville', 'Piketon', 'Pikeville', 'Pilger', 'Pillager', 'Pillow', 'Pillsbury', 'Pilot Grove', 'Pilot Knob', 'Pilot Mound', 'Pilot Mountain', 'Pilot Point', 'Pilot Rock', 'Pilot Station', 'Pima', 'Pimmit Hills', 'Pin Oak Acres', 'Pinardville', 'Pinch', 'Pinckard', 'Pinckney', 'Pinckneyville', 'Pinconning', 'Pindall', 'Pine', 'Pine Apple', 'Pine Beach', 'Pine Bluff', 'Pine Bluffs', 'Pine Bush', 'Pine Castle', 'Pine City', 'Pine Crest', 'Pine Forest', 'Pine Glen', 'Pine Grove', 'Pine Grove Mills', 'Pine Haven', 'Pine Hill', 'Pine Hills', 'Pine Hollow', 'Pine Island', 'Pine Island Center', 'Pine Island Ridge', 'Pine Knoll Shores', 'Pine Knot', 'Pine Lake', 'Pine Lakes', 'Pine Lawn', 'Pine Level', 'Pine Manor', 'Pine Mountain', 'Pine Mountain Club', 'Pine Plains', 'Pine Point', 'Pine Prairie', 'Pine Ridge', 'Pine Ridge at Crestwood', 'Pine River', 'Pine Springs', 'Pine Valley', 'Pine Village', 'Pinebluff', 'Pinecrest', 'Pinedale', 'Pinehill', 'Pinehurst', 'Pineland', 'Pinellas Park', 'Pinesdale', 'Pinetop-Lakeside', 'Pinetops', 'Pineview', 'Pineville', 'Pinewood', 'Pinewood Estates', 'Piney', 'Piney Green', 'Piney Point Village', 'Piney View', 'Pingree', 'Pingree Grove', 'Pinhook', 'Pinhook Corners', 'Pink', 'Pink Hill', 'Pinole', 'Pinon', 'Pinson', 'Pioneer', 'Pioneer Village', 'Piper City', 'Piperton', 'Pipestone', 'Pippa Passes', 'Piqua', 'Pirtleville', 'Piru', 'Pisek', 'Pisgah', 'Pisinemo', 'Pismo Beach', 'Pistakee Highlands', 'Pitcairn', 'Pitkas Point', 'Pitkin', 'Pitman', 'Pitsburg', 'Pittman', 'Pittman Center', 'Pitts', 'Pittsboro', 'Pittsburg', 'Pittsburgh', 'Pittsfield', 'Pittsford', 'Pittston', 'Pittsville', 'Pixley', 'Placentia', 'Placerville', 'Placid Lakes', 'Placitas', 'Plain', 'Plain City', 'Plain Dealing', 'Plain View', 'Plainedge', 'Plainfield', 'Plainfield Village', 'Plains', 'Plainsboro Center', 'Plainview', 'Plainville', 'Plainwell', 'Planada', 'Plandome', 'Plandome Heights', 'Plandome Manor', 'Plankinton', 'Plano', 'Plant City', 'Plantation', 'Plantation Island', 'Plantation Mobile Home Park', 'Plantersville', 'Plaquemine', 'Platea', 'Platinum', 'Plato', 'Platte', 'Platte Center', 'Platte City', 'Platte Woods', 'Plattekill', 'Platteville', 'Plattsburg', 'Plattsburgh', 'Plattsburgh West', 'Plattsmouth', 'Plaucheville', 'Playa Fortuna', 'Playita', 'Playita Cortada', 'Plaza', 'Pleak', 'Pleasant City', 'Pleasant Dale', 'Pleasant Gap', 'Pleasant Garden', 'Pleasant Grove', 'Pleasant Groves', 'Pleasant Hill', 'Pleasant Hills', 'Pleasant Hope', 'Pleasant Lake', 'Pleasant Plain', 'Pleasant Plains', 'Pleasant Prairie', 'Pleasant Ridge', 'Pleasant Run', 'Pleasant Run Farm', 'Pleasant Valley', 'Pleasant View', 'Pleasanton', 'Pleasantville', 'Pleasure Ridge Park', 'Pleasureville', 'Plentywood', 'Plevna', 'Plover', 'Plum', 'Plum Branch', 'Plum City', 'Plum Grove', 'Plum Springs', 'Plumas Eureka', 'Plumerville', 'Plummer', 'Plumville', 'Plymouth', 'Plymouth Meeting', 'Plymouth Township', 'Plymouth Village', 'Plymptonville', 'Poca', 'Pocahontas', 'Pocasset', 'Pocatello', 'Pocola', 'Pocomoke City', 'Pocono Pines', 'Poestenkill', 'Poinciana', 'Point', 'Point Arena', 'Point Baker', 'Point Blank', 'Point Clear', 'Point Comfort', 'Point Hope', 'Point Lay', 'Point Lookout', 'Point MacKenzie', 'Point Marion', 'Point Pleasant', 'Point Pleasant Beach', 'Point Reyes Station', 'Point of Rocks', 'Poipu', 'Pojoaque', 'Poland', 'Pole Ojea', 'Polk', 'Polk City', 'Polkton', 'Polkville', 'Pollard', 'Pollock', 'Pollock Pines', 'Pollocksville', 'Polo', 'Polson', 'Pomaria', 'Pomeroy', 'Pomona', 'Pomona Park', 'Pompano Beach', 'Pompano Beach Highlands', 'Pompano Estates', 'Pompton Lakes', 'Ponca', 'Ponca City', 'Ponce', 'Ponce Inlet', 'Ponce de Leon', 'Poncha Springs', 'Ponchatoula', 'Pond Creek', 'Ponder', 'Ponderay', 'Ponderosa', 'Ponderosa Park', 'Ponemah', 'Poneto', 'Pontiac', 'Pontoon Beach', 'Pontoosuc', 'Pontotoc', 'Pooler', 'Poolesville', 'Pope', 'Pope AFB', 'Pope-Vannoy Landing', 'Popejoy', 'Poplar', 'Poplar Bluff', 'Poplar Grove', 'Poplar Hills', 'Poplar-Cotton Center', 'Poplarville', 'Popponesset', 'Popponesset Island', 'Poquonock Bridge', 'Poquoson', 'Poquott', 'Porcupine', 'Port Alexander', 'Port Allegany', 'Port Allen', 'Port Alsworth', 'Port Angeles', 'Port Angeles East', 'Port Aransas', 'Port Arthur', 'Port Austin', 'Port Barre', 'Port Byron', 'Port Carbon', 'Port Charlotte', 'Port Chester', 'Port Clarence', 'Port Clinton', 'Port Costa', 'Port Deposit', 'Port Dickinson', 'Port Edwards', 'Port Ewen', 'Port Gibson', 'Port Graham', 'Port Hadlock-Irondale', 'Port Heiden', 'Port Henry', 'Port Hope', 'Port Hueneme', 'Port Huron', 'Port Isabel', 'Port Jefferson', 'Port Jefferson Station', 'Port Jervis', 'Port La Belle', 'Port Lavaca', 'Port Leyden', 'Port Lions', 'Port Ludlow', 'Port Mansfield', 'Port Matilda', 'Port Monmouth', 'Port Neches', 'Port Norris', 'Port Orange', 'Port Orchard', 'Port Orford', 'Port Protection', 'Port Reading', 'Port Republic', 'Port Richey', 'Port Royal', 'Port Salerno', 'Port Sanilac', 'Port St. Joe', 'Port St. John', 'Port St. Lucie', 'Port St. Lucie-River Park', 'Port Sulphur', 'Port Tobacco Village', 'Port Townsend', 'Port Trevorton', 'Port Vincent', 'Port Vue', 'Port Washington', 'Port Washington North', 'Port Wentworth', 'Port William', 'Portage', 'Portage Creek', 'Portage Des Sioux', 'Portage Lakes', 'Portageville', 'Portal', 'Portales', 'Porter', 'Porter Heights', 'Porterdale', 'Portersville', 'Porterville', 'Portia', 'Portis', 'Portland', 'Portola', 'Portola Hills', 'Portola Valley', 'Portsmouth', 'Portville', 'Porum', 'Posen', 'Poseyville', 'Post', 'Post Falls', 'Post Oak Bend City', 'Poston', 'Postville', 'Potala Pastillo', 'Poteau', 'Poteet', 'Poth', 'Potlatch', 'Potomac', 'Potomac Heights', 'Potosi', 'Potsdam', 'Pottawattamie Park', 'Potter', 'Potter Lake', 'Potterville', 'Potts Camp', 'Pottsboro', 'Pottsgrove', 'Pottstown', 'Pottsville', 'Potwin', 'Poughkeepsie', 'Poulan', 'Poulsbo', 'Poultney', 'Pound', 'Poway', 'Powder River', 'Powder Springs', 'Powderly', 'Powderville', 'Powell', 'Powells Crossroads', 'Powellsville', 'Powellton', 'Power', 'Powers', 'Powers Lake', 'Powersville', 'Powhatan', 'Powhatan Point', 'Powhattan', 'Poydras', 'Poyen', 'Poynette', 'Poynor', 'Prado Verde', 'Prague', 'Prairie City', 'Prairie Creek', 'Prairie Farm', 'Prairie Grove', 'Prairie Home', 'Prairie Ridge', 'Prairie Rose', 'Prairie View', 'Prairie Village', 'Prairie du Chien', 'Prairie du Rocher', 'Prairie du Sac', 'Prairieburg', 'Prathersville', 'Pratt', 'Prattsville', 'Prattville', 'Premont', 'Prentice', 'Prentiss', 'Prescott', 'Prescott Valley', 'Presho', 'Presidential Lakes Estates', 'Presidio', 'Presque Isle', 'Preston', 'Preston Heights', 'Preston-Potter Hollow', 'Prestonsburg', 'Prestonville', 'Pretty Bayou', 'Pretty Prairie', 'Price', 'Priceville', 'Prichard', 'Prien', 'Priest Point', 'Priest River', 'Primera', 'Primghar', 'Primrose', 'Prince Frederick', 'Princes Lakes', 'Princess Anne', 'Princeton', 'Princeton Junction', 'Princeton Meadows', 'Princeton North', 'Princeville', 'Prineville', 'Pringle', 'Prinsburg', 'Prior Lake', 'Pritchett', 'Privateer', 'Proctor', 'Proctorville', 'Progreso', 'Progreso Lakes', 'Progress', 'Progress Village', 'Promise City', 'Promised Land', 'Prompton', 'Prophetstown', 'Prospect', 'Prospect Heights', 'Prospect Park', 'Prosper', 'Prosperity', 'Prosser', 'Protection', 'Protivin', 'Provencal', 'Providence', 'Provincetown', 'Provo', 'Prudenville', 'Prudhoe Bay', 'Prue', 'Prunedale', 'Pryor', 'Pryor Creek', 'Puako', 'Puckett', 'Pueblito del Río', 'Pueblo', 'Pueblo Pintado', 'Pueblo West', 'Pueblo of Sandia Village', 'Puerto Real', 'Puhi', 'Pukalani', 'Pukwana', 'Pulaski', 'Pullman', 'Pump Back', 'Pumphrey', 'Pumpkin Center', 'Punaluu', 'Punta Gorda', 'Punta Rassa', 'Punta Santiago', 'Punxsutawney', 'Pupukea', 'Purcell', 'Purcellville', 'Purdin', 'Purdy', 'Purple Sage', 'Purvis', 'Puryear', 'Put-in-Bay', 'Putnam', 'Putnam District', 'Putnam Lake', 'Putney', 'Puxico', 'Puyallup', 'Pyatt', 'Pymatuning Central', 'Pymatuning North', 'Pymatuning South', 'Pyote', 'Pájaros', 'Quail', 'Quail Valley', 'Quaker City', 'Quakertown', 'Quamba', 'Quanah', 'Quantico', 'Quantico Station', 'Quapaw', 'Quarryville', 'Quartz Hill', 'Quartzsite', 'Quasqueton', 'Quay', 'Quebrada', 'Quebradillas', 'Queen Anne', 'Queen City', 'Queen Creek', 'Queen Valley', 'Queenstown', 'Quemado', 'Quenemo', 'Quentin', 'Questa', 'Quilcene', 'Quimby', 'Quinby', 'Quincy', 'Quinebaug', 'Quinhagak', 'Quinlan', 'Quinn', 'Quinnesec', 'Quintana', 'Quinter', 'Quinton', 'Quinwood', 'Quioque', 'Quitaque', 'Quitman', 'Qulin', 'Quogue', 'Raceland', 'Racine', 'Radar Base', 'Radcliff', 'Radcliffe', 'Radersburg', 'Radford', 'Radisson', 'Radium', 'Radium Springs', 'Radnor Township', 'Radom', 'Raeford', 'Raemon', 'Rafael Capó', 'Rafael González', 'Rafael Hernández', 'Rafter J Ranch', 'Ragan', 'Ragland', 'Rahway', 'Raiford', 'Rail Road Flat', 'Railroad', 'Rainbow', 'Rainbow City', 'Rainelle', 'Rainier', 'Rainsburg', 'Rainsville', 'Raisin City', 'Rake', 'Raleigh', 'Raleigh Hills', 'Ralls', 'Ralston', 'Ramah', 'Ramblewood', 'Ramblewood East', 'Ramer', 'Ramey', 'Ramona', 'Ramos', 'Rampart', 'Ramseur', 'Ramsey', 'Ramtown', 'Ranburne', 'Ranchester', 'Ranchette Estates', 'Ranchettes', 'Ranchitos Las Lomas', 'Rancho Alegre', 'Rancho Banquete', 'Rancho Calaveras', 'Rancho Chico', 'Rancho Cordova', 'Rancho Cucamonga', 'Rancho Mirage', 'Rancho Murieta', 'Rancho Palos Verdes', 'Rancho San Diego', 'Rancho Santa Fe', 'Rancho Santa Margarita', 'Rancho Tehama Reserve', 'Rancho Viejo', 'Ranchos Penitas West', 'Ranchos de Taos', 'Randalia', 'Randall', 'Randallstown', 'Randleman', 'Randlett', 'Randolph', 'Random Lake', 'Randsburg', 'Rangely', 'Ranger', 'Rangerville', 'Ranier', 'Rankin', 'Ranlo', 'Ransom', 'Ransom Canyon', 'Ransomville', 'Rantoul', 'Raoul', 'Rapid City', 'Rapid Valley', 'Rapids', 'Rapids City', 'Rarden', 'Raritan', 'Ratamosa', 'Ratcliff', 'Rathbun', 'Rathdrum', 'Ratliff City', 'Raton', 'Rattan', 'Ravalli', 'Raven', 'Ravena', 'Ravenden', 'Ravenden Springs', 'Ravenel', 'Ravenna', 'Ravensdale', 'Ravenswood', 'Ravenswood Estates', 'Ravenwood', 'Ravia', 'Ravine', 'Ravinia', 'Rawlins', 'Rawson', 'Ray', 'Ray City', 'Rayland', 'Rayle', 'Raymer', 'Raymond', 'Raymondville', 'Raymore', 'Rayne', 'Raynham', 'Raynham Center', 'Raytown', 'Rayville', 'Raywick', 'Rea', 'Reader', 'Reading', 'Readlyn', 'Readstown', 'Realitos', 'Reamstown', 'Reardan', 'Reasnor', 'Rebecca', 'Rebersburg', 'Rector', 'Red Bank', 'Red Bay', 'Red Bluff', 'Red Boiling Springs', 'Red Bud', 'Red Butte', 'Red Chute', 'Red Cliff', 'Red Cloud', 'Red Creek', 'Red Devil', 'Red Dog Mine', 'Red Feather Lakes', 'Red Hill', 'Red Hook', 'Red Jacket', 'Red Lake', 'Red Lake Falls', 'Red Level', 'Red Lick', 'Red Lion', 'Red Lodge', 'Red Mesa', 'Red Oak', 'Red Oaks Mill', 'Red River', 'Red Rock', 'Red Springs', 'Red Wing', 'Redan', 'Redbird', 'Redbird Smith', 'Redby', 'Reddick', 'Redding', 'Redfield', 'Redford', 'Redgranite', 'Redings Mill', 'Redington Beach', 'Redington Shores', 'Redkey', 'Redland', 'Redlands', 'Redmon', 'Redmond', 'Redondo Beach', 'Redstone Arsenal', 'Redwater', 'Redway', 'Redwood', 'Redwood City', 'Redwood Falls', 'Ree Heights', 'Reece City', 'Reed', 'Reed City', 'Reed Creek', 'Reed Point', 'Reeder', 'Reedley', 'Reeds', 'Reeds Spring', 'Reedsburg', 'Reedsport', 'Reedsville', 'Reedy', 'Reese', 'Reese Center', 'Reeseville', 'Reeves', 'Reevesville', 'Reform', 'Refugio', 'Regal', 'Regan', 'Regent', 'Regina', 'Register', 'Rehobeth', 'Rehoboth Beach', 'Reid Hope King', 'Reidland', 'Reidsville', 'Reidville', 'Reiffton', 'Reile\'s Acres', 'Reinbeck', 'Reinerton-Orwin-Muir', 'Reisterstown', 'Reklaw', 'Relampago', 'Reliance', 'Rembert', 'Rembrandt', 'Remer', 'Remerton', 'Reminderville', 'Remington', 'Remsen', 'Remsenburg-Speonk', 'Remy', 'Rendon', 'Rendville', 'Renfrow', 'Renick', 'Rennert', 'Renningers', 'Reno', 'Renova', 'Renovo', 'Rensselaer', 'Rensselaer Falls', 'Rentiesville', 'Renton', 'Rentz', 'Renville', 'Renwick', 'Repton', 'Republic', 'Republican City', 'Resaca', 'Reserve', 'Reserve Township', 'Rest Haven', 'Reston', 'Retreat', 'Reubens', 'Revere', 'Revillo', 'Rewey', 'Rex', 'Rexburg', 'Rexford', 'Reydon', 'Reyno', 'Reynolds', 'Reynoldsburg', 'Reynoldsville', 'Rhame', 'Rheems', 'Rhine', 'Rhinebeck', 'Rhineland', 'Rhinelander', 'Rhodell', 'Rhodes', 'Rhodhiss', 'Rhome', 'Rialto', 'Rib Lake', 'Rib Mountain', 'Rice', 'Rice Lake', 'Riceboro', 'Rices Landing', 'Riceville', 'Rich Creek', 'Rich Hill', 'Rich Square', 'Richards', 'Richardson', 'Richardton', 'Richboro', 'Richburg', 'Richey', 'Richfield', 'Richfield Springs', 'Richgrove', 'Richland', 'Richland Center', 'Richland Hills', 'Richland Springs', 'Richlands', 'Richlandtown', 'Richlawn', 'Richmond', 'Richmond Heights', 'Richmond Hill', 'Richmond West', 'Richmondville', 'Richton', 'Richton Park', 'Richview', 'Richville', 'Richwood', 'Rickardsville', 'Ricketts', 'Rickreall', 'Rico', 'Riddle', 'Riddleville', 'Ridge', 'Ridge Farm', 'Ridge Manor', 'Ridge Spring', 'Ridge Wood Heights', 'Ridgecrest', 'Ridgefield', 'Ridgefield Park', 'Ridgeland', 'Ridgeley', 'Ridgely', 'Ridgemark', 'Ridgeside', 'Ridgetop', 'Ridgeville', 'Ridgeway', 'Ridgewood', 'Ridgway', 'Ridley Park', 'Ridott', 'Riegelsville', 'Rienzi', 'Riesel', 'Rifle', 'Rifton', 'Rigby', 'Riggins', 'Riley', 'Rimersburg', 'Rinard', 'Rincon', 'Rincón', 'Ringgold', 'Ringling', 'Ringsted', 'Ringtown', 'Ringwood', 'Rio', 'Rio Bravo', 'Rio Chiquito', 'Rio Communities', 'Rio Communities North', 'Rio Dell', 'Rio Grande', 'Rio Grande City', 'Rio Hondo', 'Rio Linda', 'Rio Lucio', 'Rio Rancho', 'Rio Rico Northeast', 'Rio Rico Northwest', 'Rio Rico Southeast', 'Rio Rico Southwest', 'Rio Verde', 'Rio Vista', 'Rio del Mar', 'Rio en Medio', 'Ripley', 'Ripon', 'Rippey', 'Ririe', 'Risco', 'Rising City', 'Rising Star', 'Rising Sun', 'Rising Sun-Lebanon', 'Risingsun', 'Rison', 'Ritchey', 'Rittman', 'Ritzville', 'Riva', 'River Bend', 'River Bluff', 'River Bottom', 'River Edge', 'River Falls', 'River Forest', 'River Grove', 'River Heights', 'River Hills', 'River Oaks', 'River Ridge', 'River Road', 'River Rouge', 'River Vale', 'Riverbank', 'Riverbend', 'Riverdale', 'Riverdale Park', 'Rivergrove', 'Riverhead', 'Riverland Village', 'Riverlea', 'Riverside', 'Riverton', 'Riverton-Boulevard Park', 'Riverview', 'Riverwood', 'Riverwoods', 'Rives', 'Rivesville', 'Riviera Beach', 'Roachdale', 'Roaming Shores', 'Roan Mountain', 'Roann', 'Roanoke', 'Roanoke Rapids', 'Roaring Spring', 'Roaring Springs', 'Robards', 'Robbins', 'Robbinsdale', 'Robbinsville', 'Robeline', 'Robersonville', 'Robert Lee', 'Roberta', 'Roberts', 'Robertsdale', 'Robertson', 'Robesonia', 'Robin Glen-Indiantown', 'Robins', 'Robins AFB', 'Robinson', 'Robinson Township', 'Robinwood', 'Robstown', 'Roby', 'Roca', 'Rochelle', 'Rochelle Park', 'Rocheport', 'Rochester', 'Rochester Hills', 'Rock City', 'Rock Creek', 'Rock Falls', 'Rock Hall', 'Rock Hill', 'Rock Island', 'Rock Island Arsenal', 'Rock Mills', 'Rock Point', 'Rock Port', 'Rock Rapids', 'Rock River', 'Rock Springs', 'Rock Valley', 'Rockaway', 'Rockaway Beach', 'Rockbridge', 'Rockcreek', 'Rockdale', 'Rockfish', 'Rockford', 'Rockham', 'Rockhill Furnace', 'Rockingham', 'Rocklake', 'Rockland', 'Rockledge', 'Rockleigh', 'Rocklin', 'Rockmart', 'Rockport', 'Rocksprings', 'Rockton', 'Rockvale', 'Rockville', 'Rockville Centre', 'Rockwall', 'Rockwell', 'Rockwell City', 'Rockwood', 'Rocky', 'Rocky Ford', 'Rocky Hill', 'Rocky Mound', 'Rocky Mount', 'Rocky Mountain', 'Rocky Point', 'Rocky Ridge', 'Rocky Ripple', 'Rocky River', 'Rodeo', 'Rodessa', 'Rodman', 'Rodney', 'Rodney Village', 'Roe', 'Roebuck', 'Roeland Park', 'Roff', 'Rogers', 'Rogers City', 'Rogersville', 'Rogue River', 'Rohnert Park', 'Rohrersville', 'Rohrsburg', 'Roland', 'Rolesville', 'Rolette', 'Rolfe', 'Rolla', 'Rolling Fields', 'Rolling Fork', 'Rolling Hills', 'Rolling Hills Estates', 'Rolling Meadows', 'Rolling Oaks', 'Rollingstone', 'Rollingwood', 'Rollins', 'Roma', 'Roma Creek', 'Roman Forest', 'Rome', 'Rome City', 'Romeo', 'Romeoville', 'Romney', 'Romoland', 'Romulus', 'Ronald', 'Ronan', 'Ronceverte', 'Ronda', 'Rondo', 'Ronkonkoma', 'Ronneby', 'Roodhouse', 'Roopville', 'Roosevelt', 'Roosevelt Gardens', 'Roosevelt Park', 'Roosevelt Roads', 'Roper', 'Ropesville', 'Rosa', 'Rosa Sánchez', 'Rosalia', 'Rosalie', 'Rosamond', 'Rosaryville', 'Roscoe', 'Roscommon', 'Rose Bud', 'Rose City', 'Rose Creek', 'Rose Hill', 'Rose Hill Acres', 'Rose Lodge', 'Rose Valley', 'Roseau', 'Roseboro', 'Rosebud', 'Roseburg', 'Roseburg North', 'Rosebush', 'Rosedale', 'Roseland', 'Roselawn', 'Roselle', 'Roselle Park', 'Rosemead', 'Rosemont', 'Rosemount', 'Rosenberg', 'Rosendale', 'Rosendale Village', 'Rosenhayn', 'Rosepine', 'Roseto', 'Roseville', 'Rosewood Heights', 'Rosholt', 'Rosiclare', 'Rosita North', 'Rosita South', 'Roslyn', 'Roslyn Estates', 'Roslyn Harbor', 'Roslyn Heights', 'Rosman', 'Ross', 'Ross Township', 'Rossburg', 'Rosser', 'Rossford', 'Rossie', 'Rossiter', 'Rosslyn Farms', 'Rossmoor', 'Rosston', 'Rossville', 'Roswell', 'Rotan', 'Rothbury', 'Rothsay', 'Rothschild', 'Rothsville', 'Rothville', 'Rotonda', 'Rotterdam', 'Rough Rock', 'Round Hill', 'Round Lake', 'Round Lake Beach', 'Round Lake Heights', 'Round Lake Park', 'Round Mountain', 'Round Rock', 'Round Top', 'Round Valley', 'Roundup', 'Rouses Point', 'Rouseville', 'Rouzerville', 'Rowan', 'Rowena', 'Rowesville', 'Rowland', 'Rowland Heights', 'Rowlesburg', 'Rowlett', 'Rowley', 'Roxana', 'Roxboro', 'Roxborough Park', 'Roxie', 'Roxobel', 'Roxton', 'Roy', 'Royal', 'Royal Center', 'Royal City', 'Royal Lakes', 'Royal Oak', 'Royal Palm Beach', 'Royal Palm Estates', 'Royal Palm Ranches', 'Royal Pines', 'Royalton', 'Royersford', 'Royse City', 'Royston', 'Rozel', 'Rubidoux', 'Ruby', 'Rudd', 'Rudolph', 'Rudy', 'Rudyard', 'Rufus', 'Rugby', 'Ruidoso', 'Ruidoso Downs', 'Rule', 'Ruleville', 'Rulo', 'Ruma', 'Rumford', 'Rumson', 'Runaway Bay', 'Runge', 'Runnells', 'Runnemede', 'Running Springs', 'Rupert', 'Rural Hall', 'Rural Hill', 'Rural Retreat', 'Rural Valley', 'Rush Center', 'Rush City', 'Rush Hill', 'Rush Springs', 'Rush Valley', 'Rushford', 'Rushford Village', 'Rushmere', 'Rushmore', 'Rushsylvania', 'Rushville', 'Rusk', 'Ruskin', 'Ruso', 'Russell', 'Russell Gardens', 'Russell Springs', 'Russells Point', 'Russellton', 'Russellville', 'Russia', 'Russian Mission', 'Russiaville', 'Rustburg', 'Ruston', 'Ruth', 'Rutherford', 'Rutherford College', 'Rutherfordton', 'Ruthton', 'Ruthven', 'Rutland', 'Rutledge', 'Ryan', 'Ryder', 'Rye', 'Rye Brook', 'Ryegate', 'Ryland Heights', 'Río Blanco', 'Río Cañas Abajo', 'Río Grande', 'Río Lajas', 'S.N.P.J.', 'Sabana', 'Sabana Eneas', 'Sabana Grande', 'Sabana Hoyos', 'Sabana Seca', 'Sabetha', 'Sabin', 'Sabina', 'Sabinal', 'Sabula', 'Sac City', 'Sacaton', 'Sachse', 'Sackets Harbor', 'Saco', 'Sacramento', 'Sacred Heart', 'Saddle Brook', 'Saddle Butte', 'Saddle River', 'Saddle Rock', 'Saddle Rock Estates', 'Sadieville', 'Sadler', 'Sadorus', 'Saegertown', 'Safety Harbor', 'Safford', 'Sag Harbor', 'Sagamore', 'Sagaponack', 'Sageville', 'Saginaw', 'Saginaw Township North', 'Saginaw Township South', 'Saguache', 'Sahuarita', 'Sailor Springs', 'Saks', 'Salado', 'Salamanca', 'Salamatof', 'Salamonia', 'Salcha', 'Sale City', 'Salem', 'Salemburg', 'Salesville', 'Salida', 'Salina', 'Salinas', 'Saline', 'Salineno', 'Salineville', 'Salisbury', 'Salix', 'Salix-Beauty Line Park', 'Salladasburg', 'Salley', 'Sallis', 'Sallisaw', 'Salmon', 'Salmon Brook', 'Salmon Creek', 'Salome', 'Salt Creek', 'Salt Lake City', 'Salt Lick', 'Saltaire', 'Saltillo', 'Salton City', 'Salton Sea Beach', 'Saltsburg', 'Saltville', 'Saluda', 'Salunga-Landisville', 'Salyersville', 'Samak', 'Samburg', 'Sammamish', 'Samnorwood', 'Samoset', 'Sams Corner', 'Samson', 'Samsula-Spruce Creek', 'San Andreas', 'San Angelo', 'San Anselmo', 'San Antonio', 'San Antonio Heights', 'San Ardo', 'San Augustine', 'San Benito', 'San Bernardino', 'San Bruno', 'San Buenaventura (Ventura)', 'San Carlos', 'San Carlos Park', 'San Clemente', 'San Diego', 'San Diego Country Estates', 'San Dimas', 'San Elizario', 'San Felipe', 'San Felipe Pueblo', 'San Fernando', 'San Francisco', 'San Gabriel', 'San Germán', 'San Geronimo', 'San Ignacio', 'San Ildefonso Pueblo', 'San Isidro', 'San Jacinto', 'San Joaquin', 'San Joaquin Hills', 'San Jon', 'San Jose', 'San José', 'San Juan', 'San Juan Bautista', 'San Juan Capistrano', 'San Leandro', 'San Leanna', 'San Leon', 'San Lorenzo', 'San Lucas', 'San Luis', 'San Luis Obispo', 'San Manuel', 'San Manuel-Linn', 'San Mar', 'San Marcos', 'San Marino', 'San Martin', 'San Mateo', 'San Miguel', 'San Pablo', 'San Patricio', 'San Pedro', 'San Perlita', 'San Pierre', 'San Rafael', 'San Ramon', 'San Saba', 'San Sebastián', 'San Ysidro', 'Sanatoga', 'Sanborn', 'Sanctuary', 'Sand City', 'Sand Fork', 'Sand Hill', 'Sand Hills', 'Sand Lake', 'Sand Point', 'Sand Ridge', 'Sand Rock', 'Sand Springs', 'Sandalfoot Cove', 'Sandborn', 'Sanders', 'Sanderson', 'Sandersville', 'Sandia', 'Sandoval', 'Sandpoint', 'Sands Point', 'Sandstone', 'Sandusky', 'Sandusky South', 'Sandwich', 'Sandy', 'Sandy Creek', 'Sandy Hollow-Escondidas', 'Sandy Hook', 'Sandy Lake', 'Sandy Level', 'Sandy Ridge', 'Sandy Springs', 'Sandy Valley', 'Sandyfield', 'Sandyville', 'Sanford', 'Sanger', 'Sangrey', 'Sanibel', 'Sankertown', 'Sanostee', 'Sans Souci', 'Sansom Park', 'Santa Ana', 'Santa Ana Pueblo', 'Santa Anna', 'Santa Barbara', 'Santa Bárbara', 'Santa Clara', 'Santa Clara Pueblo', 'Santa Clarita', 'Santa Claus', 'Santa Cruz', 'Santa Fe', 'Santa Fe Springs', 'Santa Isabel', 'Santa Maria', 'Santa Monica', 'Santa Paula', 'Santa Rosa', 'Santa Teresa', 'Santa Venetia', 'Santa Ynez', 'Santan', 'Santaquin', 'Santee', 'Santo Domingo', 'Santo Domingo Pueblo', 'Sappington', 'Sapulpa', 'Sarahsville', 'Saraland', 'Saranac', 'Saranac Lake', 'Sarasota', 'Sarasota Springs', 'Saratoga', 'Saratoga Springs', 'Sarcoxie', 'Sardinia', 'Sardis', 'Sardis City', 'Sarepta', 'Sargeant', 'Sargent', 'Sarles', 'Saronville', 'Sartell', 'Sasakwa', 'Sasser', 'Satanta', 'Satartia', 'Satellite Beach', 'Satsop', 'Satsuma', 'Satus', 'Saucier', 'Saugatuck', 'Saugerties', 'Saugerties South', 'Sauget', 'Saugus', 'Sauk Centre', 'Sauk City', 'Sauk Rapids', 'Sauk Village', 'Saukville', 'Saulsbury', 'Sault Ste. Marie', 'Saunemin', 'Sausalito', 'Savage', 'Savage-Guilford', 'Savanna', 'Savannah', 'Savona', 'Savonburg', 'Savoonga', 'Savoy', 'Sawgrass', 'Sawmill', 'Sawmills', 'Sawpit', 'Sawyer', 'Sawyerville', 'Saxapahaw', 'Saxis', 'Saxman', 'Saxon', 'Saxonburg', 'Saxton', 'Saxtons River', 'Saybrook', 'Saybrook Manor', 'Saylorville', 'Sayre', 'Sayreville', 'Sayville', 'Scales Mound', 'Scalp Level', 'Scammon', 'Scammon Bay', 'Scandia', 'Scandinavia', 'Scanlon', 'Scappoose', 'Scarborough', 'Scarsdale', 'Scarville', 'Scenic Oaks', 'Schaefferstown', 'Schaghticoke', 'Schall Circle', 'Schaller', 'Schaumburg', 'Schell City', 'Schellsburg', 'Schenectady', 'Schererville', 'Schertz', 'Schiller Park', 'Schlater', 'Schleswig', 'Schlusser', 'Schnecksville', 'Schneider', 'Schoenchen', 'Schofield', 'Schofield Barracks', 'Schoharie', 'Schoolcraft', 'Schram City', 'Schriever', 'Schulenburg', 'Schulter', 'Schurz', 'Schuyler', 'Schuylerville', 'Schuylkill Haven', 'Schwenksville', 'Science Hill', 'Scio', 'Sciota', 'Sciotodale', 'Scipio', 'Scissors', 'Scituate', 'Scobey', 'Scofield', 'Scooba', 'Scotch Plains', 'Scotchtown', 'Scotia', 'Scotland', 'Scotland Neck', 'Scotsdale', 'Scott', 'Scott AFB', 'Scott City', 'Scott Lake', 'Scott Township', 'Scottdale', 'Scotts Corners', 'Scotts Hill', 'Scotts Mills', 'Scotts Valley', 'Scottsbluff', 'Scottsboro', 'Scottsburg', 'Scottsdale', 'Scottsville', 'Scottville', 'Scranton', 'Scraper', 'Screven', 'Scribner', 'Sea Breeze', 'Sea Bright', 'Sea Cliff', 'Sea Girt', 'Sea Isle City', 'Sea Ranch Lakes', 'SeaTac', 'Seaboard', 'Seabrook', 'Seabrook Farms', 'Seabrook Island', 'Seadrift', 'Seaford', 'Seaforth', 'Seagate', 'Seagoville', 'Seagraves', 'Seagrove', 'Seal Beach', 'Sealy', 'Seama', 'Seaman', 'Searchlight', 'Searcy', 'Searingtown', 'Searles Valley', 'Searsboro', 'Searsport', 'Seaside', 'Seaside Heights', 'Seaside Park', 'Seat Pleasant', 'Seaton', 'Seatonville', 'Seattle', 'Seattle Hill-Silver Firs', 'Sebastian', 'Sebastopol', 'Sebeka', 'Sebewaing', 'Sebree', 'Sebring', 'Secaucus', 'Second Mesa', 'Seconsett Island', 'Secor', 'Secretary', 'Section', 'Security-Widefield', 'Sedalia', 'Sedan', 'Sedco Hills', 'Sedgewickville', 'Sedgwick', 'Sedona', 'Sedro-Woolley', 'Seeley', 'Seeley Lake', 'Seelyville', 'Seffner', 'Seguin', 'Seibert', 'Seiling', 'Selah', 'Selawik', 'Selby', 'Selby-on-the-Bay', 'Selbyville', 'Selden', 'Seldovia', 'Seldovia Village', 'Selfridge', 'Seligman', 'Selinsgrove', 'Sellers', 'Sellersburg', 'Sellersville', 'Sells', 'Selma', 'Selmer', 'Selmont-West Selmont', 'Seltzer', 'Seminary', 'Seminole', 'Seminole Manor', 'Senath', 'Senatobia', 'Seneca', 'Seneca Falls', 'Seneca Gardens', 'Seneca Knolls', 'Senecaville', 'Senoia', 'Sentinel', 'Sentinel Butte', 'Sequim', 'Sequoyah', 'Serenada', 'Sergeant Bluff', 'Sesser', 'Setauket-East Setauket', 'Seth Ward', 'Seven Corners', 'Seven Devils', 'Seven Fields', 'Seven Hills', 'Seven Lakes', 'Seven Mile', 'Seven Oaks', 'Seven Points', 'Seven Springs', 'Seven Trees', 'Seven Valleys', 'Severance', 'Severn', 'Severna Park', 'Severy', 'Sevierville', 'Seville', 'Sewall\'s Point', 'Sewanee', 'Seward', 'Sewaren', 'Sewickley', 'Sewickley Heights', 'Sewickley Hills', 'Seymour', 'Shabbona', 'Shackelford', 'Shade Gap', 'Shadeland', 'Shady Cove', 'Shady Dale', 'Shady Grove', 'Shady Hills', 'Shady Hollow', 'Shady Point', 'Shady Shores', 'Shady Side', 'Shady Spring', 'Shadyside', 'Shafer', 'Shafter', 'Shageluk', 'Shaker Church', 'Shaker Heights', 'Shakopee', 'Shaktoolik', 'Shaler Township', 'Shalimar', 'Shallotte', 'Shallowater', 'Shambaugh', 'Shamokin', 'Shamokin Dam', 'Shamrock', 'Shamrock Lakes', 'Shandon', 'Shaniko', 'Shanksville', 'Shannon', 'Shannon City', 'Shannon Hills', 'Shanor-Northvue', 'Shark River Hills', 'Sharon', 'Sharon Hill', 'Sharon Springs', 'Sharonville', 'Sharpes', 'Sharpsburg', 'Sharpsville', 'Sharptown', 'Shasta Lake', 'Shattuck', 'Shavano Park', 'Shaver Lake', 'Shaw', 'Shawano', 'Shawnee', 'Shawnee Hills', 'Shawneetown', 'Shawsville', 'Sheakleyville', 'Sheboygan', 'Sheboygan Falls', 'Sheep Springs', 'Sheffield', 'Sheffield Lake', 'Shelbina', 'Shelburn', 'Shelburne Falls', 'Shelby', 'Shelbyville', 'Sheldahl', 'Sheldon', 'Sheldon Point (Nunam Iqua)', 'Shell Knob', 'Shell Lake', 'Shell Point', 'Shell Rock', 'Shell Valley', 'Shelley', 'Shellman', 'Shellsburg', 'Shelly', 'Shelocta', 'Shelter Island', 'Shelter Island Heights', 'Shelton', 'Shenandoah', 'Shenandoah Heights', 'Shenorock', 'Shepherd', 'Shepherdstown', 'Shepherdsville', 'Sheppton', 'Sherando', 'Sherburn', 'Sherburne', 'Sheridan', 'Sheridan Lake', 'Sherman', 'Sherrard', 'Sherrelwood', 'Sherrill', 'Sherrills Ford', 'Sherrodsville', 'Sherwood', 'Sherwood Manor', 'Shevlin', 'Sheyenne', 'Shickley', 'Shickshinny', 'Shidler', 'Shields', 'Shillington', 'Shiloh', 'Shiner', 'Shingle Springs', 'Shinglehouse', 'Shingletown', 'Shinnecock Hills', 'Shinnston', 'Shiocton', 'Ship Bottom', 'Shipman', 'Shippensburg', 'Shippenville', 'Shippingport', 'Shiprock', 'Shipshewana', 'Shiremanstown', 'Shirley', 'Shirleysburg', 'Shishmaref', 'Shively', 'Shoal Creek Drive', 'Shoal Creek Estates', 'Shoals', 'Shoemakersville', 'Shokan', 'Sholes', 'Shongaloo', 'Shongopovi', 'Shonto', 'Shoreacres', 'Shoreham', 'Shoreline', 'Shoreline Park', 'Shoreview', 'Shorewood', 'Shorewood Hills', 'Shorewood-Tower Hills-Harbert', 'Short', 'Short Pump', 'Shorter', 'Shortsville', 'Shoshone', 'Shoshoni', 'Show Low', 'Shreve', 'Shreveport', 'Shrewsbury', 'Shrub Oak', 'Shubert', 'Shubuta', 'Shueyville', 'Shullsburg', 'Shumway', 'Shungnak', 'Shuqualak', 'Sibley', 'Sicily Island', 'Sidell', 'Sidney', 'Sidon', 'Sienna Plantation', 'Sierra Blanca', 'Sierra Madre', 'Sierra Vista', 'Sierra Vista Southeast', 'Siesta Key', 'Siesta Shores', 'Sigel', 'Signal Hill', 'Signal Mountain', 'Sigourney', 'Sigurd', 'Sikes', 'Sikeston', 'Silas', 'Siler City', 'Silerton', 'Siletz', 'Silex', 'Silo', 'Siloam', 'Siloam Springs', 'Silsbee', 'Silt', 'Silvana', 'Silver Bay', 'Silver City', 'Silver Cliff', 'Silver Creek', 'Silver Grove', 'Silver Lake', 'Silver Plume', 'Silver Ridge', 'Silver Spring', 'Silver Springs', 'Silver Springs Shores', 'Silverdale', 'Silverhill', 'Silverstreet', 'Silverthorne', 'Silverton', 'Silvis', 'Simi Valley', 'Simla', 'Simmesport', 'Simms', 'Simonton', 'Simonton Lake', 'Simpson', 'Simpsonville', 'Sims', 'Simsboro', 'Simsbury Center', 'Sinai', 'Sinclair', 'Sinclairville', 'Sinking Spring', 'Sinton', 'Sioux Center', 'Sioux City', 'Sioux Falls', 'Sioux Rapids', 'Sipsey', 'Siren', 'Sisseton', 'Sissonville', 'Sister Bay', 'Sisters', 'Sistersville', 'Sitka city and', 'Six Mile', 'Skagway', 'Skaneateles', 'Skedee', 'Skellytown', 'Skiatook', 'Skidaway Island', 'Skidmore', 'Skidway Lake', 'Skippack', 'Skippers Corner', 'Skokie', 'Skokomish', 'Skowhegan', 'Skwentna', 'Sky Lake', 'Sky Valley', 'Skykomish', 'Skyline', 'Skyline View', 'Skyline-Ganipa', 'Slabtown', 'Slana', 'Slate Springs', 'Slater', 'Slater-Marietta', 'Slatington', 'Slaton', 'Slaughter', 'Slaughter Beach', 'Slaughters', 'Slaughterville', 'Slayden', 'Slayton', 'Sledge', 'Sleepy Eye', 'Sleepy Hollow', 'Sleetmute', 'Slick', 'Slickville', 'Slidell', 'Sligo', 'Slinger', 'Slippery Rock', 'Sloan', 'Sloatsburg', 'Slocomb', 'Smackover', 'Smallwood', 'Smelterville', 'Smethport', 'Smicksburg', 'Smiley', 'Smith Center', 'Smith Island', 'Smith Mills', 'Smith Valley', 'Smith Village', 'Smithboro', 'Smithers', 'Smithfield', 'Smithland', 'Smiths', 'Smiths Grove', 'Smithsburg', 'Smithton', 'Smithtown', 'Smithville', 'Smoaks', 'Smoke Rise', 'Smokey Point', 'Smolan', 'Smoot', 'Smyer', 'Smyrna', 'Snake Creek', 'Snead', 'Sneads', 'Sneads Ferry', 'Sneedville', 'Snelling', 'Snellville', 'Snohomish', 'Snook', 'Snoqualmie', 'Snoqualmie Pass', 'Snow Hill', 'Snow Lake Shores', 'Snow Shoe', 'Snowflake', 'Snowmass Village', 'Snowville', 'Snyder', 'Snydertown', 'Soap Lake', 'Sobieski', 'Socastee', 'Social Circle', 'Society Hill', 'Socorro', 'Soda Springs', 'Sodaville', 'Soddy-Daisy', 'Sodus', 'Sodus Point', 'Solana', 'Solana Beach', 'Soldier', 'Soldiers Grove', 'Soldotna', 'Soledad', 'Solen', 'Solis', 'Solomon', 'Solomons', 'Solon', 'Solon Springs', 'Solvang', 'Solvay', 'Solway', 'Sombrillo', 'Somerdale', 'Somers', 'Somers Point', 'Somerset', 'Somersworth', 'Somerton', 'Somerville', 'Somonauk', 'Sonoita', 'Sonoma', 'Sonora', 'Sopchoppy', 'Soper', 'Soperton', 'Sophia', 'Soquel', 'Sorento', 'Sorrento', 'Soso', 'Souderton', 'Soulsbyville', 'Sound Beach', 'Sour John', 'Sour Lake', 'Souris', 'South Alamo', 'South Amboy', 'South Amherst', 'South Apopka', 'South Ashburnham', 'South Barre', 'South Barrington', 'South Bay', 'South Beach', 'South Belmar', 'South Beloit', 'South Bend', 'South Bethany', 'South Bethlehem', 'South Bloomfield', 'South Boston', 'South Bound Brook', 'South Bradenton', 'South Brooksville', 'South Browning', 'South Burlington', 'South Canal', 'South Carrollton', 'South Carthage', 'South Charleston', 'South Chicago Heights', 'South Cle Elum', 'South Cleveland', 'South Coatesville', 'South Coffeyville', 'South Congaree', 'South Connellsville', 'South Corning', 'South Coventry', 'South Dayton', 'South Daytona', 'South Deerfield', 'South Dennis', 'South Dos Palos', 'South Duxbury', 'South El Monte', 'South Elgin', 'South Eliot', 'South English', 'South Euclid', 'South Fallsburg', 'South Farmingdale', 'South Flat', 'South Floral Park', 'South Fork', 'South Fork Estates', 'South Fulton', 'South Gastonia', 'South Gate', 'South Gate Ridge', 'South Gifford', 'South Glens Falls', 'South Gorin', 'South Greeley', 'South Greenfield', 'South Greensburg', 'South Gull Lake', 'South Haven', 'South Heart', 'South Heights', 'South Hempstead', 'South Henderson', 'South Highpoint', 'South Hill', 'South Holland', 'South Hooksett', 'South Houston', 'South Huntington', 'South Hutchinson', 'South Jacksonville', 'South Jordan', 'South Kensington', 'South Lake Tahoe', 'South Lancaster', 'South Laurel', 'South Lead Hill', 'South Lebanon', 'South Lineville', 'South Lockport', 'South Lyon', 'South Mansfield', 'South Miami', 'South Miami Heights', 'South Middletown', 'South Milwaukee', 'South Monroe', 'South Mountain', 'South Naknek', 'South New Castle', 'South Nyack', 'South Ogden', 'South Orange', 'South Oroville', 'South Padre Island', 'South Palm Beach', 'South Paris', 'South Park', 'South Park Township', 'South Park View', 'South Pasadena', 'South Patrick Shores', 'South Pekin', 'South Philipsburg', 'South Pittsburg', 'South Plainfield', 'South Point', 'South Portland', 'South Pottstown', 'South Prairie', 'South Range', 'South Renovo', 'South River', 'South Rockwood', 'South Rosemary', 'South Roxana', 'South Russell', 'South Salem', 'South Salt Lake', 'South San Francisco', 'South San Gabriel', 'South San Jose Hills', 'South Sanford', 'South Sarasota', 'South Shaftsbury', 'South Shore', 'South Sioux City', 'South Snyderville Basin', 'South Solon', 'South St. Paul', 'South Sumter', 'South Taft', 'South Toledo Bend', 'South Toms River', 'South Tucson', 'South Vacherie', 'South Valley', 'South Valley Stream', 'South Venice', 'South Vienna', 'South Vinemont', 'South Wallins', 'South Waverly', 'South Wayne', 'South Weber', 'South Webster', 'South Weldon', 'South Wenatchee', 'South West City', 'South Whitley', 'South Whittier', 'South Willard', 'South Williamsport', 'South Wilmington', 'South Windham', 'South Woodbridge', 'South Woodstock', 'South Yarmouth', 'South Yuba City', 'South Zanesville', 'Southampton', 'Southaven', 'Southbridge', 'Southchase', 'Southeast Arcadia', 'Southern Pines', 'Southern Shops', 'Southern Shores', 'Southern View', 'Southfield', 'Southgate', 'Southglenn', 'Southlake', 'Southmayd', 'Southmont', 'Southold', 'Southport', 'Southside', 'Southside Place', 'Southwest Greensburg', 'Southwood Acres', 'Spackenkill', 'Spade', 'Spalding', 'Spanaway', 'Spangle', 'Spanish Fork', 'Spanish Fort', 'Spanish Lake', 'Spanish Springs', 'Spanish Valley', 'Sparkman', 'Sparks', 'Sparland', 'Sparta', 'Spartanburg', 'Spartansburg', 'Spaulding', 'Spavinaw', 'Spearfish', 'Spearman', 'Spearsville', 'Spearville', 'Speculator', 'Speed', 'Speedway', 'Speers', 'Spencer', 'Spencer Mountain', 'Spencerport', 'Spencerville', 'Sperry', 'Spiceland', 'Spicer', 'Spickard', 'Spillertown', 'Spillville', 'Spindale', 'Spirit Lake', 'Spiritwood Lake', 'Spiro', 'Spivey', 'Spiveys Corner', 'Splendora', 'Spofford', 'Spokane', 'Spooner', 'Sportsmen Acres', 'Sportsmen Acres Community', 'Spotswood', 'Spotsylvania Courthouse', 'Sprague', 'Spragueville', 'Spray', 'Spreckels', 'Spring', 'Spring Arbor', 'Spring Bay', 'Spring City', 'Spring Creek', 'Spring Garden', 'Spring Garden-Terra Verde', 'Spring Green', 'Spring Grove', 'Spring Hill', 'Spring Hope', 'Spring House', 'Spring Lake', 'Spring Lake Heights', 'Spring Lake Park', 'Spring Mill', 'Spring Mills', 'Spring Mount', 'Spring Park', 'Spring Ridge', 'Spring Valley', 'Springboro', 'Springbrook', 'Springdale', 'Springer', 'Springerton', 'Springerville', 'Springetts Manor-Yorklyn', 'Springfield', 'Springhill', 'Springlake', 'Springlee', 'Springport', 'Springs', 'Springtown', 'Springvale', 'Springview', 'Springville', 'Spruce Pine', 'Spry', 'Spur', 'Spurgeon', 'Squaw Lake', 'Squaw Valley', 'Squirrel Mountain Valley', 'St. Albans', 'St. Andrews', 'St. Ann', 'St. Anne', 'St. Ansgar', 'St. Anthony', 'St. Augustine', 'St. Augustine Beach', 'St. Augustine Shores', 'St. Augustine South', 'St. Bernard', 'St. Bonaventure', 'St. Bonifacius', 'St. Charles', 'St. Clair', 'St. Clair Shores', 'St. Clairsville', 'St. Cloud', 'St. Croix Falls', 'St. David', 'St. Dennis', 'St. Donatus', 'St. Edward', 'St. Elizabeth', 'St. Elmo', 'St. Florian', 'St. Francis', 'St. Francisville', 'St. Gabriel', 'St. George', 'St. Hedwig', 'St. Helen', 'St. Helena', 'St. Helens', 'St. Henry', 'St. Hilaire', 'St. Ignace', 'St. Ignatius', 'St. Jacob', 'St. James', 'St. James City', 'St. Jo', 'St. Joe', 'St. John', 'St. Johns', 'St. Johnsbury', 'St. Johnsville', 'St. Joseph', 'St. Lawrence', 'St. Leo', 'St. Leon', 'St. Leonard', 'St. Libory', 'St. Louis', 'St. Louis Park', 'St. Louisville', 'St. Lucas', 'St. Lucie', 'St. Marie', 'St. Maries', 'St. Marks', 'St. Martin', 'St. Martins', 'St. Martinville', 'St. Mary', 'St. Mary\'s', 'St. Marys', 'St. Marys Point', 'St. Matthews', 'St. Michael', 'St. Michael-Sidman', 'St. Michaels', 'St. Nazianz', 'St. Olaf', 'St. Paris', 'St. Paul', 'St. Paul Park', 'St. Pauls', 'St. Pete Beach', 'St. Peter', 'St. Peters', 'St. Petersburg', 'St. Pierre', 'St. Regis', 'St. Regis Park', 'St. Robert', 'St. Rosa', 'St. Rose', 'St. Simons', 'St. Stephen', 'St. Stephens', 'St. Thomas', 'St. Vincent', 'St. Xavier', 'Staatsburg', 'Stacey Street', 'Stacy', 'Stacyville', 'Stafford', 'Stagecoach', 'Staley', 'Stallings', 'Stallion Springs', 'Stambaugh', 'Stamford', 'Stamping Ground', 'Stamps', 'Stanaford', 'Stanardsville', 'Stanberry', 'Standard', 'Standard City', 'Standing Pine', 'Standish', 'Stanfield', 'Stanford', 'Stanhope', 'Stanley', 'Stanleytown', 'Stannards', 'Stansbury Park', 'Stanton', 'Stantonsburg', 'Stantonville', 'Stanwood', 'Staplehurst', 'Staples', 'Stapleton', 'Star', 'Star City', 'Star Harbor', 'Star Lake', 'Star Prairie', 'Star Valley Ranch', 'Starbuck', 'Stark', 'Stark City', 'Starke', 'Starkville', 'Starkweather', 'Starr', 'Starr School', 'Starrucca', 'Startex', 'Startup', 'State Center', 'State College', 'State Line', 'State Line City', 'Stateburg', 'Stateline', 'Statesboro', 'Statesville', 'Statham', 'Staunton', 'Stayton', 'Ste. Genevieve', 'Ste. Marie', 'Steamboat', 'Steamboat Rock', 'Steamboat Springs', 'Stearns', 'Stebbins', 'Stedman', 'Steele', 'Steele City', 'Steeleville', 'Steelton', 'Steelville', 'Steen', 'Steger', 'Steilacoom', 'Steinauer', 'Stella', 'Stem', 'Stephen', 'Stephens', 'Stephens City', 'Stephenson', 'Stephenville', 'Sterling', 'Sterling City', 'Sterling Heights', 'Sterlington', 'Stetsonville', 'Steuben', 'Steubenville', 'Stevens Point', 'Stevens Village', 'Stevenson', 'Stevensville', 'Steward', 'Stewardson', 'Stewart', 'Stewart Manor', 'Stewartstown', 'Stewartsville', 'Stewartville', 'Stickney', 'Stidham', 'Stigler', 'Stilesville', 'Stillman Valley', 'Stillmore', 'Stillwater', 'Stilwell', 'Stimson Crossing', 'Stinesville', 'Stinnett', 'Stinson Beach', 'Stites', 'Stock Island', 'Stockbridge', 'Stockdale', 'Stockertown', 'Stockham', 'Stockholm', 'Stockport', 'Stockton', 'Stockville', 'Stoddard', 'Stokesdale', 'Stone Creek', 'Stone Harbor', 'Stone Mountain', 'Stone Park', 'Stone Ridge', 'Stoneboro', 'Stonefort', 'Stonegate', 'Stoneham', 'Stoneville', 'Stonewall', 'Stonewood', 'Stonington', 'Stony Brook', 'Stony Creek', 'Stony Point', 'Stony Prairie', 'Stony River', 'Stonybrook-Wilshire', 'Storden', 'Storla', 'Storm Lake', 'Stormstown', 'Storrie', 'Storrs', 'Story', 'Story City', 'Stotesbury', 'Stotts City', 'Stottville', 'Stoughton', 'Stout', 'Stoutland', 'Stoutsville', 'Stovall', 'Stover', 'Stow', 'Stowe', 'Stowe Township', 'Stowell', 'Stoy', 'Stoystown', 'Strafford', 'Strandburg', 'Strandquist', 'Strang', 'Strasburg', 'Stratford', 'Strathcona', 'Strathmere', 'Strathmoor Manor', 'Strathmoor Village', 'Strathmore', 'Stratmoor', 'Strattanville', 'Stratton', 'Straughn', 'Strausstown', 'Strawberry', 'Strawberry Point', 'Strawn', 'Streamwood', 'Streator', 'Streeter', 'Streetman', 'Streetsboro', 'Stringtown', 'Stromsburg', 'Strong', 'Strong City', 'Stronghurst', 'Strongsville', 'Stroud', 'Stroudsburg', 'Struble', 'Strum', 'Struthers', 'Stryker', 'Stuart', 'Stuarts Draft', 'Stuckey', 'Study Butte-Terlingua', 'Sturbridge', 'Sturgeon', 'Sturgeon Bay', 'Sturgeon Lake', 'Sturgeon-Noblestown', 'Sturgis', 'Sturtevant', 'Stuttgart', 'Subiaco', 'Sublette', 'Sublimity', 'Succasunna-Kenvil', 'Success', 'Sudan', 'Sudden Valley', 'Sudlersville', 'Sudley', 'Suffern', 'Suffield Depot', 'Suffolk', 'Sugar Bush Knolls', 'Sugar City', 'Sugar Creek', 'Sugar Grove', 'Sugar Hill', 'Sugar Land', 'Sugar Mountain', 'Sugar Notch', 'Sugarcreek', 'Sugarmill Woods', 'Sugden', 'Suisun City', 'Suitland-Silver Hill', 'Sulligent', 'Sullivan', 'Sullivan City', 'Sullivan\'s Island', 'Sully', 'Sulphur', 'Sulphur Rock', 'Sulphur Springs', 'Sultan', 'Sumas', 'Sumiton', 'Summerdale', 'Summerfield', 'Summerhill', 'Summerland', 'Summerlin South', 'Summerside', 'Summersville', 'Summerton', 'Summertown', 'Summerville', 'Summit', 'Summit Hill', 'Summit Park', 'Summit Station', 'Summitview', 'Summitville', 'Sumner', 'Sumpter', 'Sumrall', 'Sumter', 'Sun', 'Sun City', 'Sun City West', 'Sun Lakes', 'Sun Prairie', 'Sun River', 'Sun River Terrace', 'Sun Valley', 'Sunbright', 'Sunburg', 'Sunburst', 'Sunbury', 'Suncoast Estates', 'Suncook', 'Sundance', 'Sundown', 'Sunfield', 'Sunfish Lake', 'Sunflower', 'Sunland Park', 'Sunman', 'Sunny Isles Beach', 'Sunny Side', 'Sunnyside', 'Sunnyside-Tahoe City', 'Sunnyslope', 'Sunnyvale', 'Sunol', 'Sunol-Midtown', 'Sunray', 'Sunrise', 'Sunrise Beach', 'Sunrise Beach Village', 'Sunrise Manor', 'Sunset', 'Sunset Beach', 'Sunset Hills', 'Sunset Valley', 'Sunset Village', 'Sunshine Acres', 'Sunshine Ranches', 'Supai', 'Superior', 'Supreme', 'Suquamish', 'Surf City', 'Surfside', 'Surfside Beach', 'Surgoinsville', 'Suring', 'Surprise', 'Surrency', 'Surrey', 'Surry', 'Susan Moore', 'Susank', 'Susanville', 'Susitna', 'Susquehanna Depot', 'Susquehanna Trails', 'Sussex', 'Sutcliffe', 'Sutersville', 'Sutherland', 'Sutherlin', 'Sutter', 'Sutter Creek', 'Sutton', 'Sutton-Alpine', 'Suttons Bay', 'Suwanee', 'Suárez', 'Swainsboro', 'Swaledale', 'Swampscott', 'Swan', 'Swan Valley', 'Swannanoa', 'Swansboro', 'Swansea', 'Swanton', 'Swanville', 'Swarthmore', 'Swartz', 'Swartz Creek', 'Swayzee', 'Swea City', 'Swedesboro', 'Sweeney Ranch', 'Sweeny', 'Sweet Home', 'Sweet Springs', 'Sweet Water', 'Sweetser', 'Sweetwater', 'Swepsonville', 'Swift Trail Junction', 'Swifton', 'Swink', 'Swisher', 'Swissvale', 'Switz City', 'Switzer', 'Swoyersville', 'Sycamore', 'Sycamore Hills', 'Sykeston', 'Sykesville', 'Sylacauga', 'Sylva', 'Sylvan Beach', 'Sylvan Grove', 'Sylvan Lake', 'Sylvan Shores', 'Sylvan Springs', 'Sylvania', 'Sylvarena', 'Sylvester', 'Sylvia', 'Symerton', 'Syosset', 'Syracuse', 'Tabernash', 'Tabiona', 'Table Grove', 'Table Rock', 'Tabor', 'Tabor City', 'Tacna', 'Tacoma', 'Taconite', 'Taft', 'Taft Heights', 'Taft Mosswood', 'Taft Southwest', 'Tagg Flats', 'Tahlequah', 'Tahoe Vista', 'Tahoka', 'Taholah', 'Tainter Lake', 'Taiwah', 'Tajique', 'Takoma Park', 'Takotna', 'Talala', 'Talbotton', 'Talco', 'Talent', 'Talihina', 'Talkeetna', 'Talking Rock', 'Tallaboa', 'Tallaboa Alta', 'Talladega', 'Talladega Springs', 'Tallahassee', 'Tallapoosa', 'Tallassee', 'Tallmadge', 'Tallula', 'Tallulah', 'Tallulah Falls', 'Talmage', 'Talmo', 'Taloga', 'Talty', 'Tama', 'Tamaha', 'Tamalpais-Homestead Valley', 'Tamaqua', 'Tamarac', 'Tamarack', 'Tamaroa', 'Tamiami', 'Tamms', 'Tampa', 'Tampico', 'Tanacross', 'Tanaina', 'Tanana', 'Taneytown', 'Taneyville', 'Tangelo Park', 'Tangent', 'Tangerine', 'Tangier', 'Tangipahoa', 'Tanglewilde-Thompson Place', 'Tanner', 'Tannersville', 'Tanque Verde', 'Taopi', 'Taos', 'Taos Pueblo', 'Taos Ski Valley', 'Tappahannock', 'Tappan', 'Tappen', 'Tar Heel', 'Tara Hills', 'Tarboro', 'Tarentum', 'Tariffville', 'Tarkio', 'Tarlton', 'Tarnov', 'Tarpon Springs', 'Tarrant', 'Tarrants', 'Tarrytown', 'Tatamy', 'Tatitlek', 'Tatum', 'Tatums', 'Taunton', 'Tavares', 'Tavernier', 'Tavistock', 'Tawas City', 'Taylor', 'Taylor Creek', 'Taylor Lake Village', 'Taylor Mill', 'Taylor Springs', 'Taylors', 'Taylors Falls', 'Taylorsville', 'Taylortown', 'Taylorville', 'Tazewell', 'Tazlina', 'Tchula', 'Tea', 'Teachey', 'Teague', 'Teaneck', 'Teaticket', 'Teays Valley', 'Tecopa', 'Tecumseh', 'Tedder', 'Teec Nos Pos', 'Tega Cay', 'Tehachapi', 'Tehama', 'Tehuacana', 'Tekamah', 'Tekoa', 'Tekonsha', 'Telford', 'Tell City', 'Teller', 'Tellico Plains', 'Telluride', 'Temecula', 'Temelec', 'Tempe', 'Temperance', 'Temple', 'Temple City', 'Temple Hills', 'Temple Terrace', 'Templeton', 'Templeville', 'Ten Broeck', 'Ten Sleep', 'Tenafly', 'Tenaha', 'Tenakee Springs', 'Tenino', 'Tenkiller', 'Tennant', 'Tennessee', 'Tennessee Ridge', 'Tenney', 'Tennille', 'Tennyson', 'Tensed', 'Tenstrike', 'Tequesta', 'Terlton', 'Terra Alta', 'Terra Bella', 'Terra Mar', 'Terrace Heights', 'Terrace Park', 'Terral', 'Terramuggus', 'Terre Haute', 'Terre Hill', 'Terrebonne', 'Terrell', 'Terrell Hills', 'Terril', 'Terry', 'Terrytown', 'Terryville', 'Tescott', 'Tesuque', 'Teterboro', 'Tetlin', 'Teton', 'Teton Village', 'Tetonia', 'Teutopolis', 'Texanna', 'Texarkana', 'Texas City', 'Texhoma', 'Texico', 'Texline', 'Texola', 'Thackerville', 'Thatcher', 'Thawville', 'Thaxton', 'Thayer', 'Thayne', 'The Buttes', 'The Colony', 'The Crossings', 'The Hammocks', 'The Hills', 'The Lakes', 'The Meadows', 'The Pinery', 'The Plains', 'The Village', 'The Village of Indian Hill', 'The Villages', 'The Woodlands', 'Thebes', 'Thedford', 'Theodore', 'Theodosia', 'Theresa', 'Thermalito', 'Thermopolis', 'Thibodaux', 'Thief River Falls', 'Thiells', 'Thiensville', 'Third Lake', 'Thomas', 'Thomasboro', 'Thomaston', 'Thomasville', 'Thompson', 'Thompson Falls', 'Thompson\'s Station', 'Thompsons', 'Thompsontown', 'Thompsonville', 'Thoms Place', 'Thomson', 'Thonotosassa', 'Thor', 'Thoreau', 'Thornburg', 'Thorndale', 'Thorne Bay', 'Thornhill', 'Thornton', 'Thorntonville', 'Thorntown', 'Thornville', 'Thornwood', 'Thorp', 'Thorsby', 'Thousand Oaks', 'Thousand Palms', 'Thrall', 'Three Forks', 'Three Lakes', 'Three Oaks', 'Three Points', 'Three Rivers', 'Three Springs', 'Three Way', 'Throckmorton', 'Throop', 'Thunderbolt', 'Thurman', 'Thurmond', 'Thurmont', 'Thurston', 'Tiburon', 'Tiburones', 'Tice', 'Tickfaw', 'Tidioute', 'Tierra Bonita', 'Tierra Buena', 'Tierra Grande', 'Tierra Verde', 'Tierras Nuevas Poniente', 'Tieton', 'Tiffin', 'Tifton', 'Tigard', 'Tiger', 'Tigerton', 'Tightwad', 'Tignall', 'Tijeras', 'Tiki Island', 'Tilden', 'Tildenville', 'Tilghman Island', 'Tillamook', 'Tillar', 'Tillatoba', 'Tillmans Corner', 'Tillson', 'Tilton', 'Tilton-Northfield', 'Tiltonsville', 'Timber Hills', 'Timber Lake', 'Timber Lakes', 'Timber Pines', 'Timbercreek Canyon', 'Timberlake', 'Timberlane', 'Timberon', 'Timberville', 'Timberwood Park', 'Timblin', 'Time', 'Timken', 'Timmonsville', 'Timnath', 'Timpson', 'Tina', 'Tindall', 'Tingley', 'Tinicum Township', 'Tinley Park', 'Tinsman', 'Tintah', 'Tinton Falls', 'Tioga', 'Tionesta', 'Tipp City', 'Tipton', 'Tiptonville', 'Tira', 'Tiro', 'Tishomingo', 'Tiskilwa', 'Titonka', 'Titusville', 'Tiverton', 'Tivoli', 'Toa Alta', 'Toa Baja', 'Toast', 'Tobaccoville', 'Tobias', 'Tobin', 'Toccoa', 'Toccopola', 'Toco', 'Todd Creek', 'Todd Mission', 'Togiak', 'Tohatchi', 'Tok', 'Tokeland', 'Toksook Bay', 'Tolar', 'Toledo', 'Tolleson', 'Tollette', 'Tolley', 'Tolna', 'Tolono', 'Tolsona', 'Tolstoy', 'Toluca', 'Tom Bean', 'Tomah', 'Tomahawk', 'Tomales', 'Tomball', 'Tombstone', 'Tome-Adelino', 'Tompkinsville', 'Toms Brook', 'Toms River', 'Tonalea', 'Tonasket', 'Tonawanda', 'Tonganoxie', 'Tonica', 'Tonka Bay', 'Tonkawa', 'Tonopah', 'Tonsina', 'Tontitown', 'Tonto Basin', 'Tontogany', 'Tony', 'Tooele', 'Tool', 'Toomsboro', 'Toone', 'Top-of-the-World', 'Topeka', 'Toppenish', 'Topsail Beach', 'Topsfield', 'Topsham', 'Topton', 'Toquerville', 'Tornado', 'Tornillo', 'Toro Canyon', 'Toronto', 'Torrance', 'Torreon', 'Torrey', 'Torrington', 'Tortolita', 'Toston', 'Totowa', 'Touchet', 'Toughkenamon', 'Toulon', 'Tovey', 'Towanda', 'Towaoc', 'Tower', 'Tower City', 'Tower Hill', 'Tower Lakes', 'Town \'n\' Country', 'Town Creek', 'Town Line', 'Town and Country', 'Town of Pines', 'Towner', 'Townsend', 'Townville', 'Towson', 'Toxey', 'Toyah', 'Tracy', 'Tracy City', 'Tracyton', 'Tradewinds', 'Traer', 'Trafalgar', 'Trafford', 'Trail', 'Trail Creek', 'Trainer', 'Tranquillity', 'Trappe', 'Trapper Creek', 'Traskwood', 'Travelers Rest', 'Traver', 'Traverse City', 'Travilah', 'Treasure Island', 'Treasure Lake', 'Treece', 'Tremont', 'Tremont City', 'Tremonton', 'Trempealeau', 'Trent', 'Trent Woods', 'Trenton', 'Trentwood', 'Tresckow', 'Trevorton', 'Treynor', 'Trezevant', 'Tri-City', 'Tri-Lakes', 'Triadelphia', 'Triana', 'Triangle', 'Tribbey', 'Tribes Hill', 'Tribune', 'Trimble', 'Trimont', 'Trinidad', 'Trinity', 'Trion', 'Triplett', 'Tripoli', 'Tripp', 'Trommald', 'Trooper', 'Trophy Club', 'Tropic', 'Trosky', 'Trotwood', 'Troup', 'Trout Creek', 'Trout Lake', 'Trout Valley', 'Troutdale', 'Troutman', 'Troutville', 'Trowbridge Park', 'Troxelville', 'Troy', 'Troy Grove', 'Truckee', 'Truesdale', 'Trujillo Alto', 'Truman', 'Trumann', 'Trumansburg', 'Trumbauersville', 'Trumbull', 'Truro', 'Trussville', 'Truth or Consequences', 'Truxton', 'Tryon', 'Tsaile', 'Tse Bonito', 'Tselakai Dezza', 'Tualatin', 'Tuba City', 'Tubac', 'Tuckahoe', 'Tucker', 'Tuckerman', 'Tuckerton', 'Tucson', 'Tucson Estates', 'Tucumcari', 'Tukwila', 'Tulalip Bay', 'Tulare', 'Tularosa', 'Tulelake', 'Tuleta', 'Tulia', 'Tull', 'Tullahassee', 'Tullahoma', 'Tullos', 'Tully', 'Tullytown', 'Tulsa', 'Tulsita', 'Tuluksak', 'Tumacacori-Carmen', 'Tumwater', 'Tunica', 'Tunkhannock', 'Tunnel Hill', 'Tunnelhill', 'Tunnelton', 'Tuntutuliak', 'Tununak', 'Tuolumne City', 'Tupelo', 'Tupman', 'Tupper Lake', 'Turbeville', 'Turbotville', 'Turin', 'Turkey', 'Turkey Creek', 'Turley', 'Turlock', 'Turner', 'Turners Falls', 'Turnersville', 'Turnerville', 'Turney', 'Turon', 'Turpin Hills', 'Turrell', 'Turtle Creek', 'Turtle Lake', 'Turtle River', 'Turton', 'Tusayan', 'Tuscaloosa', 'Tuscarawas', 'Tuscarora', 'Tuscola', 'Tusculum', 'Tuscumbia', 'Tushka', 'Tuskegee', 'Tustin', 'Tustin Foothills', 'Tuttle', 'Tutuilla', 'Tutwiler', 'Tuxedo Park', 'Twain', 'Twain Harte', 'Twentynine Palms', 'Twentynine Palms Base', 'Twilight', 'Twin Bridges', 'Twin Brooks', 'Twin City', 'Twin Falls', 'Twin Groves', 'Twin Hills', 'Twin Lake', 'Twin Lakes', 'Twin Oaks', 'Twin Rivers', 'Twin Valley', 'Twining', 'Twinsburg', 'Twisp', 'Two Buttes', 'Two Harbors', 'Two Rivers', 'Two Strike', 'Ty Ty', 'Tybee Island', 'Tye', 'Tygh Valley', 'Tyler', 'Tyler Run-Queens Gate', 'Tylertown', 'Tynan', 'Tyndall', 'Tyndall AFB', 'Tyonek', 'Tyro', 'Tyrone', 'Tyronza', 'Tysons Corner', 'Ubly', 'Ucon', 'Udall', 'Udell', 'Uehling', 'Ugashik', 'Uhland', 'Uhrichsville', 'Uintah', 'Ukiah', 'Ulen', 'Ullin', 'Ulm', 'Ulmer', 'Ulysses', 'Umatilla', 'Umber View Heights', 'Unadilla', 'Unalakleet', 'Unalaska', 'Uncertain', 'Underwood', 'Underwood-Petersville', 'Unicoi', 'Union', 'Union Beach', 'Union Bridge', 'Union Center', 'Union City', 'Union Dale', 'Union Gap', 'Union Grove', 'Union Hall', 'Union Hill', 'Union Hill-Novelty Hill', 'Union Park', 'Union Point', 'Union Springs', 'Union Star', 'Uniondale', 'Uniontown', 'Unionville', 'Unionville Center', 'Uniopolis', 'Unity', 'Unity Village', 'Universal', 'Universal City', 'University', 'University City', 'University Gardens', 'University Heights', 'University Park', 'University Place', 'Upham', 'Upland', 'Uplands Park', 'Upper Arlington', 'Upper Brookville', 'Upper Fruitland', 'Upper Grand Lagoon', 'Upper Kalskag', 'Upper Lake', 'Upper Marlboro', 'Upper Nyack', 'Upper Providence Township', 'Upper Saddle River', 'Upper Sandusky', 'Upper St. Clair', 'Upsala', 'Upton', 'Upton-West Upton', 'Urania', 'Urbana', 'Urbancrest', 'Urbandale', 'Urbank', 'Urbanna', 'Urich', 'Ursa', 'Ursina', 'Ute', 'Utica', 'Utopia', 'Utuado', 'Uvalda', 'Uvalde', 'Uvalde Estates', 'Vacaville', 'Vader', 'Vadito', 'Vadnais Heights', 'Vado', 'Vaiden', 'Vail', 'Vails Gate', 'Val Verde', 'Val Verde Park', 'Valatie', 'Valders', 'Valdese', 'Valdez', 'Valdosta', 'Vale', 'Valencia', 'Valencia West', 'Valentine', 'Valeria', 'Valhalla', 'Valier', 'Valinda', 'Valle Vista', 'Vallecito', 'Vallejo', 'Valley', 'Valley Acres', 'Valley Brook', 'Valley Center', 'Valley City', 'Valley Cottage', 'Valley Falls', 'Valley Green', 'Valley Grove', 'Valley Head', 'Valley Hi', 'Valley Hill', 'Valley Mills', 'Valley Park', 'Valley Ranch', 'Valley Springs', 'Valley Station', 'Valley Stream', 'Valley View', 'Valley-Hi', 'Valleyview', 'Valliant', 'Valmeyer', 'Valparaiso', 'Valrico', 'Vamo', 'Van', 'Van Alstyne', 'Van Buren', 'Van Etten', 'Van Horn', 'Van Horne', 'Van Meter', 'Van Tassell', 'Van Vleck', 'Van Wert', 'Vance', 'Vanceboro', 'Vanceburg', 'Vancleave', 'Vancouver', 'Vandalia', 'Vandemere', 'Vandenberg AFB', 'Vandenberg Village', 'Vander', 'Vanderbilt', 'Vandercook Lake', 'Vandergrift', 'Vandervoort', 'Vandiver', 'Vandling', 'Vanduser', 'Vanleer', 'Vanlue', 'Vann Crossroads', 'Vansant', 'Vantage', 'Vardaman', 'Varina', 'Varna', 'Varnado', 'Varnamtown', 'Varnell', 'Varnville', 'Vashon', 'Vass', 'Vassar', 'Vaughn', 'Veblen', 'Veedersburg', 'Vega', 'Vega Alta', 'Vega Baja', 'Velda City', 'Velda Village Hills', 'Velma', 'Velva', 'Venango', 'Venedocia', 'Venedy', 'Venersborg', 'Veneta', 'Venetian Village', 'Venetie', 'Venice', 'Venice Gardens', 'Ventnor City', 'Ventura', 'Venturia', 'Venus', 'Vera', 'Vera Cruz', 'Veradale', 'Verdel', 'Verden', 'Verdi-Mogul', 'Verdigre', 'Verdon', 'Vergas', 'Vergennes', 'Verlot', 'Vermilion', 'Vermillion', 'Vermont', 'Vermontville', 'Vernal', 'Verndale', 'Vernon', 'Vernon Center', 'Vernon Hills', 'Vernon Valley', 'Vernonburg', 'Vernonia', 'Vero Beach', 'Vero Beach South', 'Verona', 'Verplanck', 'Versailles', 'Vesper', 'Vesta', 'Vestavia Hills', 'Veteran', 'Vevay', 'Vian', 'Viborg', 'Viburnum', 'Vicco', 'Vici', 'Vicksburg', 'Victor', 'Victoria', 'Victorville', 'Victory', 'Victory Gardens', 'Victory Lakes', 'Vidalia', 'Vidette', 'Vidor', 'Vienna', 'Vienna Center', 'Vieques', 'View Park-Windsor Hills', 'Viking', 'Vilas', 'Villa Grove', 'Villa Heights', 'Villa Hills', 'Villa Pancho', 'Villa Park', 'Villa Rica', 'Villa Ridge', 'Villa Verde', 'Villa del Sol', 'Village Green', 'Village Green-Green Ridge', 'Village Park', 'Village Shires', 'Village St. George', 'Village of Clarkston', 'Village of Four Seasons', 'Village of Lake Isabella', 'Village of the Branch', 'Villages of Oriole', 'Villalba', 'Villano Beach', 'Villard', 'Villas', 'Ville Platte', 'Villisca', 'Vilonia', 'Vina', 'Vincennes', 'Vincent', 'Vinco', 'Vine Grove', 'Vine Hill', 'Vineland', 'Vineyard', 'Vineyard Haven', 'Vineyards', 'Vining', 'Vinings', 'Vinita', 'Vinita Park', 'Vinita Terrace', 'Vinton', 'Vintondale', 'Viola', 'Violet', 'Virden', 'Virgil', 'Virgilina', 'Virgin', 'Virginia', 'Virginia Beach', 'Virginia City', 'Virginia Gardens', 'Viroqua', 'Visalia', 'Vista', 'Vista Center', 'Vista West', 'Vivian', 'Volant', 'Volcano', 'Volga', 'Volin', 'Volo', 'Voltaire', 'Vona', 'Vonore', 'Voorheesville', 'Vredenburgh', 'Vázquez', 'WaKeeney', 'Wabash', 'Wabasha', 'Wabasso', 'Wabasso Beach', 'Wabbaseka', 'Wachapreague', 'Waco', 'Waconia', 'Waddington', 'Wade', 'Wade Hampton', 'Wadena', 'Wadesboro', 'Wading River', 'Wadley', 'Wadsworth', 'Waelder', 'Wagener', 'Waggaman', 'Waggoner', 'Wagner', 'Wagon Mound', 'Wagoner', 'Wagram', 'Wahiawa', 'Wahkon', 'Wahneta', 'Wahoo', 'Wahpeton', 'Waialua', 'Waianae', 'Waihee-Waiehu', 'Waikane', 'Waikapu', 'Waikoloa Village', 'Wailea-Makena', 'Wailua', 'Wailua Homesteads', 'Wailuku', 'Waimalu', 'Waimanalo', 'Waimanalo Beach', 'Waimea', 'Wainaku', 'Wainscott', 'Wainwright', 'Waipahu', 'Waipio', 'Waipio Acres', 'Waite Hill', 'Waite Park', 'Waitsburg', 'Wakarusa', 'Wake Forest', 'Wake Village', 'Wakefield', 'Wakefield-Peacedale', 'Wakeman', 'Wakita', 'Wakonda', 'Walbridge', 'Walcott', 'Walden', 'Waldenburg', 'Waldo', 'Waldoboro', 'Waldon', 'Waldorf', 'Waldport', 'Waldron', 'Waldwick', 'Wales', 'Waleska', 'Walford', 'Walhalla', 'Walker', 'Walker Mill', 'Walker Valley', 'Walkersville', 'Walkerton', 'Walkertown', 'Walkerville', 'Wall', 'Wall Lake', 'Walla Walla', 'Walla Walla East', 'Wallace', 'Wallaceton', 'Walled Lake', 'Waller', 'Wallingford', 'Wallingford Center', 'Wallington', 'Wallins Creek', 'Wallis', 'Wallkill', 'Wallowa', 'Wallsburg', 'Wallula', 'Walnut', 'Walnut Cove', 'Walnut Creek', 'Walnut Grove', 'Walnut Hill', 'Walnut Park', 'Walnut Ridge', 'Walnut Springs', 'Walnutport', 'Walpole', 'Walsenburg', 'Walsh', 'Walshville', 'Walstonburg', 'Walterboro', 'Walterhill', 'Walters', 'Walthall', 'Waltham', 'Walthill', 'Walthourville', 'Walton', 'Walton Hills', 'Walton Park', 'Waltonville', 'Walworth', 'Wamac', 'Wamego', 'Wamic', 'Wampsville', 'Wampum', 'Wamsutter', 'Wanamassa', 'Wanamingo', 'Wanaque', 'Wanatah', 'Wanblee', 'Wanchese', 'Wanda', 'Wanette', 'Wann', 'Wantagh', 'Wapakoneta', 'Wapanucka', 'Wapato', 'Wapella', 'Wapello', 'Wappingers Falls', 'War', 'Warba', 'Ward', 'Wardell', 'Warden', 'Wardensville', 'Wardner', 'Wardsville', 'Ware', 'Ware Shoals', 'Wareham Center', 'Waretown', 'Warfield', 'Warm Beach', 'Warm Mineral Springs', 'Warm River', 'Warm Springs', 'Warminster Heights', 'Warner', 'Warner Robins', 'Warr Acres', 'Warren', 'Warren AFB', 'Warren City', 'Warren Park', 'Warren South', 'Warrens', 'Warrensburg', 'Warrensville Heights', 'Warrenton', 'Warrenville', 'Warrington', 'Warrior', 'Warrior Run', 'Warroad', 'Warsaw', 'Warson Woods', 'Wartburg', 'Wartrace', 'Warwick', 'Wasco', 'Waseca', 'Washakie Ten', 'Washam', 'Washburn', 'Washington', 'Washington Grove', 'Washington Heights', 'Washington Park', 'Washington Terrace', 'Washington Township', 'Washingtonville', 'Washougal', 'Washta', 'Washtucna', 'Wasilla', 'Waskom', 'Wasta', 'Wataga', 'Watauga', 'Watchung', 'Water Valley', 'Waterbury', 'Waterford', 'Waterford North', 'Waterloo', 'Waterman', 'Watermill', 'Waterproof', 'Watertown', 'Waterville', 'Watervliet', 'Watford City', 'Watha', 'Wathena', 'Watkins', 'Watkins Glen', 'Watkinsville', 'Watonga', 'Watseka', 'Watson', 'Watsontown', 'Watsonville', 'Watterson Park', 'Watts', 'Watts Community', 'Watts Mills', 'Wattsburg', 'Waubay', 'Waubun', 'Wauchula', 'Waucoma', 'Wauconda', 'Waukee', 'Waukegan', 'Waukesha', 'Waukomis', 'Waukon', 'Waunakee', 'Wauneta', 'Waupaca', 'Waupun', 'Wauregan', 'Waurika', 'Wausa', 'Wausau', 'Wausaukee', 'Wauseon', 'Wautoma', 'Wauwatosa', 'Wauzeka', 'Waveland', 'Waverly', 'Waverly City', 'Waverly Hall', 'Waxahachie', 'Waxhaw', 'Waycross', 'Wayland', 'Waymart', 'Wayne', 'Wayne City', 'Wayne Heights', 'Wayne Lakes', 'Waynesboro', 'Waynesburg', 'Waynesfield', 'Waynesville', 'Waynetown', 'Waynoka', 'Wayzata', 'Weallup Lake', 'Weatherby', 'Weatherby Lake', 'Weatherford', 'Weatherly', 'Weatogue', 'Weaubleau', 'Weaver', 'Weaverville', 'Webb', 'Webb City', 'Webber', 'Webbers Falls', 'Webberville', 'Weber City', 'Webster', 'Webster City', 'Webster Groves', 'Weddington', 'Wedgefield', 'Wedgewood', 'Wedowee', 'Weed', 'Weedpatch', 'Weedsport', 'Weeki Wachee', 'Weeki Wachee Gardens', 'Weeping Water', 'Weidman', 'Weigelstown', 'Weimar', 'Weiner', 'Weinert', 'Weippe', 'Weir', 'Weirton', 'Weiser', 'Weissport', 'Weissport East', 'Wekiwa Springs', 'Welaka', 'Welby', 'Welch', 'Welcome', 'Weldon', 'Weldon Spring', 'Weldon Spring Heights', 'Weleetka', 'Wellersburg', 'Wellesley', 'Wellfleet', 'Wellford', 'Welling', 'Wellington', 'Wellman', 'Wells', 'Wells Branch', 'Wells River', 'Wellsboro', 'Wellsburg', 'Wellston', 'Wellsville', 'Wellton', 'Welsh', 'Welton', 'Wenatchee', 'Wendell', 'Wenden', 'Wendover', 'Wenona', 'Wenonah', 'Wentworth', 'Wentzville', 'Wernersville', 'Weslaco', 'Wesley', 'Wesley Chapel', 'Wesley Chapel South', 'Wesley Hills', 'Wesleyville', 'Wessington', 'Wessington Springs', 'Wesson', 'West', 'West Alexander', 'West Alexandria', 'West Allis', 'West Alton', 'West Athens', 'West Babylon', 'West Baden Springs', 'West Baraboo', 'West Bay Shore', 'West Belmar', 'West Bend', 'West Bishop', 'West Blocton', 'West Bloomfield Township', 'West Bountiful', 'West Bradenton', 'West Branch', 'West Brattleboro', 'West Brookfield', 'West Brooklyn', 'West Brownsville', 'West Buechel', 'West Burke', 'West Burlington', 'West Caldwell', 'West Canton', 'West Cape May', 'West Carrollton City', 'West Carson', 'West Carthage', 'West Chatham', 'West Chester', 'West Chicago', 'West City', 'West Clarkston-Highland', 'West College Corner', 'West Columbia', 'West Compton', 'West Concord', 'West Conshohocken', 'West Covina', 'West Crossett', 'West De Land', 'West Dennis', 'West Des Moines', 'West Dundee', 'West Easton', 'West Elizabeth', 'West Elkton', 'West Elmira', 'West End', 'West End-Cobb Town', 'West Falmouth', 'West Fargo', 'West Farmington', 'West Ferriday', 'West Fork', 'West Frankfort', 'West Freehold', 'West Gate', 'West Glendive', 'West Glens Falls', 'West Goshen', 'West Grove', 'West Hamlin', 'West Hampton Dunes', 'West Harrison', 'West Hartford', 'West Hattiesburg', 'West Haven', 'West Haven-Sylvan', 'West Haverstraw', 'West Havre', 'West Hazleton', 'West Helena', 'West Hempstead', 'West Hill', 'West Hills', 'West Hollywood', 'West Homestead', 'West Hurley', 'West Ishpeming', 'West Islip', 'West Jefferson', 'West Jordan', 'West Ken-Lark', 'West Kennebunk', 'West Kittanning', 'West Lafayette', 'West Lake Hills', 'West Lake Sammamish', 'West Lake Stevens', 'West Laurel', 'West Lawn', 'West Lebanon', 'West Leechburg', 'West Leipsic', 'West Liberty', 'West Line', 'West Linn', 'West Little River', 'West Livingston', 'West Logan', 'West Long Branch', 'West Longview', 'West Manchester', 'West Mansfield', 'West Marion', 'West Mayfield', 'West Melbourne', 'West Memphis', 'West Menlo Park', 'West Miami', 'West Middlesex', 'West Middletown', 'West Mifflin', 'West Milford', 'West Millgrove', 'West Milton', 'West Milwaukee', 'West Mineral', 'West Modesto', 'West Monroe', 'West Mountain', 'West New York', 'West Newton', 'West Norriton', 'West Nyack', 'West Ocean City', 'West Odessa', 'West Okoboji', 'West Orange', 'West Palm Beach', 'West Pasco', 'West Paterson', 'West Pearsall', 'West Peavine', 'West Pelzer', 'West Pensacola', 'West Peoria', 'West Perrine', 'West Pittston', 'West Plains', 'West Pleasant View', 'West Pocomoke', 'West Point', 'West Portsmouth', 'West Puente Valley', 'West Reading', 'West Richland', 'West River', 'West Rushville', 'West Rutland', 'West Sacramento', 'West Salem', 'West Samoset', 'West Sand Lake', 'West Sayville', 'West Seneca', 'West Sharyland', 'West Side Highway', 'West Siloam Springs', 'West Simsbury', 'West Slope', 'West Smithfield', 'West Springfield', 'West St. Paul', 'West Sunbury', 'West Swanzey', 'West Tawakoni', 'West Terre Haute', 'West Union', 'West Unity', 'West University Place', 'West Valley', 'West Valley City', 'West Vero Corridor', 'West View', 'West Wareham', 'West Warwick', 'West Wenatchee', 'West Wendover', 'West Whittier-Los Nietos', 'West Wildwood', 'West Winfield', 'West Wyoming', 'West Wyomissing', 'West Yarmouth', 'West Yellowstone', 'West York', 'West and East Lealman', 'Westboro', 'Westborough', 'Westbrook', 'Westbrook Center', 'Westbury', 'Westby', 'Westchase', 'Westchester', 'Westcliffe', 'Westcreek', 'Westdale', 'Westerly', 'Western', 'Western Grove', 'Western Springs', 'Westernport', 'Westerville', 'Westfield', 'Westfield Center', 'Westfir', 'Westgate', 'Westgate-Belvedere Homes', 'Westhampton', 'Westhampton Beach', 'Westhaven-Moonstone', 'Westhope', 'Westlake', 'Westlake Corner', 'Westlake Village', 'Westland', 'Westley', 'Westmere', 'Westminster', 'Westmont', 'Westmoreland', 'Westmorland', 'Weston', 'Weston Mills', 'Westover', 'Westover Hills', 'Westphalia', 'Westport', 'Westside', 'Westvale', 'Westview', 'Westview Circle', 'Westville', 'Westway', 'Westwego', 'Westwood', 'Westwood Hills', 'Westwood Lakes', 'Westworth Village', 'Wetherington', 'Wethersfield', 'Wetmore', 'Wetonka', 'Wetumka', 'Wetumpka', 'Wewahitchka', 'Weweantic', 'Wewoka', 'Weyauwega', 'Weyerhaeuser', 'Weyers Cave', 'Weymouth', 'Whalan', 'Whale Pass', 'Whaleyville', 'Wharton', 'What Cheer', 'Wheat Ridge', 'Wheatcroft', 'Wheatfield', 'Wheatland', 'Wheatley', 'Wheatley Heights', 'Wheaton', 'Wheaton-Glenmont', 'Wheeler', 'Wheeler AFB', 'Wheelersburg', 'Wheeling', 'Wheelwright', 'Whelen Springs', 'Whetstone', 'Whigham', 'Whipps Millgate', 'Whiskey Creek', 'Whisper Walk', 'Whispering Pines', 'Whitaker', 'Whitakers', 'White', 'White Bear Lake', 'White Bird', 'White Bluff', 'White Castle', 'White Center', 'White City', 'White Cloud', 'White Deer', 'White Earth', 'White Hall', 'White Haven', 'White Horse', 'White House', 'White House Station', 'White Island Shores', 'White Lake', 'White Marsh', 'White Meadow Lake', 'White Mesa', 'White Mountain', 'White Oak', 'White Oak East', 'White Oak West', 'White Pigeon', 'White Pine', 'White Plains', 'White River', 'White River Junction', 'White Rock', 'White Salmon', 'White Sands', 'White Settlement', 'White Shield', 'White Springs', 'White Stone', 'White Sulphur Springs', 'White Swan', 'Whiteash', 'Whiteface', 'Whitefield', 'Whitefish', 'Whitefish Bay', 'Whitehall', 'Whitehawk', 'Whitehorse', 'Whitehouse', 'Whiteland', 'Whitelaw', 'Whiteman AFB', 'Whitemarsh Island', 'Whiteriver', 'Whiterocks', 'Whitesboro', 'Whitesboro-Burleigh', 'Whitesburg', 'Whiteside', 'Whitestone Logging Camp', 'Whitestown', 'Whitesville', 'Whiteville', 'Whitewater', 'Whitewood', 'Whitewright', 'Whitfield', 'Whiting', 'Whitinsville', 'Whitley City', 'Whitmire', 'Whitmore Lake', 'Whitmore Village', 'Whitney', 'Whitney Point', 'Whitsett', 'Whittemore', 'Whitten', 'Whittier', 'Whittingham', 'Whitwell', 'Wibaux', 'Wichita', 'Wichita Falls', 'Wickenburg', 'Wickerham Manor-Fisher', 'Wickes', 'Wickett', 'Wickliffe', 'Widener', 'Wiederkehr Village', 'Wiggins', 'Wilber', 'Wilberforce', 'Wilbraham', 'Wilbur', 'Wilbur Park', 'Wilburton', 'Wilburton Number One', 'Wilburton Number Two', 'Wilcox', 'Wild Peach Village', 'Wild Rose', 'Wilder', 'Wildomar', 'Wildrose', 'Wildwood', 'Wildwood Crest', 'Wildwood Lake', 'Wiley', 'Wiley Ford', 'Wilhoit', 'Wilkerson', 'Wilkes-Barre', 'Wilkes-Barre Township', 'Wilkesboro', 'Wilkeson', 'Wilkesville', 'Wilkins Township', 'Wilkinsburg', 'Wilkinson', 'Wilkinson Heights', 'Willacoochee', 'Willamar', 'Willamina', 'Willard', 'Willards', 'Willcox', 'Willernie', 'Willey', 'Williams', 'Williams Bay', 'Williams Creek', 'Williamsburg', 'Williamsfield', 'Williamson', 'Williamsport', 'Williamston', 'Williamstown', 'Williamsville', 'Williford', 'Willimantic', 'Willington', 'Willis', 'Willisburg', 'Williston', 'Williston Highlands', 'Williston Park', 'Willisville', 'Willits', 'Willmar', 'Willoughby', 'Willoughby Hills', 'Willow', 'Willow City', 'Willow Creek', 'Willow Grove', 'Willow Hill', 'Willow Lake', 'Willow Oak', 'Willow Park', 'Willow River', 'Willow Springs', 'Willow Street', 'Willow Valley', 'Willowbrook', 'Willowick', 'Willows', 'Wills Point', 'Willshire', 'Wilmar', 'Wilmer', 'Wilmerding', 'Wilmette', 'Wilmington', 'Wilmington Island', 'Wilmington Manor', 'Wilmont', 'Wilmore', 'Wilmot', 'Wilsall', 'Wilsey', 'Wilson', 'Wilson City', 'Wilson Creek', 'Wilson\'s Mills', 'Wilson-Conococheague', 'Wilsonville', 'Wilton', 'Wilton Manors', 'Wimauma', 'Wimberley', 'Wimbledon', 'Winamac', 'Winchendon', 'Winchester', 'Winchester Bay', 'Wind Gap', 'Wind Lake', 'Wind Point', 'Windber', 'Windcrest', 'Windemere', 'Winder', 'Windermere', 'Windfall City', 'Windham', 'Windom', 'Window Rock', 'Windsor', 'Windsor Heights', 'Windsor Locks', 'Windthorst', 'Windy Hills', 'Winfall', 'Winfield', 'Wing', 'Wingate', 'Winger', 'Wingo', 'Winifred', 'Wink', 'Winkelman', 'Winlock', 'Winnebago', 'Winneconne', 'Winnemucca', 'Winner', 'Winnetka', 'Winnetoon', 'Winnett', 'Winnfield', 'Winnie', 'Winnsboro', 'Winnsboro Mills', 'Winona', 'Winona Lake', 'Winooski', 'Winside', 'Winslow', 'Winslow West', 'Winsted', 'Winston', 'Winston-Salem', 'Winstonville', 'Winter', 'Winter Beach', 'Winter Garden', 'Winter Gardens', 'Winter Haven', 'Winter Park', 'Winter Springs', 'Winterhaven', 'Winterport', 'Winters', 'Winterset', 'Winterstown', 'Wintersville', 'Winterville', 'Winthrop', 'Winthrop Harbor', 'Winton', 'Wiota', 'Wiscasset', 'Wisconsin Dells', 'Wisconsin Rapids', 'Wisdom', 'Wise', 'Wiseman', 'Wishek', 'Wishram', 'Wisner', 'Wister', 'Withamsville', 'Withee', 'Witt', 'Wittenberg', 'Wixom', 'Wixon Valley', 'Woburn', 'Woden', 'Wofford Heights', 'Wolbach', 'Wolcott', 'Wolcottville', 'Wolf Lake', 'Wolf Point', 'Wolf Trap', 'Wolfdale', 'Wolfe City', 'Wolfeboro', 'Wolfforth', 'Wolford', 'Wolsey', 'Wolverine', 'Wolverine Lake', 'Wolverton', 'Womelsdorf', 'Womelsdorf (Coalton)', 'Womens Bay', 'Wonder Lake', 'Wonewoc', 'Wood', 'Wood Dale', 'Wood Lake', 'Wood River', 'Wood Village', 'Wood-Ridge', 'Woodacre', 'Woodall', 'Woodbine', 'Woodbourne', 'Woodbourne-Hyde Park', 'Woodbranch', 'Woodbridge', 'Woodburn', 'Woodbury', 'Woodbury Center', 'Woodbury Heights', 'Woodcliff Lake', 'Woodcock', 'Woodcreek', 'Woodcrest', 'Woodfield', 'Woodfin', 'Woodford', 'Woodhaven', 'Woodhull', 'Woodinville', 'Woodlake', 'Woodland', 'Woodland Beach', 'Woodland Heights', 'Woodland Hills', 'Woodland Mills', 'Woodland Park', 'Woodlawn', 'Woodlawn Heights', 'Woodlawn Park', 'Woodlawn-Oakdale', 'Woodloch', 'Woodlyn', 'Woodlynne', 'Woodman', 'Woodmere', 'Woodmont', 'Woodmoor', 'Woodmore', 'Woodridge', 'Woodruff', 'Woods Bay', 'Woods Creek', 'Woods Cross', 'Woods Heights', 'Woods Hole', 'Woods Landing-Jelm', 'Woodsboro', 'Woodsburgh', 'Woodsfield', 'Woodside', 'Woodside East', 'Woodson', 'Woodson Terrace', 'Woodstock', 'Woodston', 'Woodstown', 'Woodsville', 'Woodville', 'Woodward', 'Woodway', 'Woodworth', 'Wooldridge', 'Woolsey', 'Woolstock', 'Woonsocket', 'Wooster', 'Worcester', 'Worden', 'Worland', 'Worley', 'Wormleysburg', 'Worth', 'Wortham', 'Worthing', 'Worthington', 'Worthington Hills', 'Worthington Springs', 'Worthville', 'Wounded Knee', 'Wrangell', 'Wray', 'Wren', 'Wrens', 'Wrenshall', 'Wright', 'Wright City', 'Wright-Patterson AFB', 'Wrightsboro', 'Wrightstown', 'Wrightsville', 'Wrightsville Beach', 'Wrightwood', 'Wurtland', 'Wurtsboro', 'Wyaconda', 'Wyalusing', 'Wyandanch', 'Wyandotte', 'Wyanet', 'Wyatt', 'Wyckoff', 'Wye', 'Wyeville', 'Wykoff', 'Wyldwood', 'Wylie', 'Wymore', 'Wynantskill', 'Wyncote', 'Wyndham', 'Wyndmere', 'Wyndmoor', 'Wynne', 'Wynnedale', 'Wynnewood', 'Wynona', 'Wynot', 'Wyocena', 'Wyola', 'Wyoming', 'Wyomissing', 'Wyomissing Hills', 'Wytheville', 'Xenia', 'Y', 'Y-O Ranch', 'Yabucoa', 'Yachats', 'Yacolt', 'Yadkinville', 'Yah-ta-hey', 'Yakima', 'Yakutat', 'Yalaha', 'Yale', 'Yamhill', 'Yampa', 'Yanceyville', 'Yankee Lake', 'Yankeetown', 'Yankton', 'Yantis', 'Yaphank', 'Yardley', 'Yardville-Groveville', 'Yarmouth', 'Yarmouth Port', 'Yarnell', 'Yarrow Point', 'Yates Center', 'Yates City', 'Yatesville', 'Yauco', 'Yaurel', 'Yazoo City', 'Yeadon', 'Yeager', 'Yeagertown', 'Yeehaw Junction', 'Yellow Bluff', 'Yellow Springs', 'Yellville', 'Yelm', 'Yemassee', 'Yeoman', 'Yerington', 'Yetter', 'Yoakum', 'Yoder', 'Yoe', 'Yoncalla', 'Yonkers', 'Yorba Linda', 'York', 'York Harbor', 'York Haven', 'York Springs', 'Yorkana', 'Yorketown', 'Yorkshire', 'Yorktown', 'Yorktown Heights', 'Yorkville', 'Yosemite Lakes', 'Yosemite Valley', 'Young', 'Young Harris', 'Youngstown', 'Youngsville', 'Youngtown', 'Youngwood', 'Yountville', 'Ypsilanti', 'Yreka', 'Yuba', 'Yuba City', 'Yucaipa', 'Yucca Valley', 'Yukon', 'Yulee', 'Yuma', 'Yutan', 'Yznaga', 'Zachary', 'Zaleski', 'Zalma', 'Zanesfield', 'Zanesville', 'Zap', 'Zapata', 'Zapata Ranch', 'Zavalla', 'Zearing', 'Zeb', 'Zebulon', 'Zeeland', 'Zeigler', 'Zelienople', 'Zellwood', 'Zemple', 'Zena', 'Zenda', 'Zephyr Cove-Round Hill Village', 'Zephyrhills', 'Zephyrhills North', 'Zephyrhills South', 'Zephyrhills West', 'Zia Pueblo', 'Zillah', 'Zilwaukee', 'Zimmerman', 'Zinc', 'Zion', 'Zionsville', 'Zoar', 'Zolfo Springs', 'Zuehl', 'Zumbro Falls', 'Zumbrota', 'Zuni Pueblo', 'Zurich', 'Zwingle', 'Zwolle' ]}; sub validate { my ($self, $proto, $field, $param) = @_; if (defined $field->{city} && defined $param) { if ($field->{required} || $param) { my $cre = $self->regexp; $self->error($proto, $field) unless $param =~ /$cre/i; } } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::City - City Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { address_city => { city => 1 } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::Between is a core validation class field directive that provides the ability to perform city/area validations for cities in the USA. Cities will be validated without regard for case. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Help.pm100644000765000024 330414410403624 24665 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: Help Directive for Validation Class Field Definitions package Validation::Class::Directive::Help; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 0; has 'field' => 1; has 'multi' => 0; sub normalize { my ($self, $proto, $field) = @_; # static help-text may contain multiline strings for the sake of # aesthetics, flatten them here if (defined $field->{help}) { $field->{help} =~ s/^[\n\s\t\r]+//g; $field->{help} =~ s/[\n\s\t\r]+$//g; $field->{help} =~ s/[\n\s\t\r]+/ /g; } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::Help - Help Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { username => { help => q/A username was automatically generated for you at the time you registered your account. Check your email client for additional instructions./ } } ); =head1 DESCRIPTION Validation::Class::Directive::Help is a core validation class field directive that holds the help-text statement(s) to be associated with specific fields which are useful when rendering form fields or when developing RESTful API resources. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Name.pm100644000765000024 167614410403624 24667 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: Name Directive for Validation Class Field Definitions package Validation::Class::Directive::Name; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 0; 1; __END__ =pod =head1 NAME Validation::Class::Directive::Name - Name Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 DESCRIPTION Validation::Class::Directive::Name is a core validation class field directive that merely holds the name of the associated field. This directive is used internally and the value is populated automatically. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut UUID.pm100644000765000024 320614410403624 24544 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: UUID Directive for Validation Class Field Definitions package Validation::Class::Directive::UUID; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 0; has 'message' => '%s is not a valid UUID'; sub validate { my ($self, $proto, $field, $param) = @_; if (defined $field->{uuid} && defined $param) { if ($field->{required} || $param) { my $ure = qr/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i; $self->error($proto, $field) unless $param =~ $ure; } } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::UUID - UUID Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { user_uuid => { uuid => 1 } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::UUID is a core validation class field directive that handles validation of Globally/Universally Unique Identifiers. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Date.pm100644000765000024 1217114410403624 24674 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: Date Directive for Validation Class Field Definitions package Validation::Class::Directive::Date; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 0; has 'message' => '%s requires a valid date'; sub validate { my ($self, $proto, $field, $param) = @_; if (defined $field->{date} && defined $param) { my $dtre = { # options: # dmy 27-12-2006 or 27-12-06 separators can be a space, period, dash, forward slash # mdy 12-27-2006 or 12-27-06 separators can be a space, period, dash, forward slash # ymd 2006-12-27 or 06-12-27 separators can be a space, period, dash, forward slash # dMy 27 December 2006 or 27 Dec 2006 # Mdy December 27, 2006 or Dec 27, 2006 comma is optional # My December 2006 or Dec 2006 # my 12/2006 separators can be a space, period, dash, forward slash 'dmy' => qr%^(?:(?:31(\/|-|\.|\x20)(?:0?[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.|\x20)(?:0?[1,3-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.|\x20)0?2\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.|\x20)(?:(?:0?[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$%, 'mdy' => qr%^(?:(?:(?:0?[13578]|1[02])(\/|-|\.|\x20)31)\1|(?:(?:0?[13-9]|1[0-2])(\/|-|\.|\x20)(?:29|30)\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:0?2(\/|-|\.|\x20)29\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0?[1-9])|(?:1[0-2]))(\/|-|\.|\x20)(?:0?[1-9]|1\d|2[0-8])\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$%, 'ymd' => qr%^(?:(?:(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))(\/|-|\.|\x20)(?:0?2\1(?:29)))|(?:(?:(?:1[6-9]|[2-9]\d)?\d{2})(\/|-|\.|\x20)(?:(?:(?:0?[13578]|1[02])\2(?:31))|(?:(?:0?[1,3-9]|1[0-2])\2(29|30))|(?:(?:0?[1-9])|(?:1[0-2]))\2(?:0?[1-9]|1\d|2[0-8]))))$%, 'dMy' => qr%^((31(?!\ (Feb(ruary)?|Apr(il)?|June?|(Sep(?=\b|t)t?|Nov)(ember)?)))|((30|29)(?!\ Feb(ruary)?))|(29(?=\ Feb(ruary)?\ (((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)))))|(0?[1-9])|1\d|2[0-8])\ (Jan(uary)?|Feb(ruary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sep(?=\b|t)t?|Nov|Dec)(ember)?)\ ((1[6-9]|[2-9]\d)\d{2})$%, 'Mdy' => qr%^(?:(((Jan(uary)?|Ma(r(ch)?|y)|Jul(y)?|Aug(ust)?|Oct(ober)?|Dec(ember)?)\ 31)|((Jan(uary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sep)(tember)?|(Nov|Dec)(ember)?)\ (0?[1-9]|([12]\d)|30))|(Feb(ruary)?\ (0?[1-9]|1\d|2[0-8]|(29(?=,?\ ((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)))))))\,?\ ((1[6-9]|[2-9]\d)\d{2}))$%, 'My' => qr%^(Jan(uary)?|Feb(ruary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sep(?=\b|t)t?|Nov|Dec)(ember)?)[ /]((1[6-9]|[2-9]\d)\d{2})$%, 'my' => qr%^(((0[123456789]|10|11|12)([- /.])(([1][9][0-9][0-9])|([2][0-9][0-9][0-9]))))$% }; my $type = $field->{date}; if ($field->{required} || $param) { my $is_valid = 0; $type = isa_arrayref($type) ? $type : $type eq '1' ? [sort keys %$dtre] : [$type] ; for (@{$type}) { if ($param =~ $dtre->{$_}) { $is_valid = 1; last; } } $self->error($proto, $field) unless $is_valid; } } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::Date - Date Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { creation_date => { date => 1 } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::Date is a core validation class field directive that provides validation of simple date formats. =over 8 =item * alternative argument: an-array-of-options =item * option: dmy e.g. 27-12-2006 or 27-12-06 =item * option: mdy e.g. 12-27-2006 or 12-27-06 =item * option: ymd e.g. 2006-12-27 or 06-12-27 =item * option: dMy e.g. 27 December 2006 or 27 Dec 2006 =item * option: Mdy e.g. December 27, 2006 or Dec 27, 2006 (comma optional) =item * option: My e.g. December 2006 or Dec 2006 =item * option: my e.g. 12/2006 This directive can be passed a single value or an array of values: fields => { creation_date => { date => ['dmy', 'mdy'] } } =back =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut 10-default-values.t100644000765000024 302714410403624 25031 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regressionuse Test::More; package MyVal::A; use Validation::Class; package MyVal::B; use Validation::Class; mixin ':unique' => { pattern => qr/^\d+$/, required => 1, min_length => 1, max_length => 255, filters => ['trim', 'strip', 'numeric'], default => sub { time() } }; package main; my $a = MyVal::A->new( fields => { access_key => { default => 12345, required => 1 }, access_code => { default => sub { return ref shift; }, required => 1 }, }, params => { access_key => 'abcde', access_code => 'abcdefghi' } ); ok $a, 'class initialized'; ok 'abcde' eq $a->params->get('access_key'), 'access_key has explicit value'; ok 'abcdefghi' eq $a->params->get('access_code'), 'access_code has explicit value'; $a->params->clear; ok $a->validate('access_code', 'access_key'), 'params validated via default values'; ok 12345 eq $a->params->get('access_key'), 'access_key has default value'; ok 'MyVal::A' eq $a->params->get('access_code'), 'access_code has default value w/context'; my $b = MyVal::B->new( fields => { access_code => { mixin => ':unique', multiples => 1, default => sub { time() }, required => 1 }, }, params => { } ); ok $b->validate('access_code'), 'access_code passed validation'; #require Data::Dumper; die Data::Dumper::Dumper($b->proto->fields, $b->proto->params); done_testing; 98-unknown_params.t100644000765000024 56414410403624 25155 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regressionuse Test::More tests => 1; package MyVal; use Validation::Class; package main; my $r = MyVal->new( fields => { status => { # ... } }, params => { _dc => '1310548813350', id => 'i4jiojtrgijeriogjrtiorjwgoitjr' }, ignore_unknown => 1 ); # resolve the anomyly ok $r->validate('_foo'), 'valid by default'; 04-profile-usages.t100644000765000024 502014410403624 25033 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regressionBEGIN { use FindBin; use lib $FindBin::Bin. "/modules/"; } use Test::More tests => 12; package MyValAlt; use Validation::Class; mixin ID => { required => 1, min_length => 1, max_length => 11 }; mixin TEXT => { required => 1, min_length => 1, max_length => 255, filters => [qw/trim strip/] }; mixin UTEXT => { required => 1, min_length => 1, max_length => 255, filters => 'uppercase' }; field id => { mixin => 'ID', label => 'Object ID', error => 'Object ID error' }; field name => { mixin => 'TEXT', label => 'Object Name', error => 'Object Name error', filters => ['uppercase'] }; field handle => { mixin => 'UTEXT', label => 'Object Handle', error => 'Object Handle error', filters => [qw/trim strip/] }; field email => { mixin => 'TEXT', label => 'Object Email', error => 'Object Email error', max_length => 500 }; field email_confirm => { mixin_field => 'email', label => 'Object Email Confirm', error => 'Object Email confirmation error', min_length => 5 }; profile email_change => sub { my ($self, $hash) = @_; $self->validate('+email', '+email_confirm'); return $self->error_count && keys %{$hash} ? 1 : 0; }; package main; use MyVal; my $v1 = MyValAlt->new(params => {}); ok $v1, 'initialization successful'; ok !$v1->validate_profile('email_change'), 'email_change profile did not validate'; ok $v1->error_count == 2, '2 errors encountered on failure'; $v1->params->{email} = 'abc'; $v1->params->{email_confirm} = 'abc'; ok !$v1->validate_profile('email_change'), 'email_change profile did not validate'; ok $v1->validate_profile('email_change', {this => 'that'}), 'email_change profile validated OK'; my $v2 = MyVal->new(params => {}); ok !$v2->validate_profile('new_ticket'), 'new_ticket profile did not validate'; ok $v2->error_count == 2, '2 errors encountered on failure'; $v2->param(name => 'the dude'); ok !$v2->validate_profile('new_ticket'), 'new_ticket profile did not validate'; ok $v2->error_count == 1, '1 errors encountered on failure'; $v2->param(description => 'the bomb dot com'); ok $v2->validate_profile('new_ticket'), 'new_ticket profile validated OK'; ok $v2->error_count == 0, 'NO errors set'; my $v3 = MyVal->new( params => { 'person.name' => 'the dude', 'ticket.description' => 'hot diggidy dog' } ); ok $v3->validate_profile('new_ticket'), 'new_ticket profile validated OK'; validators000755000765000024 014410403624 23513 5ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression22-ssn.t100644000765000024 162714410403624 25072 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/validatorsuse Test::More; package main; use utf8; use Validation::Class::Simple; my $s = Validation::Class::Simple->new( fields => { user_ssn => {ssn => 1} } ); sub should_fail { my ($name, @ssns) = @_; for (@ssns) { $s->params->{$name} = $_; ok !$s->validate($name), "$_ is an invalid $name param"; } } sub should_pass { my ($name, @ssns) = @_; for (@ssns) { $s->params->{$name} = $_; ok $s->validate($name), "$_ is a valid $name param"; } } # failures diag 'validating bad social security numbers'; should_fail 'user_ssn' => qw( 000000000 111111111 123456789 000-00-0000 203-303-698 203-303-6988 ); diag 'validating good social security numbers'; should_pass 'user_ssn' => qw( 203-00-6988 987-65-4321 001-11-1111 211-10-1234 209-20-1811 207-65-9878 303-17-2345 416-33-0693 ); done_testing; Simple000755000765000024 014410403624 22612 5ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/ClassStreamer.pm100644000765000024 2457314410403624 25125 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Simple# ABSTRACT: Simple Streaming Data Validation package Validation::Class::Simple::Streamer; use 5.10.0; use strict; use warnings; use base 'Validation::Class::Simple'; use Carp; use Validation::Class::Util; use overload bool => \&validate, '""' => \&messages, fallback => 1; our $VERSION = '7.900059'; # VERSION sub new { my $class = shift; $class = ref $class || $class; my $self = $class->SUPER::new(@_); $self->{action} = ''; $self->{target} = ''; return $self; } sub check { my ($self, $target) = @_; if ($target) { return $self if $target eq $self->{target}; $self->prototype->fields->add($target => {name => $target}) unless $self->prototype->fields->has($target); $self->prototype->queue($self->{target} = $target); $self->prototype->normalize($self); } return $self; } sub clear { my ($self) = @_; $self->prototype->queued->clear; $self->prototype->reset_fields; return $self; } sub declare { my ($self, @config) = @_; my $arguments = pop(@config); my $action = shift(@config) || $self->{action}; my $target = $self->{target}; return $self unless $target; $self->prototype->queue($target); # if clear() was called or check() wasn't unless ($arguments) { $arguments = 1 if $action eq 'city'; $arguments = 1 if $action eq 'creditcard'; $arguments = 1 if $action eq 'date'; $arguments = 1 if $action eq 'decimal'; $arguments = 1 if $action eq 'email'; $arguments = 1 if $action eq 'hostname'; $arguments = 1 if $action eq 'multiples'; $arguments = 1 if $action eq 'required'; $arguments = 1 if $action eq 'ssn'; $arguments = 1 if $action eq 'state'; $arguments = 1 if $action eq 'telephone'; $arguments = 1 if $action eq 'time'; $arguments = 1 if $action eq 'uuid'; $arguments = 1 if $action eq 'zipcode'; } if ($self->prototype->fields->has($target)) { my $field = $self->prototype->fields->get($target); if ($field->can($action)) { $field->$action($arguments) if defined $arguments; return $self; } } exit carp sprintf q(Can't locate object method "%s" via package "%s"), $action, ((ref $_[0] || $_[0]) || 'main') ; } sub messages { my ($self, @arguments) = @_; return $self->prototype->errors_to_string(@arguments); } sub validate { my ($self) = @_; my $true = $self->prototype->validate($self); return $true; } sub AUTOLOAD { (my $routine = $Validation::Class::Simple::Streamer::AUTOLOAD) =~ s/.*:://; my ($self) = @_; if ($routine) { $self->{action} = $routine; goto &declare; } croak sprintf q(Can't locate object method "%s" via package "%s"), $routine, ((ref $_[0] || $_[0]) || 'main') ; } sub DESTROY {} 1; __END__ =pod =head1 NAME Validation::Class::Simple::Streamer - Simple Streaming Data Validation =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple::Streamer; my $params = { credit_card => '0000000000000000', email_address => 'root@localhost', }; my $rules = Validation::Class::Simple::Streamer->new(params => $params); # the point here is expressiveness # directive methods auto-validate in boolean context !!! if (not $rules->check('credit_card')->creditcard(['visa', 'mastercard'])) { # credit card is invalid visa/mastercard warn $rules->errors_to_string; } if (not $rules->check('email_address')->min_length(3)->email) { # email address is invalid warn $rules->errors_to_string; } # prepare password for validation $rules->check('password'); die "Password is not valid" unless $rules->min_symbols(1) && $rules->matches('password2'); # are you of legal age? if ($rules->check('member_years_of_age')->between('18-75')) { # access to explicit content approved } # get all fields with errors my $fields = $rules->error_fields; # warn with errors if any warn $rules->errors_to_string unless $rules->validate; =head1 DESCRIPTION Validation::Class::Simple::Streamer is a simple streaming validation module that makes data validation fun. Target parameters and attach matching fields and directives to them by chaining together methods which represent Validation::Class L. This module is built around the powerful L data validation framework via L. This module is a sub-class of and derived from the L class. =head1 RATIONALE If you are new to Validation::Class, or would like more information on the underpinnings of this library and how it views and approaches data validation, please review L. Please review the L for a detailed step-by-step look into how Validation::Class works. =head1 METHODS =head2 check The check method specifies the parameter to be affected by directive methods if/when called. $self = $self->check('email_address'); # focus on email_address $self->required; # apply the Required directive to email_address $self->min_symbols(1); # apply the MinSymbols directive to email_address $self->min_length(5); # apply the MinLength directive to email_address =head2 clear The clear method resets the validation queue and declared fields but leaves the declared parameters in-tact, almost like the object state post-instantiation. $self->clear; =head2 messages The messages method returns any registered errors as a concatenated string using the L method and accepts the same parameters. print $self->messages; =head2 validate The validate method uses the validator to perform data validation based on the series and sequence of commands issued previously. This method is called implicitly whenever the object is used in boolean context, e.g. in a conditional. $true = $self->validate; =head1 PROXY METHODS Each instance of Validation::Class::Simple::Streamer is injected with a few proxy methods which are basically aliases to the corresponding prototype class methods, however it is possible to access the prototype directly using the proto/prototype methods. =head2 class $self->class; See L for full documentation. =head2 clear_queue $self->clear_queue; See L for full documentation. =head2 error_count $self->error_count; See L for full documentation. =head2 error_fields $self->error_fields; See L for full documentation. =head2 errors $self->errors; See L for full documentation. =head2 errors_to_string $self->errors_to_string; See L for full documentation. =head2 get_errors $self->get_errors; See L for full documentation. =head2 get_fields $self->get_fields; See L for full documentation. =head2 get_hash $self->get_hash; See L for full documentation. =head2 get_params $self->get_params; See L for full documentation. =head2 get_values $self->get_values; See L for full documentation. =head2 fields $self->fields; See L for full documentation. =head2 filtering $self->filtering; See L for full documentation. =head2 ignore_failure $self->ignore_failure; See L for full documentation. =head2 ignore_unknown $self->ignore_unknown; See L for full documentation. =head2 is_valid $self->is_valid; See L for full documentation. =head2 param $self->param; See L for full documentation. =head2 params $self->params; See L for full documentation. =head2 plugin $self->plugin; See L for full documentation. =head2 queue $self->queue; See L for full documentation. =head2 report_failure $self->report_failure; See L for full documentation. =head2 report_unknown $self->report_unknown; See L for full documentation. =head2 reset_errors $self->reset_errors; See L for full documentation. =head2 reset_fields $self->reset_fields; See L for full documentation. =head2 reset_params $self->reset_params; See L for full documentation. =head2 set_errors $self->set_errors; See L for full documentation. =head2 set_fields $self->set_fields; See L for full documentation. =head2 set_params $self->set_params; See L for full documentation. =head2 set_method $self->set_method; See L for full documentation. =head2 stash $self->stash; See L for full documentation. =head2 validate $self->validate; See L for full documentation. =head2 validate_method $self->validate_method; See L for full documentation. =head2 validate_profile $self->validate_profile; See L for full documentation. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Mixin.pm100644000765000024 263314410403624 25065 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: Mixin Directive for Validation Class Field Definitions package Validation::Class::Directive::Mixin; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 0; has 'field' => 1; has 'multi' => 1; 1; __END__ =pod =head1 NAME Validation::Class::Directive::Mixin - Mixin Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( mixins => { basic => { required => 1, filters => ['trim', 'strip'] } } fields => { full_name => { mixin => 'basic' } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::Mixin is a core validation class field directive that determines what directive templates will be merged with the associated field. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Error.pm100644000765000024 332114410403624 25065 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: Error Directive for Validation Class Field Definitions package Validation::Class::Directive::Error; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 0; has 'field' => 1; has 'multi' => 0; sub normalize { my ($self, $proto, $field) = @_; # static messages may contain multiline strings for the sake of # aesthetics, flatten them here if (defined $field->{error}) { $field->{error} =~ s/^[\n\s\t\r]+//g; $field->{error} =~ s/[\n\s\t\r]+$//g; $field->{error} =~ s/[\n\s\t\r]+/ /g; } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::Error - Error Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { username => { error => 'This is not a valid username' } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::Error is a core validation class field directive that holds the error message that will supersede any other error messages that attempt to register errors at the field-level for the associated field. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Alias.pm100644000765000024 533114410403624 25030 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: Alias Directive for Validation Class Field Definitions package Validation::Class::Directive::Alias; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 0; has 'field' => 1; has 'multi' => 0; has 'dependencies' => sub {{ normalization => ['name'], validation => ['name'] }}; sub normalize { my ($self, $proto, $field, $param) = @_; # create a map from aliases if applicable $self->execute_alias_mapping($proto, $field, $param); return $self; } sub before_validation { my ($self, $proto, $field, $param) = @_; # create a map from aliases if applicable $self->execute_alias_mapping($proto, $field, $param); return $self; } sub execute_alias_mapping { my ($self, $proto, $field, $param) = @_; if (defined $field->{alias}) { my $name = $field->{name}; my $aliases = isa_arrayref($field->{alias}) ? $field->{alias} : [$field->{alias}] ; foreach my $alias (@{$aliases}) { if ($proto->params->has($alias)) { # rename the submitted parameter alias with the field name $proto->params->add($name => $proto->params->delete($alias)); push @{$proto->stash->{'validation.fields'}}, $name unless grep { $name eq $_} @{$proto->stash->{'validation.fields'}} ; } } } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::Alias - Alias Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { login => { alias => 'username' } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::Alias is a core validation class field directive that provides the ability to map arbitrary parameter names with a field's parameter value. =over 8 =item * alternative argument: an-array-of-aliases This directive can be passed a single value or an array of values: fields => { login => { alias => ['username', 'email_address'] } } =back =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Label.pm100644000765000024 323214410403624 25014 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: Label Directive for Validation Class Field Definitions package Validation::Class::Directive::Label; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 0; has 'field' => 1; has 'multi' => 0; sub normalize { my ($self, $proto, $field) = @_; # static messages may contain multiline strings for the sake of # aesthetics, flatten them here if (defined $field->{label}) { $field->{label} =~ s/^[\n\s\t\r]+//g; $field->{label} =~ s/[\n\s\t\r]+$//g; $field->{label} =~ s/[\n\s\t\r]+/ /g; } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::Label - Label Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { user_ssn => { label => 'User Social Security Number' } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::Label is a core validation class field directive that holds a user-friendly string (name) representing the associated field. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Email.pm100644000765000024 375114410403624 25032 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: Email Directive for Validation Class Field Definitions package Validation::Class::Directive::Email; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 0; has 'message' => '%s requires a valid email address'; sub validate { my ($self, $proto, $field, $param) = @_; if (defined $field->{email} && defined $param) { if ($field->{required} || $param) { my $ere = qr/^[a-z0-9!#$%&\'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&\'*+\/=?^_`{|}~-]+)*@(?:[-_a-z0-9][-_a-z0-9]*\.)*(?:[a-z0-9][-a-z0-9]{0,62})\.(?:(?:[a-z]{2}\.)?[a-z]{2,4}|museum|travel)$/; $self->error($proto, $field) unless $param =~ $ere; } } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::Email - Email Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { user_email => { email => 1 } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::Email is a core validation class field directive that checks the validity of email addresses specified by the associated parameters. Please note, the email directive does not perform a host lookup nor does it conform to the RFC specification. For more sophisticated email validation, please use custom validation with L or similar. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Value.pm100644000765000024 370614410403624 25057 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: Value Directive for Validation Class Field Definitions package Validation::Class::Directive::Value; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 1; # ensure most core directives execute before this one has 'dependencies' => sub {{ normalization => [qw( default )], validation => [qw( alias between depends_on error errors filtering filters label length matches max_alpha max_digits max_length max_sum min_alpha min_digits min_length min_sum mixin mixin_field multiples name options pattern readonly required toggle )] }}; sub after_validation { my ($self, $proto, $field, $param) = @_; # set the field value $field->{value} = $param || ''; return $self; } sub before_validation { my ($self, $proto, $field, $param) = @_; # set the field value $field->{value} = $param || ''; return $self; } sub normalize { my ($self, $proto, $field, $param) = @_; # set the field value $field->{value} = $param || ''; return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::Value - Value Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 DESCRIPTION Validation::Class::Directive::Value is a core validation class field directive that holds the absolute value of the associated field. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut State.pm100644000765000024 655314410403624 25066 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: State Directive for Validation Class Field Definitions package Validation::Class::Directive::State; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 0; has 'message' => '%s is not a valid state'; has 'regexp' => sub {sprintf'^(%s)$',join'|',map{quotemeta}@{shift->states}}; has 'states' => sub {[ # u.s. states and territories 'Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey', 'New Mexico', 'New York', 'North Carolina', 'North Dakota', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island', 'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming', 'District of Columbia', 'Puerto Rico', 'Guam', 'American Samoa', 'U.S. Virgin Islands', 'Northern Mariana Islands', ]}; sub validate { my ($self, $proto, $field, $param) = @_; if (defined $field->{state} && defined $param) { if ($field->{required} || $param) { my $type = $field->{state}; my $lre = $self->regexp; my $sre = { 'abbr' => qr/^(A[LKSZRAEP]|C[AOT]|D[EC]|F[LM]|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEHINOPST]|N[CDEHJMVY]|O[HKR]|P[ARW]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$/i, 'long' => qr/$lre/i, }; my $is_valid = 0; $type = isa_arrayref($type) ? $type : $type == 1 ? [keys %$sre] : [$type]; for (@{$type}) { if ($param =~ $sre->{$_}) { $is_valid = 1; last; } } $self->error($proto, $field) unless $is_valid; } } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::State - State Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { address_state => { state => 1 } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::State is a core validation class field directive that handles state validation for states in the USA. States will be validated against a list of state (case-insensitive abbreviated and long) names. For example: ny, NY, New York, and new york will validate. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut 98-03-document-example-method-usages.t100644000765000024 253214410403624 24736 0ustar00christiaanstaff000000000000Validation-Class-7.900059/tuse utf8; use strict; use warnings; use Test::More; { package T; use Validation::Class; field name => { min_length => 2, max_length => 100 }; document user => { 'name.first' => 'name', 'name.last' => 'name' }; method set_user => { input_document => 'user', using => sub { $_[1] } }; package main; my $data = { name => { first => undef } }; my $class = eval { T->new }; ok "T" eq ref $class, "T instantiated"; ok $class->set_user($data), "T document (user) is valid; nothing required"; my $user = $class->proto->documents->get('user'); $user->{'name.first'} = '+name'; ok !$class->set_user($data) && $class->errors_to_string =~ /name\.first/, "T document (user) is NOT valid; name.first required"; $user->{'name.first'} = 'name'; $data->{name}->{first} = 'friendly'; $data->{name}->{middle} = 'guy'; is_deeply { name => { first => 'friendly', middle => 'guy', last => undef } }, $class->set_user($data), 'T document (user) is valid; return value expected' ; is_deeply { name => { first => 'friendly', last => undef } }, $class->set_user($data, { prune => 1 }), 'T document (user) is valid; pruned return value expected' ; } done_testing; 99-toggling-filters-during-execution.t100644000765000024 260714410403624 25257 0ustar00christiaanstaff000000000000Validation-Class-7.900059/tuse strict; use warnings; use Test::More; use Validation::Class::Simple; sub validate_ignoring_filters_1 { my ($validation, $hashref) = @_; $validation->params->clear; $validation->params->add(%$hashref); no warnings "redefine"; local *Validation::Class::Directive::Filters::execute_filtering = sub { $_[0] }; my $r = eval { $validation->validate }; return $r; } sub validate_ignoring_filters_2 { my ($validation, $hashref) = @_; $validation->filtering("off"); $validation->params->clear; $validation->params->add(%$hashref); my $r = eval { $validation->validate }; $validation->filtering("pre"); return $r; } my $vsimple = "Validation::Class::Simple"->new( fields => { name => { required => 1, pattern => qr{^\w+$}, filters => "trim" }, }, ); my $should_pass = { name => "foo" }; my $should_fail = { name => " foo " }; ok( validate_ignoring_filters_1($vsimple, $should_pass), 'validate_ignoring_filters_1($vsimple, $should_pass)', ); ok( !validate_ignoring_filters_1($vsimple, $should_fail), '!validate_ignoring_filters_1($vsimple, $should_fail)', ); ok( validate_ignoring_filters_2($vsimple, $should_pass), 'validate_ignoring_filters_2($vsimple, $should_pass)', ); ok( !validate_ignoring_filters_2($vsimple, $should_fail), '!validate_ignoring_filters_2($vsimple, $should_fail)', ); done_testing; 03-decimal.t100644000765000024 76214410403624 25143 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/filtersuse Test::More tests => 2; # load module package MyVal; use Validation::Class; package main; my $v = MyVal->new( fields => {foobar => {filters => 'decimal'}}, params => {foobar => '$2000.99'} ); ok $v->params->{foobar} =~ /^2000\.99$/, 'decimal filter working as expected'; $v = MyVal->new( fields => {foobar => {filters => 'decimal'}}, params => {foobar => '- $2000.99'} ); ok $v->params->{foobar} =~ /^-2000\.99$/, 'decimal filter working with negative number as expected'; 05-numeric.t100644000765000024 134114410403624 25223 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/filtersuse Test::More tests => 3; # load module package MyVal; use Validation::Class; package main; my $v = MyVal->new( fields => {foobar => {filters => 'numeric'}}, params => {foobar => '123abc456def'} ); ok $v->params->{foobar} =~ /^123456$/, 'numeric filter working as expected'; $v = MyVal->new( fields => {foobar => {filters => 'numeric'}}, params => {foobar => '---- 123abc456def'} ); ok $v->params->{foobar} =~ /^-123456$/, 'numeric filter working with negative number as expected'; $v = MyVal->new( fields => {foobar => {filters => 'numeric'}}, params => {foobar => ' - ---- 123abc456def'} ); ok $v->params->{foobar} =~ /^-123456$/, 'numeric filter working with negative number as expected'; 22-city.t100644000765000024 167014410403624 25235 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/validatorsuse Test::More; package main; use utf8; use Validation::Class::Simple; my $r = Validation::Class::Simple->new(fields => {city => {city => 1}}); # failures $r->params->{city} = 'bumfuck'; ok !$r->validate(), 'bumfuck is invalid'; $r->params->{city} = 'prison'; ok !$r->validate(), 'prison is invalid'; $r->params->{city} = 'st louis'; ok !$r->validate(), 'st louis is invalid'; # successes $r->params->{city} = 'new york'; ok $r->validate(), 'new york is valid'; $r->params->{city} = 'st. louis'; ok $r->validate(), 'st. louis is valid'; $r->params->{city} = 'atlanta'; ok $r->validate(), 'atlanta is valid'; $r->params->{city} = 'philadelphia'; ok $r->validate(), 'philadelphia is valid'; $r->params->{city} = 'santa monica'; ok $r->validate(), 'santa monica is valid'; $r->params->{city} = 'baltimore'; ok $r->validate(), 'baltimore is valid'; $r->params->{city} = 'santa bárbara'; ok $r->validate(), 'santa bárbara is valid'; done_testing; 22-time.t100644000765000024 177314410403624 25227 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/validatorsuse Test::More; package main; use utf8; use Validation::Class::Simple; my $s = Validation::Class::Simple->new( fields => { scheduled_time => {time => 1} } ); sub should_fail { my ($name, @times) = @_; for (@times) { $s->params->{$name} = $_; ok !$s->validate($name), "$_ is an invalid $name param"; } } sub should_pass { my ($name, @times) = @_; for (@times) { $s->params->{$name} = $_; ok $s->validate($name), "$_ is a valid $name param"; } } # failures diag 'validating bad times'; should_fail 'scheduled_time' => qw( aa AA ab Ab 25 30 -14 3000 24 2499 2399 2360 4321 3:000 30:00 :23 23: 24:99 23:99 23:60 43:21 ); diag 'validating good times'; should_pass 'scheduled_time' => ( '23:59', '00', '00:00', '11:11', '12:34', '11:11 am', '11:11 AM', '11:11AM', '11:11PM', '11:11 PM', '11:11 pm', ); done_testing; 22-uuid.t100644000765000024 162314410403624 25231 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/validatorsuse Test::More; package main; use utf8; use Validation::Class::Simple; my $s = Validation::Class::Simple->new( fields => { user_uuid => {uuid => 1} } ); sub should_fail { my ($name, @ids) = @_; for (@ids) { $s->params->{$name} = $_; ok !$s->validate($name), "$_ is an invalid $name param"; } } sub should_pass { my ($name, @ids) = @_; for (@ids) { $s->params->{$name} = $_; ok $s->validate($name), "$_ is a valid $name param"; } } # failures diag 'validating bad uuids'; should_fail 'user_uuid' => qw( 0000A0000AA000B0B00AA00AAA0BB000 00000000-0000-0000-0000 0000-0000-0000-000000000000 00000000-0000-000000000000 ); diag 'validating good uuids'; should_pass 'user_uuid' => qw( 00000000-0000-0000-0000-000000000000 4162F712-1DD2-11B2-B17E-C09EFE1DC403 4162F712-1DD2-11B2-B17E-C09EFE1DC403 ); done_testing; 22-date.t100644000765000024 135014410403624 25175 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/validatorsuse Test::More; package main; use utf8; use Validation::Class::Simple; my $s = Validation::Class::Simple->new( fields => { date_created => {date => 'mdy'} } ); sub should_fail { my ($name, @dates) = @_; for (@dates) { $s->params->{$name} = $_; ok !$s->validate($name), "$_ is an invalid $name param"; } } sub should_pass { my ($name, @dates) = @_; for (@dates) { $s->params->{$name} = $_; ok $s->validate($name), "$_ is a valid $name param"; } } # failures diag 'validating bad dates'; should_fail 'date_created' => qw( 00/00/0000 11/11/1111 123456 ); diag 'validating good dates'; should_pass 'date_created' => qw( 01/01/1980 12/29/2020 ); done_testing; Toggle.pm100644000765000024 414214410403624 25217 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: Toggle Directive for Validation Class Field Definitions package Validation::Class::Directive::Toggle; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 0; has 'field' => 1; has 'multi' => 0; sub before_validation { my ($self, $proto, $field, $param) = @_; if (defined $field->{toggle}) { my $stash = $proto->stash->{'directive.toggle'} ||= {}; # to be restored after validation $stash->{$field->{name}}->{'required'} = defined $field->{required} ? $field->{required} == 0 ? 0 : 1 : 0; $field->{required} = 1 if ($field->{toggle} =~ /^(\+|1)$/); $field->{required} = 0 if ($field->{toggle} =~ /^(\-|0)$/); } return $self; } sub after_validation { my ($self, $proto, $field, $param) = @_; if (defined $field->{toggle}) { my $stash = $proto->stash->{'directive.toggle'} ||= {}; if (defined $stash->{$field->{name}}->{'required'}) { # restore field state from stash after validation $field->{required} = $stash->{$field->{name}}->{'required'}; delete $stash->{$field->{name}}; } } delete $field->{toggle} if exists $field->{toggle}; return $self; } sub normalize { my ($self, $proto, $field, $param) = @_; # on normalize, always remove the toggle directive delete $field->{toggle} if exists $field->{toggle}; return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::Toggle - Toggle Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 DESCRIPTION Validation::Class::Directive::Toggle is a core validation class field directive that is used internally to handle validation of per-validation-event requirements. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Length.pm100644000765000024 324514410403624 25222 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: Length Directive for Validation Class Field Definitions package Validation::Class::Directive::Length; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 0; has 'message' => '%s should be exactly %s characters'; sub validate { my $self = shift; my ($proto, $field, $param) = @_; if (defined $field->{length} && defined $param) { my $length = $field->{length}; if ($field->{required} || $param) { unless (length($param) == $length) { $self->error(@_, $length); } } } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::Length - Length Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { security_pin => { length => 4 } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::Length is a core validation class field directive that validates the exact length of the associated parameters. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut MinSum.pm100644000765000024 325414410403624 25211 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: MinSum Directive for Validation Class Field Definitions package Validation::Class::Directive::MinSum; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 0; has 'message' => '%s must be greater than %s'; sub validate { my $self = shift; my ($proto, $field, $param) = @_; if (defined $field->{min_sum} && defined $param) { my $min_sum = $field->{min_sum}; if ( $field->{required} || $param ) { if (int($param) < int($min_sum)) { $self->error(@_, $min_sum); } } } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::MinSum - MinSum Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { invoice_total => { min_sum => 1 } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::MinSum is a core validation class field directive that validates the numeric value of the associated parameters. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut MaxSum.pm100644000765000024 325514410403624 25214 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: MaxSum Directive for Validation Class Field Definitions package Validation::Class::Directive::MaxSum; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 0; has 'message' => '%s must be less than %s'; sub validate { my $self = shift; my ($proto, $field, $param) = @_; if (defined $field->{max_sum} && defined $param) { my $max_sum = $field->{max_sum}; if ( $field->{required} || $param ) { if (int($param) > int($max_sum)) { $self->error(@_, $max_sum); } } } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::MaxSum - MaxSum Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { invoice_total => { max_sum => 10000 } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::MaxSum is a core validation class field directive that validates the numeric value of the associated parameters. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Errors.pm100644000765000024 167414410403624 25261 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: Errors Directive for Validation Class Field Definitions package Validation::Class::Directive::Errors; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 0; has 'field' => 1; has 'multi' => 0; 1; __END__ =pod =head1 NAME Validation::Class::Directive::Errors - Errors Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 DESCRIPTION Validation::Class::Directive::Errors is a core validation class field directive that holds error message registered at the field-level for the associated field. This directive is used internally. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut 11-group-validation.t100644000765000024 431314410403624 25374 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regressionuse Test::More tests => 21; package MyVal; use Validation::Class; package main; my $v = MyVal->new( fields => { 'user.login' => {error => 'login error'}, 'user.password' => { error => 'password error', min_length => 3, max_length => 9, pattern => 'XXX######' } }, params => { 'user.login' => 'member', 'user.password' => 'abc123456' } ); ok $v, 'class initialized'; ok defined $v->fields->{'user.login'}, 'login field exists'; ok defined $v->params->{'user.login'}, 'login param exists'; # check min_length directive $v->fields->{'user.login'}->{min_length} = 10; ok !$v->validate('user.login'), 'error found as expected'; ok !$v->validate, 'alternate use of validation found error also'; ok $v->error_count == 1, 'error count is correct'; ok $v->errors_to_string eq 'login error', 'error message specified captured'; $v->fields->{'user.login'}->{min_length} = 5; ok $v->validate('user.login'), 'user.login rule validates'; ok $v->validate, 'alternate use of validation validates'; ok $v->error_count == 0, 'error count is zero'; ok $v->errors_to_string eq '', 'no error messages found'; # check max_length directive $v->fields->{'user.login'}->{max_length} = 5; ok !$v->validate('user.login'), 'error found as expected'; ok !$v->validate, 'alternate use of validation found error also'; ok $v->error_count == 1, 'error count is correct'; ok $v->errors_to_string eq 'login error', 'error message specified captured'; $v->fields->{'user.login'}->{max_length} = 9; ok $v->validate('user.login'), 'user.login rule validates'; ok $v->validate, 'alternate use of validation validates'; ok $v->error_count == 0, 'error count is zero'; ok $v->errors_to_string eq '', 'no error messages found'; # grouped fields perform like normal fields, now testing validation and # extraction routines # my $obj = $v->unflatten_params(); - DEPRECATED my $obj = $v->proto->unflatten_params($v->proto->params->hash); ok defined $obj->{user}->{login} && $obj->{user}->{login}, 'unflatten_params has user hash with login key'; ok defined $obj->{user}->{password} && $obj->{user}->{password}, 'unflatten_params has user hash with password key'; 17-pattern-matching.t100644000765000024 73614410403624 25350 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regressionuse Test::More tests => 3; package MyVal; use Validation::Class; field email => {required => 1}; field email1 => {required => 1}; field email2 => {required => 1}; field email3 => {required => 1}; package main; my $v = MyVal->new( params => { email => 1, email1 => 1, email2 => 1, email3 => 1 } ); ok $v, 'initialization successful'; ok $v->validate(qr/email(\d+)?/), 'validation passed'; ok $v->error_count == 0, 'validation ok'; 03-currency.t100644000765000024 102114410403624 25404 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/filtersuse Test::More tests => 2; # load module package MyVal; use Validation::Class; package main; my $v = MyVal->new( fields => {foobar => {filters => 'currency'}}, params => {foobar => '$2,000,000.99'} ); ok $v->params->{foobar} =~ /^2,000,000\.99$/, 'currency filter working as expected'; $v = MyVal->new( fields => {foobar => {filters => 'currency'}}, params => {foobar => ' -- - - $ 2,000,000.99'} ); ok $v->params->{foobar} =~ /^-2,000,000\.99$/, 'currency filter working with negative number as expected'; 22-state.t100644000765000024 232714410403624 25405 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/validatorsuse Test::More; package main; use utf8; use Validation::Class::Simple; my $s = Validation::Class::Simple->new( fields => { address_state => {state => 1} } ); sub should_fail { my ($name, @states) = @_; for (@states) { $s->params->{$name} = $_; ok !$s->validate($name), "$_ is an invalid $name param"; } } sub should_pass { my ($name, @states) = @_; for (@states) { $s->params->{$name} = $_; ok $s->validate($name), "$_ is a valid $name param"; } } # failures diag 'validating bad states'; should_fail 'address_state' => qw( zz xx XX a w do fu FU F.U. prison nowhere jail hole heaven hell PURGATORY Goergia goergia ); diag 'validating good states'; should_pass 'address_state' => ( 'VA', 'va', 'PA', 'pa', 'GA', 'ga', 'CA', 'ca', 'MA', 'ma', 'VIRGINIA', 'Virginia', 'virginia', 'Pennsylvania', 'pennsylvania', 'Georgia', 'georgia', 'California', 'california', 'Massachusetts', 'massachusetts', 'DC', 'District of Columbia', 'Washington', 'washington', 'WASHINGTON' ); done_testing; 22-email.t100644000765000024 176214410403624 25356 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/validatorsuse Test::More; package main; use utf8; use Validation::Class::Simple; my $s = Validation::Class::Simple->new( fields => { email_address => {email => 1} } ); sub should_fail { my ($name, @emails) = @_; for (@emails) { $s->params->{$name} = $_; ok !$s->validate($name), "$_ is an invalid $name param"; } } sub should_pass { my ($name, @emails) = @_; for (@emails) { $s->params->{$name} = $_; ok $s->validate($name), "$_ is a valid $name param"; } } # failures diag 'validating bad emails'; should_fail 'email_address' => ( 'Abc.example.com', 'Abc.@example.com', 'Abc..123@example.com', 'A@b@c@example.com', 'a"b(c)d,e:f;gi[j\k]l@example.com', 'just"not"right@example.com', 'this#is"not\allowed@example.com', 'this is"not\allowed@example.com', 'this\ still\"not\\allowed@example.com', ); diag 'validating good emails'; should_pass 'email_address' => qw( awncorp@cpan.org ); done_testing; MyVal000755000765000024 014410403624 24043 5ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/modulesTemp.pm100644000765000024 36514410403624 25432 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/modules/MyValpackage MyVal::Temp; use Validation::Class; load { base => [ 'MyVal::Person' ] }; field login => { mixin => 'TMP', label => 'Staff login' }; field password => { mixin => 'TMP', label => 'Staff password' }; 1;Matches.pm100644000765000024 520614410403624 25364 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: Matches Directive for Validation Class Field Definitions package Validation::Class::Directive::Matches; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 1; has 'message' => '%s does not match %s'; sub validate { my $self = shift; my ($proto, $field, $param) = @_; if (defined $field->{matches} && defined $param) { my $specification = $field->{matches}; if ($field->{required} || $param) { my $dependents = isa_arrayref($specification) ? $specification : [$specification] ; if (@{$dependents}) { my @required_fields = (); foreach my $dependent (@{$dependents}) { $param ||= ''; my $field = $proto->fields->get($dependent); my $param2 = $proto->params->get($dependent) || ''; push @required_fields, $field->label || $field->name unless $param eq $param2 ; } if (my @r = @required_fields) { my$list=(join(' and ',join(', ',@r[0..$#r-1])||(),$r[-1])); $self->error(@_, $list); } } } } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::Matches - Matches Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { password => { matches => 'password2' } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::Matches is a core validation class field directive that validates whether the value of the dependent parameters matches that of the associated field. =over 8 =item * alternative argument: an-array-of-parameter-names This directive can be passed a single value or an array of values: fields => { password => { matches => ['password2', 'password3'] } } =back =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Options.pm100644000765000024 624514410403624 25437 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: Options Directive for Validation Class Field Definitions package Validation::Class::Directive::Options; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 0; has 'message' => '%s must be either %s'; sub validate { my $self = shift; my ($proto, $field, $param) = @_; if (defined $field->{options} && defined $param) { my $options = $field->{options}; if ( $field->{required} || $param ) { my (@options) = isa_arrayref($options) ? @{$options} : split /(?:\s{1,})?[,\-]{1,}(?:\s{1,})?/, $options ; foreach my $option (@options) { if ($option =~ /^([^\|]+)\|(.*)/) { $option = $0; } elsif (isa_arrayref($option)) { $option = $option->[0]; } } unless (grep { $param eq $_ } @options) { if (my @o = @options) { my$list=(join(' or ',join(', ',@o[0..$#o-1])||(),$o[-1])); $self->error(@_, $list); } } } } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::Options - Options Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { user_role => { options => 'Client' } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::Options is a core validation class field directive that holds an enumerated list of values to be validated against the associated parameters. =over 8 =item * alternative argument: an-array-of-user-defined-options This directive can be passed a single value or an array of values: fields => { user_role => { options => ['Client', 'Employee', 'Administrator'] } } # the following examples are useful for plugins (and other code) # that may want to otherwise identify option values fields => { user_role => { options => [ '1|Client', '2|Employee', '3|Administrator' ] } } # please note: # declaring options as "keyed-options" will cause the validation of # the option's key and NOT the option's value fields => { user_role => { options => [ [ 1 => 'Client' ], [ 2 => 'Employee' ], [ 3 => 'Administrator' ] ] } } =back =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Pattern.pm100644000765000024 446614410403624 25424 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: Pattern Directive for Validation Class Field Definitions package Validation::Class::Directive::Pattern; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 0; has 'message' => '%s is not formatted properly'; sub validate { my ($self, $proto, $field, $param) = @_; if (defined $field->{pattern} && defined $param) { my $pattern = $field->{pattern}; if ($field->{required} || $param) { unless ( isa_regexp($pattern) ) { $pattern =~ s/([^#X ])/\\$1/g; $pattern =~ s/#/\\d/g; $pattern =~ s/X/[a-zA-Z]/g; $pattern = qr/$pattern/; } unless ( $param =~ $pattern ) { $self->error($proto, $field); } } } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::Pattern - Pattern Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { company_email => { pattern => qr/\@company\.com$/ } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::Pattern is a core validation class field directive that validates simple patterns and complex regular expressions. =over 8 =item * alternative argument: an-array-of-something This directive can be passed a regexp object or a simple pattern. A simple pattern is a string where the `#` character matches digits and the `X` character matches alphabetic characters. fields => { task_date => { pattern => '##-##-####' }, task_time => { pattern => '##:##:##' } } =back =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Decimal.pm100644000765000024 557514410403624 25347 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: Decimal Directive for Validation Class Field Definitions package Validation::Class::Directive::Decimal; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 0; has 'message' => '%s requires a valid decimal number'; sub validate { my ($self, $proto, $field, $param) = @_; if (defined $field->{decimal} && defined $param) { # checks for a valid decimal. Both the sign and exponent are optional # 0 => Any number of decimal places, including none # 1 => Any number of decimal places greater than 0, or a float|double # 2 => Exactly that many number of decimal places if ($field->{required} || $param) { my $type = $field->{decimal}; my $lnum = '[0-9]+'; my $dnum = "[0-9]*[\.]${lnum}"; my $sign = '[+-]?'; my $exp = "(?:[eE]${sign}${lnum})?"; my $dre; if ($type == 0) { $dre = qr/^${sign}(?:${lnum}|${dnum})${exp}$/; } elsif ($type == 1) { $dre = qr/^${sign}${dnum}${exp}$/; } else { $type = "[0-9]\{${type}}"; $dnum = "(?:[0-9]*[\.]${type}|${lnum}[\.]${type})"; $dre = qr/^${sign}${dnum}${exp}$/; } $self->error($proto, $field) unless $param =~ $dre; } } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::Decimal - Decimal Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { amount_paid => { decimal => 1 } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::Decimal is a core validation class field directive that provides validation of floating point integers. =over 8 =item * alternative argument: a-single-variable-value =item * option: 0 e.g. Any number of decimal places, including none =item * option: 1 e.g. Any number of decimal places greater than 0, or a float|double =item * option: $n e.g. Exactly that many number of decimal places This directive can be passed a single value only: fields => { amount_paid => { decimal => 2 # 2 decimal places } } =back =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Default.pm100644000765000024 503614410403624 25365 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: Default Directive for Validation Class Field Definitions package Validation::Class::Directive::Default; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 1; has 'dependencies' => sub {{ normalization => ['filters', 'readonly'], # note: default-values are only handled during normalization now # validation => ['multiples', 'value'] }}; sub normalize { my ($self, $proto, $field, $param) = @_; # override parameter value if default exists if (defined $field->{default} && ! defined $param) { my @defaults = isa_arrayref($field->{default}) ? @{$field->{default}} : ($field->{default}) ; my $context = $proto->stash->{'normalization.context'}; my $name = $field->name; foreach my $default (@defaults) { $default = $default->($context, $proto) if isa_coderef($default); } $proto->params->add($name, @defaults == 1 ? $defaults[0] : [@defaults]); } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::Default - Default Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { access_code => { default => 'demo123' } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::Default is a core validation class field directive that holds the value which should be used if no parameter is supplied. =over 8 =item * alternative argument: a-coderef-returning-a-default-value This directive can be passed a single value or a coderef which should return the value to be used as the default value: fields => { access_code => { default => sub { my $self = shift; # this coderef will receive a context object return join '::', lc __PACKAGE__, time(); } } } =back =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Between.pm100644000765000024 446714410403624 25401 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: Between Directive for Validation Class Field Definitions package Validation::Class::Directive::Between; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 1; has 'message' => '%s must be between %s'; sub validate { my $self = shift; my ($proto, $field, $param) = @_; if (defined $field->{between} && defined $param) { my $between = $field->{between}; if ( $field->{required} || $param ) { my ( $min, $max ) = isa_arrayref($between) ? @{$between} > 1 ? @{$between} : (split /(?:\s{1,})?\D{1,}(?:\s{1,})?/, $between->[0]) : (split /(?:\s{1,})?\D{1,}(?:\s{1,})?/, $between); $min = scalar($min); $max = scalar($max); # warn $min, ',', $max, ',', $param; unless ( $param >= $min && $param <= $max ) { $self->error(@_, "$min-$max"); } } } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::Between - Between Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { person_age => { between => '18-95' } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::Between is a core validation class field directive that provides the ability to validate the numeric range of the associated parameters. =over 8 =item * alternative argument: an-array-of-numbers This directive can be passed a single value or an array of values: fields => { person_age => { between => [18, 95] } } =back =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Zipcode.pm100644000765000024 322114410403624 25370 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: Zipcode Directive for Validation Class Field Definitions package Validation::Class::Directive::Zipcode; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 0; has 'message' => '%s is not a valid postal code'; sub validate { my ($self, $proto, $field, $param) = @_; if (defined $field->{zipcode} && defined $param) { if ($field->{required} || $param) { my $zcre = qr/\A\b[0-9]{5}(?:-[0-9]{4})?\b\z/i; $self->error($proto, $field) unless $param =~ $zcre; } } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::Zipcode - Zipcode Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { address_zipcode => { zipcode => 1 } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::Zipcode is a core validation class field directive that handles postal-code validation for areas in the USA and North America. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Filters.pm100644000765000024 1354014410403624 25430 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: Filters Directive for Validation Class Field Definitions package Validation::Class::Directive::Filters; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION our $_registry = { alpha => \&filter_alpha, alphanumeric => \&filter_alphanumeric, autocase => \&filter_autocase, capitalize => \&filter_capitalize, currency => \&filter_currency, decimal => \&filter_decimal, lowercase => \&filter_lowercase, numeric => \&filter_numeric, strip => \&filter_strip, titlecase => \&filter_titlecase, trim => \&filter_trim, uppercase => \&filter_uppercase }; sub registry { return $_registry; } sub filter_alpha { $_[0] =~ s/[^A-Za-z]//g; return $_[0]; } sub filter_alphanumeric { $_[0] =~ s/[^A-Za-z0-9]//g; return $_[0]; } sub filter_autocase { $_[0] =~ s/(^[a-z]|\b[a-z])/\u$1/g; return $_[0]; } sub filter_capitalize { $_[0] = ucfirst $_[0]; $_[0] =~ s/\.\s+([a-z])/\. \U$1/g; return $_[0]; } sub filter_currency { my $n = $_[0] =~ /^(?:[^\d\-]+)?([\-])/ ? 1 : 0; $_[0] =~ s/[^0-9\.\,]+//g; return $n ? "-$_[0]" : "$_[0]"; } sub filter_decimal { my $n = $_[0] =~ /^(?:[^\d\-]+)?([\-])/ ? 1 : 0; $_[0] =~ s/[^0-9\.]+//g; return $n ? "-$_[0]" : "$_[0]"; } sub filter_lowercase { return lc $_[0]; } sub filter_numeric { my $n = $_[0] =~ /^(?:[^\d\-]+)?([\-])/ ? 1 : 0; $_[0] =~ s/[^0-9]+//g; return $n ? "-$_[0]" : "$_[0]"; } sub filter_strip { $_[0] =~ s/\s+/ /g; $_[0] =~ s/^\s+//; $_[0] =~ s/\s+$//; return $_[0]; } sub filter_titlecase { return join( " ", map { ucfirst $_ } (split( /\s/, lc $_[0] )) ); } sub filter_trim { $_[0] =~ s/^\s+//g; $_[0] =~ s/\s+$//g; return $_[0]; } sub filter_uppercase { return uc $_[0]; } has 'mixin' => 1; has 'field' => 1; has 'multi' => 1; has 'dependencies' => sub {{ normalization => ['filtering'], validation => [] }}; sub after_validation { my ($self, $proto, $field, $param) = @_; if ($proto->validated == 2) { $self->execute_filtering($proto, $field, $param, 'post'); } return $self; } sub before_validation { my ($self, $proto, $field, $param) = @_; $self->execute_filtering($proto, $field, $param, 'pre'); return $self; } sub normalize { my ($self, $proto, $field, $param) = @_; # by default fields should have a filters directive # unless already specified if (! defined $field->{filters}) { $field->{filters} = []; } # run any existing filters on instantiation # if the field is set to pre-filter else { $self->execute_filtering($proto, $field, $param, 'pre'); } return $self; } sub execute_filtering { my ($self, $proto, $field, $param, $state) = @_; return unless $state && ($proto->filtering eq 'pre' || $proto->filtering eq 'post') && defined $field->{filters} && defined $field->{filtering} && defined $param ; my $filtering = $field->{filtering}; $field->{filtering} = $proto->filtering unless defined $field->{filtering}; if ($field->{filtering} eq $state && $state ne 'off') { my @filters = isa_arrayref($field->{filters}) ? @{$field->{filters}} : ($field->{filters}); my $values = $param; foreach my $value (isa_arrayref($param) ? @{$param} : ($param)) { next if ! $value; foreach my $filter (@filters) { $filter = $proto->filters->get($filter) unless isa_coderef($filter); next if ! $filter; $value = $filter->($value); } } my $name = $field->name; $proto->params->add($name, $param); } $field->{filtering} = $filtering; return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::Filters - Filters Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { user_ident => { filters => 'trim' } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::Filters is a core validation class field directive that specifies which filter should be executed on the associated field. =over 8 =item * alternative argument: an-array-of-options =item * option: trim e.g. remove leading/trailing spaces =item * option: strip e.g. replace multiple spaces with one space =item * option: lowercase e.g. convert to lowercase =item * option: uppercase e.g. convert to uppercase =item * option: titlecase e.g. uppercase first letter of each word; all else lowercase =item * option: autocase e.g. uppercase first letter of each word =item * option: capitalize e.g. uppercase the first letter =item * option: alphanumeric e.g. remove non-any alphanumeric characters =item * option: numeric e.g. remove any non-numeric characters =item * option: alpha e.g. remove any non-alpha characters =item * option: decimal e.g. preserve only numeric, dot and comma characters This directive can be passed a single value or an array of values: fields => { user_ident => { filters => ['trim', 'strip'] } } =back =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut 97-persistent-values.t100644000765000024 274214410403624 25627 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regressionuse Test::More tests => 6; package MyVal; use Validation::Class; field this => { required => 1, error => 'This aint that.', filters => ['trim', 'strip'] }; field that => { required => 1, error => 'That aint this.', filters => ['trim', 'strip'] }; sub my_fields { my $fields = { this => { required => 1, error => 'This aint that.', filters => ['trim', 'strip'] }, that => { required => 1, error => 'That aint this.', filters => ['trim', 'strip'] } }; return $fields; } my $first_params = { this => '0123456789', that => '' }; my $second_params = { this => '', that => '' }; package main; my $v1 = MyVal->new( #fields => my_fields, params => $first_params, ignore_unknown => 1 ); # validation objects ok $v1, '1st validation object ok'; $v1->validate(qw/this that/); ok $v1->fields->{this}->{value} eq '0123456789', '1st validation object -this- field value correct'; my $v2 = MyVal->new( #fields => my_fields, params => $second_params, ignore_unknown => 1 ); ok $v2, '2nd validation object ok'; $v2->validate(qw/this that/); ok $v2->fields->{this}->{value} eq '', '2nd validation object -this- field value correct'; ok !$v2->params->{this}, '2nd validation object -this- param correct'; ok !$v2->fields->{this}->{value}, '2nd validation object -this- field value correct'; 10-custom-validation.t100644000765000024 132014410403624 25544 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regressionuse Test::More tests => 5; package MyVal; use Validation::Class; package main; my $v = MyVal->new( fields => { foobar => { error => 'foobar error', validation => sub { shift->{_ran_}++; return 1; } }, barfoo => { required => 1, validation => sub { return 0; } } }, params => { foobar => 'abc123456', barfoo => 1 } ); ok $v, 'class initialized'; ok $v->validate('foobar'), 'valid'; ok $v->{_ran_} == 1, 'validation ran once as intended'; ok !$v->validate('barfoo'), 'not valid'; ok $v->errors_to_string, 'error message'; 06-uppercase.t100644000765000024 45414410403624 25535 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/filtersuse Test::More tests => 1; # load module package MyVal; use Validation::Class; package main; my $v = MyVal->new( fields => {foobar => {filters => 'uppercase'}}, params => {foobar => '123abc456def'} ); ok $v->params->{foobar} =~ /^123ABC456DEF$/, 'uppercase filter working as expected'; 08-titlecase.t100644000765000024 46314410403624 25525 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/filtersuse Test::More tests => 1; # load module package MyVal; use Validation::Class; package main; my $v = MyVal->new( fields => {foobar => {filters => 'titlecase'}}, params => {foobar => 'mr. frank white'} ); ok $v->params->{foobar} =~ /^Mr\. Frank White$/, 'titlecase filter working as expected'; 07-lowercase.t100644000765000024 45414410403624 25533 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/filtersuse Test::More tests => 1; # load module package MyVal; use Validation::Class; package main; my $v = MyVal->new( fields => {foobar => {filters => 'lowercase'}}, params => {foobar => '123ABC456DEF'} ); ok $v->params->{foobar} =~ /^123abc456def$/, 'lowercase filter working as expected'; 05-length.t100644000765000024 117614410403624 25550 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/validatorsuse Test::More tests => 5; package MyVal; use Validation::Class; package main; my $r = MyVal->new( fields => {foobar => {length => '1'}}, params => {foobar => 'a'} ); ok $r->validate(), 'foobar validates'; $r->params->{foobar} = 'abc'; ok !$r->validate(), 'foobar doesnt validate'; ok $r->errors_to_string() =~ /should be exactly 1 characters/, 'displays proper error message'; $r->params->{foobar} = 'a'; $r->fields->{foobar}->{length} = 2; ok !$r->validate(), 'foobar doesnt validate'; ok $r->errors_to_string() =~ /should be exactly 2 characters/, 'displays proper error message'; #warn $r->errors_to_string(); Staff.pm100644000765000024 27714410403624 25572 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/modules/MyValpackage MyVal::Staff; use Validation::Class; field login => { mixin => 'TMP', label => 'Staff login' }; field password => { mixin => 'TMP', label => 'Staff password' }; 1;Readonly.pm100644000765000024 313314410403624 25552 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: Readonly Directive for Validation Class Field Definitions package Validation::Class::Directive::Readonly; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 0; has 'field' => 1; has 'multi' => 0; sub normalize { my ($self, $proto, $field) = @_; # respect readonly fields if (defined $field->{readonly}) { my $name = $field->name; # probably shouldn't be deleting the submitted parameters !!! delete $proto->params->{$name} if exists $proto->params->{$name}; } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::Readonly - Readonly Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { task_completed => { readonly => 1 } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::Readonly is a core validation class field directive that determines whether the associated parameters should be ignored. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Required.pm100644000765000024 372014410403624 25557 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: Required Directive for Validation Class Field Definitions package Validation::Class::Directive::Required; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 0; has 'message' => '%s is required'; has 'dependencies' => sub {{ normalization => [], validation => ['alias', 'toggle'] }}; sub before_validation { my ($self, $proto, $field, $param) = @_; if (defined $field->{required}) { if ($field->{required} && (! defined $param || $param eq '')) { $self->error($proto, $field); $proto->stash->{'validation.bypass_event'}++ unless $proto->ignore_intervention; } } return $self; } sub normalize { my ($self, $proto, $field, $param) = @_; # by default, field validation is optional $field->{required} = 0 unless defined $field->{required}; return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::Required - Required Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { search_query => { required => 1 } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::Required is a core validation class field directive that handles validation of supply and demand. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut MinAlpha.pm100644000765000024 341314410403624 25467 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: MinAlpha Directive for Validation Class Field Definitions package Validation::Class::Directive::MinAlpha; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 0; has 'message' => '%s must not contain less than %s alphabetic characters'; sub validate { my $self = shift; my ($proto, $field, $param) = @_; if (defined $field->{min_alpha} && defined $param) { my $min_alpha = $field->{min_alpha}; if ( $field->{required} || $param ) { my @i = ($param =~ /[a-zA-Z]/g); if (@i < $min_alpha) { $self->error(@_, $min_alpha); } } } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::MinAlpha - MinAlpha Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { password => { min_alpha => 1 } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::MinAlpha is a core validation class field directive that validates the length of alphabetic characters in the associated parameters. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut MaxAlpha.pm100644000765000024 341414410403624 25472 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: MaxAlpha Directive for Validation Class Field Definitions package Validation::Class::Directive::MaxAlpha; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 0; has 'message' => '%s must not contain more than %s alphabetic characters'; sub validate { my $self = shift; my ($proto, $field, $param) = @_; if (defined $field->{max_alpha} && defined $param) { my $max_alpha = $field->{max_alpha}; if ( $field->{required} || $param ) { my @i = ($param =~ /[a-zA-Z]/g); if (@i > $max_alpha) { $self->error(@_, $max_alpha); } } } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::MaxAlpha - MaxAlpha Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { password => { max_alpha => 12 } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::MaxAlpha is a core validation class field directive that validates the length of alphabetic characters in the associated parameters. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Messages.pm100644000765000024 276414410403624 25555 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: Messages Directive for Validation Class Field Definitions package Validation::Class::Directive::Messages; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 0; 1; __END__ =pod =head1 NAME Validation::Class::Directive::Messages - Messages Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { username => { required => 1, min_length => 5, messages => { required => '%s is mandatory', min_length => '%s is not the correct length' } } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::Messages is a core validation class field directive that holds error message which will supersede the default error messages of the associated directives. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Hostname.pm100644000765000024 330114410403624 25550 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: Hostname Directive for Validation Class Field Definitions package Validation::Class::Directive::Hostname; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 0; has 'message' => '%s requires a valid hostname'; sub validate { my ($self, $proto, $field, $param) = @_; if (defined $field->{hostname} && defined $param) { if ($field->{required} || $param) { my $hnre = qr/^(?:[-_a-z0-9][-_a-z0-9]*\.)*(?:[a-z0-9][-a-z0-9]{0,62})\.(?:(?:[a-z]{2}\.)?[a-z]{2,4}|museum|travel)$/; $self->error($proto, $field) unless $param =~ $hnre; } } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::Hostname - Hostname Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { company_domain => { hostname => 1 } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::Hostname is a core validation class field directive that handles validatation of server hostnames. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Base000755000765000024 014410403624 23676 5ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/myapp/lib/MyApp/TestEmail.pm100644000765000024 43014410403624 25400 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/myapp/lib/MyApp/Test/Basepackage MyApp::Test::Base::Email; use Validation::Class; # rules mixin mxn email => { required => 1, max_length => 255, filters => [qw/trim strip/] }; fld email => { mixin => 'basic', max_length => 11, required => 0 }; 1;21-filtering-behavior.t100644000765000024 446714410403624 25703 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regressionuse Test::More tests => 12; # begin package MyVal; use Validation::Class; package main; my $dpre = MyVal->new( fields => {foobar => {filters => 'alphanumeric'}}, params => {foobar => '1@%23abc45@%#@#%6d666ef..'} ); ok $dpre->params->{foobar} =~ /^123abc456d666ef$/, 'default pre-filtering ok'; my $pre = MyVal->new( fields => {foobar => {filters => 'alphanumeric'}}, params => {foobar => '1@%23abc45@%#@#%6d666ef..'}, filtering => 'pre' ); ok $pre->params->{foobar} =~ /^123abc456d666ef$/, 'explicit pre-filtering ok'; my $post = MyVal->new( fields => {foobar => {filters => 'alphanumeric'}}, params => {foobar => '1@%23abc45@%#@#%6d666ef..'}, filtering => 'post' ); ok $post->params->{foobar} =~ /^1@%23abc45@%#@#%6d666ef\.\.$/, 'explicit post-filtering ok'; $post->validate; ok $post->params->{foobar} =~ /^123abc456d666ef$/, 'explicit post-filtering after validate ok'; my $nope = MyVal->new( fields => {foobar => {filters => 'alphanumeric'}}, params => {foobar => '1@%23abc45@%#@#%6d666ef..'}, filtering => 'off' ); ok $nope->params->{foobar} =~ /^1@%23abc45@%#@#%6d666ef\.\.$/, 'explicit no-filtering ok'; $nope->validate; ok $nope->params->{foobar} =~ /^1@%23abc45@%#@#%6d666ef\.\.$/, 'explicit no-filtering after validate ok'; $nope = MyVal->new( fields => {foobar => {filters => 'alphanumeric'}}, params => {foobar => '1@%23abc45@%#@#%6d666ef..'}, filtering => 'manual' ); ok $nope->params->{foobar} =~ /^1@%23abc45@%#@#%6d666ef\.\.$/, 'explicit no pre/post filtering ok'; $nope->validate; ok $nope->params->{foobar} =~ /^1@%23abc45@%#@#%6d666ef\.\.$/, 'explicit no-filtering after validate ok'; # ok $nope->apply_filters('manual'), 'applying filters manually'; - DEPRECATED ok $nope->proto->apply_filters('manual'), 'applying filters manually'; ok $nope->params->{foobar} =~ /^123abc456d666ef$/, 'filtering applied manually'; $nope = MyVal->new( fields => {foobar => {filters => 'alphanumeric'}}, params => {foobar => '1@%23abc45@%#@#%6d666ef..'}, filtering => 'pre' ); ok $nope->filtering('pre'), 'changing filtering behavior: pre'; $nope->fields->{foobar}->{pattern} = qr/^\d{3}\w{3}\d{3}\w\d{3}\w{2}$/; $nope->params->{foobar} = '1@%23abc45@%#@#%6d666ef..'; ok $nope->validate, 'pre-filtering allowed validation'; 22-filtering-behavior.t100644000765000024 315314410403624 25673 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regressionuse Test::More tests => 9; # begin package MyVal; use Validation::Class; mixin 'trim' => {filters => [qw/trim strip/]}; field 'dist' => { mixin => 'trim', label => 'distribution', error => 'invalid distribution description', filters => sub { $_[0] =~ s/::/-/g; $_[0] }, pattern => qr/[a-zA-Z0-9\-:]+(\-[0-9\.\_\-]+)?/, max_length => 150 }; field 'login', { label => 'user login', error => 'login invalid', filtering => 'post', filters => [qw/trim strip alphanumeric/] }; field 'password', { label => 'user password', error => 'password invalid', # no filtering at all }; field 'name', { label => 'user name', error => 'invalid name', filtering => 'pre', filters => [qw/trim strip alpha titlecase/] }; package main; my $rules = MyVal->new( params => { name => 'george 3', login => 'admin@abco.com', password => '#!/bin/bash', dist => ' Validation::Class ' } ); ok $rules, 'validation class init ok'; ok $rules->params->{name} =~ /^George$/, 'name as expected'; ok $rules->params->{login} =~ /^admin\@abco\.com$/, 'login as expected'; ok $rules->params->{password} =~ /^#!\/bin\/bash$/, 'password as expected'; ok $rules->validate, 'validation failed ok'; ok $rules->params->{name} =~ /^George$/, 'name as expected'; ok $rules->params->{login} =~ /^adminabcocom$/, 'login as expected'; ok $rules->params->{password} =~ /^#!\/bin\/bash$/, 'password as expected'; ok $rules->params->{dist} =~ /^Validation-Class$/, 'dist as expected'; 09-capitalize.t100644000765000024 65714410403624 25703 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/filtersuse Test::More tests => 1; # load module package MyVal; use Validation::Class; package main; my $v = MyVal->new( fields => {foobar => {filters => 'capitalize'}}, params => { foobar => 'i am that I am. this is not going to work. im leaving, good bye.' } ); ok $v->params->{foobar} =~ /^I am that I am. This is not going to work. Im leaving, good bye./, 'capitalize filter working as expected'; 07-options.t100644000765000024 120014410403624 25750 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/validatorsuse Test::More tests => 5; package MyVal; use Validation::Class; package main; my $r = MyVal->new( fields => {status => {options => 'Active, Inactive'}}, params => {status => 'Active'} ); ok $r->validate(), 'status is valid'; $r->params->{status} = 'active'; ok !$r->validate(), 'status case doesnt match'; ok 'status must be either Active or Inactive' eq $r->errors_to_string(), 'displays proper error message'; $r->params->{status} = 'inactive'; ok !$r->validate(), 'status case doesnt match alt'; $r->params->{status} = 'Inactive'; ok $r->validate(), 'alternate status value validates'; #warn $r->errors_to_string(); 22-zipcode.t100644000765000024 164714410403624 25726 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/validatorsuse Test::More; package main; use utf8; use Validation::Class::Simple; my $s = Validation::Class::Simple->new( fields => { address_zipcode => {zipcode => 1} } ); sub should_fail { my ($name, @zipcodes) = @_; for (@zipcodes) { $s->params->{$name} = $_; ok !$s->validate($name), "$_ is an invalid $name param"; } } sub should_pass { my ($name, @zipcodes) = @_; for (@zipcodes) { $s->params->{$name} = $_; ok $s->validate($name), "$_ is a valid $name param"; } } # failures diag 'validating bad zip-codes'; should_fail 'address_zipcode' => qw( 00000-00 12345-12 12345-67 111114321 22030-123 ); diag 'validating good zip-codes'; should_pass 'address_zipcode' => qw( 00000 00000-0000 90036 80954 75501 01003 10003 22030 30303 41876 55413 60666 22030-5565 22030-1111 ); done_testing; 21-min_sum.t100644000765000024 74714410403624 25717 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/validatorsuse Test::More tests => 4; package MyVal; use Validation::Class; package main; my $r = MyVal->new( fields => { one => { label => 'Object', min_sum => 100 } } ); $r->params->{one} = 111; ok $r->validate('one'), 'validation ok'; $r->params->{one} = 100; ok $r->validate('one'), 'validation ok'; $r->params->{one} = 99; ok !$r->validate('one'), 'validation failed'; $r->params->{one} = 1000; ok $r->validate('one'), 'validation ok'; 22-decimal.t100644000765000024 134214410403624 25657 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/validatorsuse Test::More; package main; use utf8; use Validation::Class::Simple; my $s = Validation::Class::Simple->new( fields => { payment_amount => {decimal => 1} } ); sub should_fail { my ($name, @amounts) = @_; for (@amounts) { $s->params->{$name} = $_; ok !$s->validate($name), "$_ is an invalid $name param"; } } sub should_pass { my ($name, @amounts) = @_; for (@amounts) { $s->params->{$name} = $_; ok $s->validate($name), "$_ is a valid $name param"; } } # failures diag 'validating bad decimals'; should_fail 'payment_amount' => qw( 12345 54321 ); diag 'validating good decimals'; should_pass 'payment_amount' => qw( 123.45 543.21 ); done_testing; 03-pattern.t100644000765000024 130614410403624 25735 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/validatorsuse Test::More tests => 5; package MyVal; use Validation::Class; package main; my $r = MyVal->new( fields => { telephone => {pattern => '### ###-####'}, url => {pattern => qr/https?:\/\/.+/} }, params => { telephone => '123 456-7890', url => 'dept.site.com' } ); ok $r->validate('telephone'), 'telephone validates'; $r->params->{telephone} = '1234567890'; ok !$r->validate('telephone'), 'telephone doesnt validate'; ok $r->errors_to_string() =~ /is not formatted properly/, 'displays proper error message'; ok !$r->validate('url'), 'url doesnt validate'; $r->params->{url} = 'http://dept.site.com/'; ok $r->validate('url'), 'url validates'; 04-between.t100644000765000024 64114410403624 25673 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/validatorsuse Test::More tests => 3; package MyVal; use Validation::Class; package main; my $r = MyVal->new( fields => {foobar => {between => '2-5'}}, params => {foobar => 3} ); ok $r->validate(), 'foobar validates'; $r->params->{foobar} = 8; ok !$r->validate(), 'foobar doesnt validate'; ok 'foobar must be between 2-5' eq $r->errors_to_string(), 'displays proper error message'; #warn $r->errors_to_string(); 20-max_sum.t100644000765000024 74414410403624 25715 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/validatorsuse Test::More tests => 4; package MyVal; use Validation::Class; package main; my $r = MyVal->new( fields => { one => { label => 'Object', max_sum => 100 } } ); $r->params->{one} = 1; ok $r->validate('one'), 'validation ok'; $r->params->{one} = 11; ok $r->validate('one'), 'validation ok'; $r->params->{one} = 111; ok !$r->validate('one'), 'validation failed'; $r->params->{one} = 100; ok $r->validate('one'), 'validation ok'; 06-matches.t100644000765000024 175014410403624 25712 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/validatorsuse Test::More tests => 7; package MyVal; use Validation::Class; package main; my $r = MyVal->new( fields => { password => {matches => 'password2'}, password2 => { # .... }, }, params => { password => 'secret$', password2 => 'secret$', } ); ok $r->validate(), 'password validates'; $r->params->{password2} = 's3cret'; ok !$r->validate(), 'foobar doesnt validate'; ok $r->errors_to_string() =~ /password does not match password2/, 'displays proper error message'; $r->fields->{password}->{label} = 'pass (a)'; $r->fields->{password2}->{label} = 'pass (b)'; ok !$r->validate(), 'foobar doesnt validate'; ok $r->errors_to_string() =~ /pass \(a\) does not match pass \(b\)/, 'displays proper error message'; $r->params->{password2} = ''; ok !$r->validate(), 'foobar doesnt validate'; ok $r->errors_to_string() =~ /pass \(a\) does not match pass \(b\)/, 'displays proper error message'; #warn $r->errors_to_string(); Ticket.pm100644000765000024 37214410403624 25746 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/modules/MyValpackage MyVal::Ticket; use Validation::Class; field description => { mixin => 'TMP', label => 'Ticket description' }; field priority => { mixin => 'TMP', label => 'Ticket priority', options => [qw/Low Normal High Other/] }; 1;Person.pm100644000765000024 42214410403624 25765 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/modules/MyValpackage MyVal::Person; use Validation::Class; mixin TMP => { required => 1, min_length => 1, max_length => 255, }; field name => { mixin => 'TMP', label => 'Person\'s name' }; field email => { mixin => 'TMP', label => 'Person\'s email' }; 1;DependsOn.pm100644000765000024 504414410403624 25657 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: DependsOn Directive for Validation Class Field Definitions package Validation::Class::Directive::DependsOn; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 1; has 'message' => '%s requires %s'; sub validate { my $self = shift; my ($proto, $field, $param) = @_; if (defined $field->{depends_on} && defined $param) { my $specification = $field->{depends_on}; if ($field->{required} || $param) { my $dependents = isa_arrayref($specification) ? $specification : [$specification] ; if (@{$dependents}) { my @required_fields = (); foreach my $dependent (@{$dependents}) { my $field = $proto->fields->get($dependent); push @required_fields, $field->label || $field->name unless $proto->params->has($dependent) ; } if (my @r = @required_fields) { my$list=(join(' and ',join(', ',@r[0..$#r-1])||(),$r[-1])); $self->error(@_, $list); } } } } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::DependsOn - DependsOn Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { password_confirmation => { depends_on => 'password' } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::DependsOn is a core validation class field directive that validates the existence of dependent parameters. =over 8 =item * alternative argument: an-array-of-parameter-names This directive can be passed a single value or an array of values: fields => { password2_confirmation => { depends_on => ['password', 'password2'] } } =back =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut MaxDigits.pm100644000765000024 340214410403624 25665 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: MaxDigits Directive for Validation Class Field Definitions package Validation::Class::Directive::MaxDigits; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 0; has 'message' => '%s must not contain more than %s digits'; sub validate { my $self = shift; my ($proto, $field, $param) = @_; if (defined $field->{max_digits} && defined $param) { my $max_digits = $field->{max_digits}; if ( $field->{required} || $param ) { my @i = ($param =~ /[0-9]/g); if (@i > $max_digits) { $self->error(@_, $max_digits); } } } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::MaxDigits - MaxDigits Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { password => { max_digits => 12 } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::MaxDigits is a core validation class field directive that validates the length of numeric characters in the associated parameters. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Telephone.pm100644000765000024 330214410403624 25716 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: Telephone Directive for Validation Class Field Definitions package Validation::Class::Directive::Telephone; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 0; has 'message' => '%s is not a valid telephone number'; sub validate { my ($self, $proto, $field, $param) = @_; if (defined $field->{telephone} && defined $param) { if ($field->{required} || $param) { my $tre = qr/^(?:\+?1)?[-. ]?\(?[2-9][0-8][0-9]\)?[-. ]?[2-9][0-9]{2}[-. ]?[0-9]{4}$/; $self->error($proto, $field) unless $param =~ $tre; } } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::Telephone - Telephone Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { user_phone => { telephone => 1 } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::Telephone is a core validation class field directive that handles telephone number validation for the USA and North America. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut MinDigits.pm100644000765000024 340114410403624 25662 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: MinDigits Directive for Validation Class Field Definitions package Validation::Class::Directive::MinDigits; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 0; has 'message' => '%s must not contain less than %s digits'; sub validate { my $self = shift; my ($proto, $field, $param) = @_; if (defined $field->{min_digits} && defined $param) { my $min_digits = $field->{min_digits}; if ( $field->{required} || $param ) { my @i = ($param =~ /[0-9]/g); if (@i < $min_digits) { $self->error(@_, $min_digits); } } } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::MinDigits - MinDigits Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { password => { min_digits => 1 } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::MinDigits is a core validation class field directive that validates the length of numeric characters in the associated parameters. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Filtering.pm100644000765000024 326714410403624 25730 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: Filtering Directive for Validation Class Field Definitions package Validation::Class::Directive::Filtering; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 0; has 'dependencies' => sub {{ normalization => ['alias'], validation => [] }}; sub normalize { my ($self, $proto, $field, $param) = @_; # by default fields should have a filtering directive # unless already specified $field->{filtering} = $proto->filtering unless defined $field->{filtering}; return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::Filtering - Filtering Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { telephone_number => { filters => ['numeric'] filtering => 'post' } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::Filtering is a core validation class field directive that specifies whether filtering and sanitation should occur as a pre-process or post-process. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut MaxLength.pm100644000765000024 334314410403624 25667 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: MaxLength Directive for Validation Class Field Definitions package Validation::Class::Directive::MaxLength; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 0; has 'message' => '%s must not contain more than %s characters'; sub validate { my $self = shift; my ($proto, $field, $param) = @_; if (defined $field->{max_length} && defined $param) { my $max_length = $field->{max_length}; if ( $field->{required} || $param ) { if (length($param) > $max_length) { $self->error(@_, $max_length); } } } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::MaxLength - MaxLength Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { password => { max_length => 50 } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::MaxLength is a core validation class field directive that validates the length of all characters in the associated parameters. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut MinLength.pm100644000765000024 334214410403624 25664 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: MinLength Directive for Validation Class Field Definitions package Validation::Class::Directive::MinLength; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 0; has 'message' => '%s must not contain less than %s characters'; sub validate { my $self = shift; my ($proto, $field, $param) = @_; if (defined $field->{min_length} && defined $param) { my $min_length = $field->{min_length}; if ( $field->{required} || $param ) { if (length($param) < $min_length) { $self->error(@_, $min_length); } } } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::MinLength - MinLength Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { password => { min_length => 5 } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::MinLength is a core validation class field directive that validates the length of all characters in the associated parameters. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Multiples.pm100644000765000024 1230214410403624 25771 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: Multiples Directive for Validation Class Field Definitions package Validation::Class::Directive::Multiples; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 0; has 'field' => 1; has 'multi' => 0; has 'message' => '%s does not support multiple values'; # ensure most core directives execute before this one has 'dependencies' => sub {{ normalization => [], validation => [qw( alias between depends_on error errors filtering filters label length matches max_alpha max_digits max_length max_sum min_alpha min_digits min_length min_sum mixin mixin_field name options pattern readonly required toggle )] }}; sub after_validation { my $self = shift; my ($proto, $field, $param) = @_; if (defined $field->{multiples} && defined $param) { $self->after_validation_delete_clones($proto, $field, $param); } return $self; } sub after_validation_delete_clones { my $self = shift; my ($proto, $field, $param) = @_; my $name = $field->name; # this will add additional processing overhead which we hate, but is how we # will currently prevent the reaping of strangely named fields that appear # to be clones/clonable but are not in-fact ... so we'll check if the field # is in the clones array return unless grep { defined $_ and $name eq $_ } @{$proto->stash->{'directive.validation.clones'}} ; my ($key, $index) = $name =~ /^(.*)\:(\d+)$/; if ($key && defined $index) { my $value = $proto->params->delete($name); $proto->params->{$key} ||= []; $proto->params->{$key}->[$index] = $value; # inherit errors from clone if ($proto->fields->has($key) && $proto->fields->has($name)) { $proto->fields->get($key)->errors->add( $proto->fields->get($name)->errors->list ); } # remove clone permenantly $proto->fields->delete($name); delete $proto->stash->{'directive.validation.clones'}->[$index]; } return $self; } sub before_validation { my $self = shift; my ($proto, $field, $param) = @_; if (defined $field->{multiples} && defined $param) { $self->before_validation_create_clones($proto, $field, $param); } return $self; } sub before_validation_create_clones { my $self = shift; my ($proto, $field, $param) = @_; # clone fields to handle parameters with multi-values if (isa_arrayref($param)) { # is cloning allowed? .. in the U.S it is currently illegal :} return $self->error(@_) if ! $field->{multiples}; # clone deterministically my $name = $field->name; for (my $i=0; $i < @{$param}; $i++) { my $clone = "$name:$i"; $proto->params->add($clone => $param->[$i]); my $label = ($field->label || $name); my $options = {label => "$label #".($i+1), multiples => 0}; $proto->clone_field($name, $clone => $options); # add clones to field list to be validated push @{$proto->stash->{'validation.fields'}}, $clone if grep { $_ eq $name } @{$proto->stash->{'validation.fields'}} ; # record clones (to be reaped later) push @{$proto->stash->{'directive.validation.clones'}}, $clone; } $proto->params->delete($name); # remove the field the clones are based on from the fields list @{$proto->stash->{'validation.fields'}} = grep { $_ ne $name } @{$proto->stash->{'validation.fields'}} if @{$proto->stash->{'validation.fields'}} ; } return $self; } sub normalize { my $self = shift; my ($proto, $field, $param) = @_; # set a default value for the multiples directives # ... the default policy is deny,allow $field->{multiples} = 0 if ! defined $field->{multiples}; return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::Multiples - Multiples Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { user_options => { multiples => 1 } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::Multiples is a core validation class field directive that validates whether the associated parameters may contain a multi-value (an array of strings). =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut 02-package-declaration.t100644000765000024 75114410403624 25750 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regressionuse Test::More tests => 4; package MyApp::Test; use Validation::Class; field 'field01' => { required => 1, min_length => 1, max_length => 255, }; field 'field02' => { required => 1, min_length => 1, max_length => 255, }; package main; my $v = MyApp::Test->new; # check attributes ok ref $v, 'class initialized'; ok $v->fields->{field01}, 'field01 inheritence ok'; ok $v->fields->{field02}, 'field02 inheritence ok'; ok !$v->error_count, 'no errors yet'; 22-hostname.t100644000765000024 173114410403624 26101 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/validatorsuse Test::More; package main; use utf8; use Validation::Class::Simple; my $s = Validation::Class::Simple->new( fields => { domain_name => {hostname => 1} } ); sub should_fail { my ($name, @domains) = @_; for (@domains) { $s->params->{$name} = $_; ok !$s->validate($name), "$_ is an invalid $name param"; } } sub should_pass { my ($name, @domains) = @_; for (@domains) { $s->params->{$name} = $_; ok $s->validate($name), "$_ is a valid $name param"; } } # failures diag 'validating bad hostnames'; should_fail 'domain_name' => ( '.example.com', 'Abc.example.', 'Abc..example.com', 'A~b~c~example.com', 'a#b[j\k]example.com', 'just"not"right.example.com', 'this!is.example.com', 'this is.example.com', 'this\ still\"not\\allowed.example.com', ); diag 'validating good hostnames'; should_pass 'domain_name' => qw( example.com cpan.org us.gov ); done_testing; MaxSymbols.pm100644000765000024 345114410403624 26076 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: MaxSymbols Directive for Validation Class Field Definitions package Validation::Class::Directive::MaxSymbols; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 0; has 'message' => '%s must not contain more than %s special characters'; sub validate { my $self = shift; my ($proto, $field, $param) = @_; if (defined $field->{max_symbols} && defined $param) { my $max_symbols = $field->{max_symbols}; if ( $field->{required} || $param ) { my @i = ($param =~ /[^a-zA-Z0-9]/g); if (@i > $max_symbols) { $self->error(@_, $max_symbols); } } } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::MaxSymbols - MaxSymbols Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { password => { max_symbols => 30 } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::MaxSymbols is a core validation class field directive that validates the length of non-alphanumeric characters in the associated parameters. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut MinSymbols.pm100644000765000024 345014410403624 26073 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: MinSymbols Directive for Validation Class Field Definitions package Validation::Class::Directive::MinSymbols; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 0; has 'message' => '%s must not contain less than %s special characters'; sub validate { my $self = shift; my ($proto, $field, $param) = @_; if (defined $field->{min_symbols} && defined $param) { my $min_symbols = $field->{min_symbols}; if ( $field->{required} || $param ) { my @i = ($param =~ /[^a-zA-Z0-9]/g); if (@i < $min_symbols) { $self->error(@_, $min_symbols); } } } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::MinSymbols - MinSymbols Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { password => { min_symbols => 1 } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::MinSymbols is a core validation class field directive that validates the length of non-alphanumeric characters in the associated parameters. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Validation.pm100644000765000024 633014410403624 26071 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: Validation Directive for Validation Class Field Definitions package Validation::Class::Directive::Validation; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 0; has 'field' => 1; has 'multi' => 0; has 'message' => '%s could not be validated'; # ensure most core directives execute before this one has 'dependencies' => sub {{ normalization => [], validation => [qw( alias between default depends_on error errors filtering filters label length matches max_alpha max_digits max_length max_sum min_alpha min_digits min_length min_sum mixin mixin_field multiples name options pattern readonly required toggle value )] }}; sub validate { my $self = shift; my ($proto, $field, $param) = @_; if (defined $field->{validation} && defined $param) { my $context = $proto->stash->{'validation.context'}; my $count = ($proto->errors->count+$field->errors->count); my $failed = !$field->validation->($context,$field,$proto->params)?1:0; my $errors = ($proto->errors->count+$field->errors->count)>$count ?1:0; # error handling; did the validation routine pass or fail? # validation passed with no errors if (!$failed && !$errors) { # noop } # validation failed with no errors elsif ($failed && !$errors) { $self->error(@_); } # validation passed with errors elsif (!$failed && $errors) { # noop -- but acknowledge errors have been set } # validation failed with errors elsif ($failed && $errors) { # assume errors have been set from inside the validation routine } } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::Validation - Validation Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { example_data => { validation => sub { my ($self, $proto, $field, $params) = @_; # user-defined validation should return true/false } } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::Validation is a core validation class field directive that is used to execute user-defined validation routines. This directive always takes a sub-routine and should return true or false. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut MixinField.pm100644000765000024 266014410403624 26031 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: MixinField Directive for Validation Class Field Definitions package Validation::Class::Directive::MixinField; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 0; has 'field' => 1; has 'multi' => 0; 1; __END__ =pod =head1 NAME Validation::Class::Directive::MixinField - MixinField Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { first_name => { required => 1, filters => ['trim', 'strip'] }, last_name => { mixin_field => 'first_name' } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::MixinField is a core validation class field directive that determines what fields will be used as templates and merged with the associated field. =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Creditcard.pm100644000765000024 723614410403624 26051 0ustar00christiaanstaff000000000000Validation-Class-7.900059/lib/Validation/Class/Directive# ABSTRACT: Creditcard Directive for Validation Class Field Definitions package Validation::Class::Directive::Creditcard; use strict; use warnings; use base 'Validation::Class::Directive'; use Validation::Class::Util; our $VERSION = '7.900059'; # VERSION has 'mixin' => 1; has 'field' => 1; has 'multi' => 0; has 'message' => '%s requires a valid credit card number'; sub validate { my ($self, $proto, $field, $param) = @_; if (defined $field->{creditcard} && defined $param) { my $ccre = { 'amex' => qr/^3[4|7]\d{13}$/, 'bankcard' => qr/^56(10\d\d|022[1-5])\d{10}$/, 'diners' => qr/^(?:3(0[0-5]|[68]\d)\d{11})|(?:5[1-5]\d{14})$/, 'disc' => qr/^(?:6011|650\d)\d{12}$/, 'electron' => qr/^(?:417500|4917\d{2}|4913\d{2})\d{10}$/, 'enroute' => qr/^2(?:014|149)\d{11}$/, 'jcb' => qr/^(3\d{4}|2100|1800)\d{11}$/, 'maestro' => qr/^(?:5020|6\d{3})\d{12}$/, 'mastercard' => qr/^5[1-5]\d{14}$/, 'solo' => qr/^(6334[5-9][0-9]|6767[0-9]{2})\d{10}(\d{2,3})?$/, 'switch' => qr/^(?:49(03(0[2-9]|3[5-9])|11(0[1-2]|7[4-9]|8[1-2])|36[0-9]{2})\d{10}(\d{2,3})?)|(?:564182\d{10}(\d{2,3})?)|(6(3(33[0-4][0-9])|759[0-9]{2})\d{10}(\d{2,3})?)$/, 'visa' => qr/^4\d{12}(\d{3})?$/, 'voyager' => qr/^8699[0-9]{11}$/, # or do a simple catch-all match 'any' => qr/^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6011[0-9]{12}|3(?:0[0-5]|[68][0-9])[0-9]{11}|3[47][0-9]{13})$/ }; my $type = $field->{creditcard}; if ($field->{required} || $param) { my $is_valid = 0; $type = isa_arrayref($type) ? $type : $type eq '1' ? ['any'] : [$type]; for (@{$type}) { if ($param =~ $ccre->{$_}) { $is_valid = 1; last; } } $self->error($proto, $field) unless $is_valid; } } return $self; } 1; __END__ =pod =head1 NAME Validation::Class::Directive::Creditcard - Creditcard Directive for Validation Class Field Definitions =head1 VERSION version 7.900059 =head1 SYNOPSIS use Validation::Class::Simple; my $rules = Validation::Class::Simple->new( fields => { person_cc => { creditcard => 1 } } ); # set parameters to be validated $rules->params->add($parameters); # validate unless ($rules->validate) { # handle the failures } =head1 DESCRIPTION Validation::Class::Directive::Creditcard is a core validation class field directive that provides validation for american express, bankcard, diners card, discover card, electron, enroute, jcb, maestro, mastercard, solo, switch, visa and voyager credit cards. =over 8 =item * alternative argument: an-array-of-options =item * option: amex =item * option: bankcard =item * option: diners =item * option: disc =item * option: electron =item * option: enroute =item * option: jcb =item * option: maestro =item * option: mastercard =item * option: solo =item * option: switch =item * option: visa =item * option: voyager This directive can be passed a single value or an array of values: fields => { person_cc => { creditcard => ['visa', 'mastercard'] } } =back =head1 AUTHOR Al Newkirk =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut 10-alphanumeric.t100644000765000024 50214410403624 26203 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/filtersuse Test::More tests => 1; # load module package MyVal; use Validation::Class; package main; my $v = MyVal->new( fields => {foobar => {filters => 'alphanumeric'}}, params => {foobar => '1@%23abc45@%#@#%6d666ef..'} ); ok $v->params->{foobar} =~ /^123abc456d666ef$/, 'alphanumeric filter working as expected'; 21-min_alpha.t100644000765000024 76314410403624 26176 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/validatorsuse Test::More tests => 4; package MyVal; use Validation::Class; package main; my $r = MyVal->new( fields => { one => { label => 'Object', min_alpha => 2 } } ); $r->params->{one} = 'see'; ok $r->validate('one'), 'validation ok'; $r->params->{one} = 'be'; ok $r->validate('one'), 'validation ok'; $r->params->{one} = 'a'; ok !$r->validate('one'), 'validation failed'; $r->params->{one} = 'zz123456'; ok $r->validate('one'), 'validation ok'; 22-telephone.t100644000765000024 162414410403624 26247 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/validatorsuse Test::More; package MyVal; use Validation::Class; package main; my $r = MyVal->new(fields => {phone => {telephone => 1}}); # failures $r->params->{phone} = '0000000'; ok !$r->validate(), '0000000 is invalid'; $r->params->{phone} = '1115551212'; ok !$r->validate(), '1115551212 is invalid'; # successes $r->params->{phone} = '2155551212'; ok $r->validate(), '2155551212 is valid'; $r->params->{phone} = '12155551212'; ok $r->validate(), '12155551212 is valid'; $r->params->{phone} = '+12155551212'; ok $r->validate(), '+12155551212 is valid'; $r->params->{phone} = '+1 215 555-1212'; ok $r->validate(), '+1 215 555-1212 is valid'; $r->params->{phone} = '+1 (215) 555-1212'; ok $r->validate(), '+1 (215) 555-1212 is valid'; $r->params->{phone} = '(215) 555-1212'; ok $r->validate(), '(215) 555-1212 is valid'; $r->params->{phone} = '215 555 1212'; ok $r->validate(), '215 555 1212 is valid'; done_testing; 20-max_alpha.t100644000765000024 75714410403624 26202 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/validatorsuse Test::More tests => 4; package MyVal; use Validation::Class; package main; my $r = MyVal->new( fields => { one => { label => 'Object', max_alpha => 2 } } ); $r->params->{one} = 'a'; ok $r->validate('one'), 'validation ok'; $r->params->{one} = 'be'; ok $r->validate('one'), 'validation ok'; $r->params->{one} = 'see'; ok !$r->validate('one'), 'validation failed'; $r->params->{one} = 123456; ok $r->validate('one'), 'validation ok'; 21-min_digit.t100644000765000024 75714410403624 26214 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/validatorsuse Test::More tests => 4; package MyVal; use Validation::Class; package main; my $r = MyVal->new( fields => { one => { label => 'Object', min_digits => 2 } } ); $r->params->{one} = 111; ok $r->validate('one'), 'validation ok'; $r->params->{one} = 11; ok $r->validate('one'), 'validation ok'; $r->params->{one} = 1; ok !$r->validate('one'), 'validation failed'; $r->params->{one} = '11abcdef'; ok $r->validate('one'), 'validation ok'; 20-max_digit.t100644000765000024 75514410403624 26213 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/validatorsuse Test::More tests => 4; package MyVal; use Validation::Class; package main; my $r = MyVal->new( fields => { one => { label => 'Object', max_digits => 2 } } ); $r->params->{one} = 1; ok $r->validate('one'), 'validation ok'; $r->params->{one} = 11; ok $r->validate('one'), 'validation ok'; $r->params->{one} = 111; ok !$r->validate('one'), 'validation failed'; $r->params->{one} = 'abcdef'; ok $r->validate('one'), 'validation ok'; 22-creditcard.t100644000765000024 352014410403624 26365 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/validatorsuse Test::More; package main; use utf8; use Validation::Class::Simple; my $r = Validation::Class::Simple->new(fields => {visa_number => {creditcard => 1}}); sub should_fail { my ($name, @numbers) = @_; for (@numbers) { $r->params->{$name} = $_; ok !$r->validate(), "$_ is an invalid $name param"; } } sub should_pass { my ($name, @numbers) = @_; for (@numbers) { $r->params->{$name} = $_; ok $r->validate(), "$_ is a valid $name param"; } } # failures diag 'validating bad visa numbers'; should_fail visa_number => qw( 1111111111111111 0000000000000000 1234567887654321 ); diag 'now validating visa numbers against mastercard validator'; $r->fields->get('visa_number')->creditcard('mastercard'); should_fail visa_number => qw( 1111111111111111 0000000000000000 1234567887654321 ); # successes diag 'now validating bad visa numbers which are properly formatted'; $r->fields->get('visa_number')->creditcard(1); should_pass visa_number => qw( 4222222222222 4111111111111111 4012888888881881 ); diag 'now passing the "visa" argument to the creditcard directive'; $r->fields->get('visa_number')->creditcard('visa'); should_pass visa_number => qw( 4222222222222 4111111111111111 4012888888881881 ); diag 'now using mc numbers and passing the "mastercard" argument to the creditcard directive'; $r->fields->get('visa_number')->creditcard('mastercard'); should_pass visa_number => qw( 5105105105105100 5555555555554444 ); diag 'now using mc and visa numbers and passing the ["visa", "mastercard"] argument to the creditcard directive'; $r->fields->get('visa_number')->creditcard(['visa', 'mastercard']); should_pass visa_number => qw( 4222222222222 4111111111111111 4012888888881881 5105105105105100 5555555555554444 ); done_testing; 08-depends_on.t100644000765000024 111614410403624 26402 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/validatorsuse Test::More tests => 5; package MyVal; use Validation::Class; package main; my $r = MyVal->new( fields => { two => { label => 'The Two', required => 1 }, one => { label => 'The One', depends_on => 'two' } } ); ok $r->validate('one'), 'one not required, pass'; $r->params->{one} = 1; # flag ok !$r->validate('one'), 'two is required'; ok $r->error_count == 1, 'error count ok'; $r->params->{two} = 2; ok $r->validate('one'), 'validation ok'; ok !$r->error_count, 'error count ok'; 01-min_length.t100644000765000024 66614410403624 26372 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/validatorsuse Test::More tests => 3; package MyVal; use Validation::Class; package main; my $r = MyVal->new( fields => {foobar => {min_length => 5}}, params => {foobar => 'apple'} ); ok $r->validate(), 'foobar validates'; $r->fields->{foobar}->{min_length} = 6; ok !$r->validate(), 'foobar doesnt validate'; ok $r->errors_to_string() =~ /must not contain less than 6/, 'displays proper error message'; #warn $r->errors_to_string(); 02-max_length.t100644000765000024 66614410403624 26375 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/validatorsuse Test::More tests => 3; package MyVal; use Validation::Class; package main; my $r = MyVal->new( fields => {foobar => {max_length => 5}}, params => {foobar => 'apple'} ); ok $r->validate(), 'foobar validates'; $r->fields->{foobar}->{max_length} = 4; ok !$r->validate(), 'foobar doesnt validate'; ok $r->errors_to_string() =~ /must not contain more than 4/, 'displays proper error message'; #warn $r->errors_to_string(); 11-array-param-validation.t100644000765000024 344314410403624 26457 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regressionuse Test::More tests => 12; package MyVal; use Validation::Class; package main; my $v1 = MyVal->new( fields => {foobar => {min_length => 5}}, params => {foobar => [join('', 1 .. 4), join('', 1 .. 5),]} ); # check that an array parameters is handled properly on-the-fly ok !$v1->validate('foobar'), 'validation does not pass'; ok $v1->error_count == 1, '1 errors set, 1 wrong element of the param array value'; ok $v1->errors_to_string =~ /multiple/, 'error message identifies no array handling specified'; my $v2 = MyVal->new( fields => { 'foobar.barbaz' => { min_length => 5, multiples => 1 } }, params => {'foobar.barbaz' => [join('', 1 .. 4), join('', 1 .. 5),]} ); ok !$v2->validate('foobar.barbaz'), 'validation does not pass'; ok $v2->error_count == 1, '1 errors set, 1 wrong element of the param array value'; ok $v2->errors_to_string =~ /#/, 'error message identifies the problem param array element'; my $v3 = MyVal->new( fields => {'foobar.barbaz:0' => {min_length => 5}}, params => { 'foobar.barbaz:0' => join('', 1 .. 4), 'foobar.barbaz:1' => join('', 1 .. 5) } ); ok !$v3->validate('foobar.barbaz:0'), 'validation does not pass'; ok $v3->error_count == 1, '1 errors set, 1 wrong element of the param array value'; ok $v3->errors_to_string =~ /less than 5/, 'error message identifies the problem param array element'; my $v4 = MyVal->new( fields => {'foobar.barbaz' => {min_length => 5}}, params => {'foobar.barbaz' => join('', 1 .. 4)} ); ok !$v4->validate('foobar.barbaz'), 'validation does not pass'; ok $v4->error_count == 1, '1 errors set, 1 wrong element of the param array value'; ok $v4->errors_to_string !~ /#/, 'error message identifies the problem param in not an array element'; 21-min_symbols.t100644000765000024 76214410403624 26600 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/validatorsuse Test::More tests => 4; package MyVal; use Validation::Class; package main; my $r = MyVal->new( fields => { one => { label => 'Object', min_symbols => 2 } } ); $r->params->{one} = '@@#'; ok $r->validate('one'), 'validation ok'; $r->params->{one} = '@@'; ok $r->validate('one'), 'validation ok'; $r->params->{one} = '!'; ok !$r->validate('one'), 'validation failed'; $r->params->{one} = '$$D'; ok $r->validate('one'), 'validation ok'; 20-max_symbols.t100644000765000024 76214410403624 26601 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/validatorsuse Test::More tests => 4; package MyVal; use Validation::Class; package main; my $r = MyVal->new( fields => { one => { label => 'Object', max_symbols => 2 } } ); $r->params->{one} = '@'; ok $r->validate('one'), 'validation ok'; $r->params->{one} = '@@'; ok $r->validate('one'), 'validation ok'; $r->params->{one} = '@@#'; ok !$r->validate('one'), 'validation failed'; $r->params->{one} = '$$D'; ok $r->validate('one'), 'validation ok'; 99-alias-handling-with-report-unknown-enabled.t100644000765000024 103714410403624 26726 0ustar00christiaanstaff000000000000Validation-Class-7.900059/tuse FindBin; use Test::More; use utf8; use strict; use warnings; { use_ok 'Validation::Class'; } { { package T; use Validation::Class; field foo => { required => 1, alias => ['bar'] }; } package main; my $t = T->new( ignore_unknown => 1, report_unknown => 1, ); $t->params->add({'bar' => 'ayeoke'}); ok "T" eq ref $t, "T instantiated"; ok $t->validate, 't validates all params successfully'; ok !$t->error_count, 't has no errors'; } done_testing(); Plugin000755000765000024 014410403624 25301 5ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/modules/MyValGlade.pm100644000765000024 41414410403624 26772 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regression/modules/MyVal/Pluginpackage MyVal::Plugin::Glade; sub new { my ($self, $proto) = @_; $proto->stash(smell => \&smell); $proto->stash(squirt => \&squirt); $proto->set_method(squash => sub {'abc'}); return bless {}, $self; } sub smell {'Good'} sub squirt {1} 1; 13-multiline-labels-and-errors.t100644000765000024 157414410403624 27434 0ustar00christiaanstaff000000000000Validation-Class-7.900059/t/legacy/regressionuse Test::More tests => 5; package MyVal; use Validation::Class; field name => { required => 1, label => q( This is a test of a particularly long label string ), error => q( The name parameter is required, in order to use this parameter you must kill three goats and eat the flesh of an african albino tree spider ) }; package main; use strict; use warnings; my $v = MyVal->new(params => {}); ok $v, 'initialization successful'; ok $v->fields->{name}->{label} !~ /[\n\t\r]/, 'label does not have new-lines, carriage-returns and tabs'; ok $v->fields->{name}->{label} !~ /\s{2,}/, 'label does not have consecutive spaces'; ok $v->fields->{name}->{error} !~ /[\n\t\r]/, 'error does not have new-lines, carriage-returns and tabs'; ok $v->fields->{name}->{error} !~ /\s{2,}/, 'error does not have consecutive spaces';