function OnPostback()
 {
     /* @var $email Zend_Mail */
     $email = $this->form->GetDataObject();
     # Throttles sending rate to deter spam
     if (isset($_SESSION['email_form_throttle'])) {
         $last_sent = $_SESSION['email_form_throttle'];
         $allow_after = $last_sent + 10;
         if (time() <= $allow_after) {
             $this->throttled = true;
             # Use a validator to display the message, because that ensures the submitted data is repopulated in the form
             require_once 'data/validation/required-field-validator.class.php';
             $fail = new RequiredFieldValidator(array("this_validator_will_fail"), "You've sent another email too quickly. We limit the speed you can send them, to help protect you against spam. Try again now.");
             $fail->SetValidIfNotFound(false);
             $this->form->AddValidator($fail);
             return;
         }
     }
     # send email if valid
     if ($this->IsValid() and $this->valid) {
         $email->addTo($this->address);
         $this->send_attempted = true;
         $this->send_succeeded = true;
         try {
             $email->send();
             $_SESSION['email_form_throttle'] = time();
         } catch (Zend_Mail_Transport_Exception $e) {
             $this->send_succeeded = false;
         }
     }
 }
 function OnPostback()
 {
     $this->season = $this->edit->GetDataObject();
     if (!$this->season->GetId()) {
         $existing_season_id = $this->season_manager->CheckIfSeasonExists($this->season->GetCompetition()->GetId(), $this->season->GetStartYear(), $this->season->GetEndYear());
         if ($existing_season_id) {
             require_once 'data/validation/required-field-validator.class.php';
             $season = new Season($this->GetSettings());
             $season->SetId($existing_season_id);
             $validator = new RequiredFieldValidator('This_Validator_Will_Fail', "The season you're adding already exists &#8211; <a href=\"" . $season->GetNavigateUrl() . "\">edit season</a>");
             $validator->SetValidIfNotFound(false);
             $this->edit->AddValidator($validator);
         }
     }
     # Get the competition. This is used to build the page title and, when saving, the short URL.
     # It is also re-indexed in search below.
     $this->competition_manager = new CompetitionManager($this->GetSettings(), $this->GetDataConnection());
     $this->competition_manager->ReadById(array($this->season->GetCompetition()->GetId()));
     $this->season->SetCompetition($this->competition_manager->GetFirst());
     unset($this->competition_manager);
     # save data if valid
     if ($this->IsValid()) {
         $b_saved_new = !(bool) $this->season->GetId();
         $id = $this->season_manager->SaveSeason($this->season);
         $this->season->SetId($id);
         # Add the competition to the search  engine. Re-request so we have team names as well as IDs.
         require_once "search/competition-search-adapter.class.php";
         $this->SearchIndexer()->DeleteFromIndexById("competition" . $this->season->GetCompetition()->GetId());
         $adapter = new CompetitionSearchAdapter($this->season->GetCompetition());
         $this->SearchIndexer()->Index($adapter->GetSearchableItem());
         $this->SearchIndexer()->CommitChanges();
         # If just saved a new season, redirect to load this page from scratch
         # (When just loading data on this page, didn't load correctly into aggregated editors)
         if ($b_saved_new) {
             $this->Redirect($this->season->GetEditSeasonUrl());
         }
         $this->Redirect($this->season->GetNavigateUrl());
     }
 }
 /**
  * @return void
  * @desc Create DataValidator objects to validate the edit control
  */
 public function CreateValidators()
 {
     require_once 'data/validation/required-field-validator.class.php';
     require_once 'data/validation/numeric-validator.class.php';
     require_once 'data/validation/length-validator.class.php';
     $this->a_validators = array();
     $this->AddValidator(new RequiredFieldValidator($this->GetNamingPrefix() . 'Title', 'Please enter the tournament name', ValidatorMode::SingleField()));
     $this->AddValidator(new LengthValidator($this->GetNamingPrefix() . 'Title', 'Your tournament name should not be more than 200 characters long', 0, 200));
     $player_type_required = new RequiredFieldValidator($this->GetNamingPrefix() . 'PlayerType', 'Please specify who can play in the tournament');
     $player_type_required->SetValidIfNotFound(false);
     $this->AddValidator($player_type_required);
     $this->AddValidator(new NumericValidator($this->GetNamingPrefix() . 'Qualify', 'A number should represent who can play'));
     $this->AddValidator(new NumericValidator($this->GetNamingPrefix() . 'PlayerType', 'A number should represent the type of team'));
     $this->AddValidator(new NumericValidator($this->GetNamingPrefix() . 'Players', "The number of players per team should be in digits, for example '8' not 'eight'"));
     $this->AddValidator(new RequiredFieldValidator(array($this->GetNamingPrefix() . 'Start_day', $this->GetNamingPrefix() . 'Start_month', $this->GetNamingPrefix() . 'Start_year'), 'Please select a date for the match', ValidatorMode::AllFields()));
     $this->AddValidator(new RequiredFieldValidator(array($this->GetNamingPrefix() . 'Start_hour', $this->GetNamingPrefix() . 'Start_minute', $this->GetNamingPrefix() . 'Start_ampm'), 'If you know the match time select the hour, minute and am or pm. If not, leave all three blank.', ValidatorMode::AllOrNothing()));
     $this->AddValidator(new NumericValidator($this->GetNamingPrefix() . 'Ground', 'The ground should be a number'));
     $this->AddValidator(new LengthValidator($this->GetNamingPrefix() . 'Notes', 'Your match notes should not be more than 5000 characters long', 0, 5000));
 }
 /**
  * @return bool
  * @desc Test whether all registered DataValidators are valid
  */
 public function IsValid()
 {
     /* @var $o_validator DataValidator */
     # Reject requests for validation if request is not a postback
     if (strtoupper($this->GetAttribute("method")) == "POST" and !$this->IsPostback()) {
         return true;
     }
     # Create validators if not yet done
     if (!isset($this->a_validators)) {
         $this->a_validators = array();
         $this->CreateValidators();
     }
     # Check for cached validation result
     if ($this->b_valid == null) {
         # Validate
         $b_valid = true;
         if (is_array($this->a_validators)) {
             # For POST forms, add CSRF validator where it will always be applied
             # Exclude  when validation errors not shown as that's effectively an indication that this is part of a larger form,
             # and in that situation this validator breaks internal  postbacks
             if (strtoupper($this->GetAttribute("method")) == "POST" and $this->IsPostback() and !$this->csrf_validator_added and $this->b_show_validation_errors and (!isset($_POST['securitytoken']) or !isset($_SESSION['csrf_token']) or $_POST['securitytoken'] != $_SESSION['csrf_token'])) {
                 require_once 'data/validation/required-field-validator.class.php';
                 $fail = new RequiredFieldValidator(array("this_validator_will_fail"), "The security information for this form isn't correct. Try again, or let us know if there's a problem.");
                 $fail->SetValidIfNotFound(false);
                 $this->a_validators[] = $fail;
                 $this->csrf_validator_added = true;
                 # Hack, because this validator was getting added twice
             }
             foreach ($this->a_validators as $o_validator) {
                 if ($o_validator->RequiresSettings()) {
                     $o_validator->SetSiteSettings($this->settings);
                 }
                 if ($o_validator->RequiresDataConnection()) {
                     $o_validator->SetDataConnection($this->data_connection);
                 }
                 if (strtoupper($this->GetAttribute("method")) == "GET") {
                     $o_validator->a_data = $_GET;
                 }
                 # Order of this line is vital. IsValid() must come first in the test to ensure it always runs,
                 # rather than short circuiting when $b_valid is false. This is because it must run when the page is
                 # first being validated and database resources are available, and cache its result. That way when
                 # it is read again later by the validation summary it has the cached result and doesn't need to go
                 # to the now unavailable database.
                 $b_valid = ($o_validator->IsValid() and $b_valid);
             }
         }
         # Cache result
         $this->b_valid = $b_valid;
     }
     # Return cached result
     return $this->b_valid;
 }
 /**
  * @return void
  * @desc Create DataValidator objects to validate the edit control
  */
 public function CreateValidators()
 {
     require_once 'data/validation/required-field-validator.class.php';
     require_once 'data/validation/plain-text-validator.class.php';
     require_once 'data/validation/length-validator.class.php';
     require_once 'stoolball/player-name-validator.class.php';
     if ($this->GetCurrentPage() == PlayerEditor::MERGE_PLAYER) {
         $radio_required = new RequiredFieldValidator($this->GetNamingPrefix() . "MergeOptions", "Please choose whether to merge the two players");
         $radio_required->SetValidIfNotFound(false);
         $this->AddValidator($radio_required);
     }
     $this->AddValidator(new RequiredFieldValidator($this->GetNamingPrefix() . 'Name', "Please add the player's name"));
     $this->AddValidator(new PlainTextValidator($this->GetNamingPrefix() . 'Name', "Please use only letters, numbers and simple punctuation in the player's name"));
     $this->AddValidator(new LengthValidator($this->GetNamingPrefix() . 'Name', "Please make the player's name shorter", 0, 100));
     $player_name_validator = new PlayerNameValidator(array($this->GetNamingPrefix() . "Name"), "Sorry, you can't use that name for a player. Please choose another.");
     $player_name_validator->SetSiteSettings($this->GetSettings());
     $this->AddValidator($player_name_validator);
 }
 /**
  * @return void
  * @desc Create DataValidator objects to validate the edit control
  */
 public function CreateValidators()
 {
     # Validate existing rows only if 'add' or 'delete' not clicked,
     # because those buttons should only affect the row those buttons relate to.
     $i_rows_posted = count($this->a_rows_posted);
     if (!$this->controlling_editor->IsInternalPostback() and $i_rows_posted) {
         $i_last_item = $this->a_rows_posted[$i_rows_posted - 1];
         foreach ($this->a_rows_posted as $i) {
             if ($i == $i_last_item and $this->Adding()) {
                 continue;
             }
             # ignore last one if it's the new row
             $this->CreateValidatorsForItem($i);
         }
     }
     # Validate the new row, unless 'delete' was clicked on another row in this control,
     # because then only the deleted row should be affected, or unless any internal
     # button in another control was clicked.
     if (!$this->DeleteClicked() and !$this->IsUnrelatedInternalPostback()) {
         $this->CreateValidatorsForItem();
     }
     # If saving, and this control doesn't have its minimum number of items, force a validation error
     $i_total_items = $this->DataObjects()->GetCount();
     if ($i_total_items < $this->i_min_items and !$this->controlling_editor->IsInternalPostback()) {
         $force_invalid = new RequiredFieldValidator('ForceInvalid', 'Please add at least one item in \'' . strtolower($this->table->GetCaption()) . '\'');
         $force_invalid->SetValidIfNotFound(false);
         $this->AddValidator($force_invalid);
     }
 }