function OnPreRender()
 {
     /* @var $o_validator DataValidator */
     $a_validators = array();
     $a_controls_to_validate =& $this->a_controls_to_validate;
     foreach ($a_controls_to_validate as $o_control) {
         $a_validators = array_merge($a_validators, $o_control->GetValidators());
     }
     if (count($a_validators)) {
         $o_list = new XhtmlElement('ul');
         foreach ($a_validators as $o_validator) {
             if (!$o_validator->IsValid()) {
                 $o_item = new XhtmlElement('li', $o_validator->GetMessage());
                 $o_list->AddControl($o_item);
             }
         }
         if ($o_list->CountControls()) {
             if ($this->s_header_text) {
                 $this->AddControl(new XhtmlElement('span', $this->s_header_text));
             }
             $this->AddControl($o_list);
             $this->SetVisible(true);
         } else {
             $this->SetVisible(false);
         }
     }
 }
 private function AddMetadata(Match $match, XhtmlElement $li)
 {
     $li->AddCssClass('vevent');
     # hCalendar
     $li->AddAttribute("typeof", "schema:SportsEvent");
     $li->AddAttribute("about", $match->GetLinkedDataUri());
     $meta = new XhtmlElement('span');
     $meta->SetCssClass('metadata');
     # hCalendar end date
     if ($match->GetStartTime() and $match->GetIsStartTimeKnown()) {
         $end_date = $this->CreateEndDate($match);
         $meta->AddControl($end_date);
     }
     # hCalendar location
     if (!is_null($match->GetGround())) {
         $ground = new XhtmlElement('span', htmlentities($match->GetGround()->GetNameAndTown(), ENT_QUOTES, "UTF-8", false));
         $ground->SetCssClass('location');
         $meta->AddControl(' at ');
         $meta->AddControl($ground);
     }
     # hCalendar description
     $hcal_desc = new XhtmlElement('span');
     $hcal_desc->SetCssClass('description');
     $i_seasons = $match->Seasons()->GetCount();
     if ($i_seasons) {
         $meta->AddControl(' in ');
         $seasons = $match->Seasons()->GetItems();
         for ($i = 0; $i < $i_seasons; $i++) {
             $b_last = ($i > 0 and $i == $i_seasons - 1);
             if ($i > 0 and !$b_last) {
                 $hcal_desc->AddControl(', ');
             } elseif ($b_last) {
                 $hcal_desc->AddControl(' and ');
             }
             $hcal_desc->AddControl(htmlentities($seasons[$i]->GetCompetitionName(), ENT_QUOTES, "UTF-8", false));
         }
     }
     if (!$match->GetIsStartTimeKnown()) {
         $hcal_desc->AddControl('. Start time not known');
     }
     if ($hcal_desc->CountControls()) {
         $meta->AddControl($hcal_desc);
     }
     # hCalendar timestamp
     $meta->AddControl('. At ');
     $hcal_stamp = new XhtmlElement('abbr', htmlentities(Date::Time(gmdate('U')), ENT_QUOTES, "UTF-8", false));
     $hcal_stamp->SetTitle(Date::Microformat());
     $hcal_stamp->SetCssClass('dtstamp');
     $meta->AddControl($hcal_stamp);
     # hCalendar GUID
     $meta->AddControl(' match ');
     $hcal_guid = new XhtmlElement('span', htmlentities($match->GetLinkedDataUri(), ENT_QUOTES, "UTF-8", false));
     $hcal_guid->SetCssClass('uid');
     $meta->AddControl($hcal_guid);
     # hCalendar status
     $s_status = 'CONFIRMED';
     switch ($match->Result()->GetResultType()) {
         case MatchResult::CANCELLED:
         case MatchResult::POSTPONED:
         case MatchResult::AWAY_WIN_BY_FORFEIT:
         case MatchResult::HOME_WIN_BY_FORFEIT:
             $s_status = 'CANCELLED';
     }
     $meta->AddControl(' is ');
     $status = new XhtmlElement('span', $s_status);
     $status->SetCssClass('status');
     $meta->AddControl($status);
     $meta->AddControl('.');
     $li->AddControl($meta);
 }