192 var $OrderBrowserKey;
203 var $BeginExtraRowArgs;
221 $this->
Title = $title;
222 $this->SubTitle =
"";
223 $this->Distinct =
"";
227 $this->BeginRow =
"<tr class=\"row%d\">\n";
228 $this->CloseRow =
"</tr>\n";
229 $this->BeginRowArgs = array(
'#even');
230 $this->Totals = array();
231 $this->Columns = array();
232 $this->HiddenColumns = array();
233 $this->FieldNames = array();
234 $this->DivOpen =
'<div id="browser">';
235 $this->DivClose =
'</div>';
236 $this->ForcedOrder =
false;
237 dbg_error_log(
"Browser",
":Browser: New browser called $title");
265 function AddColumn( $field, $header=
"", $align=
"", $format=
"", $sql=
"", $class=
"", $datatype=
"", $hook=
null ) {
266 $this->Columns[] =
new BrowserColumn( $field, $header, $align, $format, $sql, $class, $datatype, $hook );
267 $this->FieldNames[$field] = count($this->Columns) - 1;
281 $this->HiddenColumns[] =
new BrowserColumn( $field,
"",
"",
"", $sql );
282 $this->FieldNames[$field] = count($this->Columns) - 1;
295 $this->
Title = $new_title;
305 function Title( $new_title =
null ) {
306 if ( isset($new_title) ) $this->
Title = $new_title;
317 $top = count($this->Columns);
318 for( $i=0; $i < $top; $i++ ) {
319 dbg_error_log(
"Browser",
"Comparing %s with column name list", $this->Columns[$i]->Field);
320 if ( in_array($this->Columns[$i]->Field,$column_list) ) $this->Columns[$i]->SetTranslatable();
322 $top = count($this->HiddenColumns);
323 for( $i=0; $i < $top; $i++ ) {
324 dbg_error_log(
"Browser",
"Comparing %s with column name list", $this->HiddenColumns[$i]->Field);
325 if ( in_array($this->HiddenColumns[$i]->Field,$column_list) ) $this->HiddenColumns[$i]->SetTranslatable();
335 $this->SubTitle = $sub_title;
344 function SetDiv( $open_div, $close_div ) {
345 $this->DivOpen = $open_div;
346 $this->DivClose = $close_div;
359 $this->Joins = $join_list;
372 $this->Union = $union_select;
383 $this->Where = $where_clause;
394 $this->Distinct =
"DISTINCT ".$distinct;
405 $this->Limit =
"LIMIT ".intval($limit_n);
416 $this->Offset =
"OFFSET ".intval($offset_n);
429 if ( $this->Where ==
"" ) {
430 $this->Where = $more_where;
433 $this->Where =
"$this->Where $operator $more_where";
454 function AddGrouping( $field, $browser_array_key=0 ) {
455 if ( $this->Grouping ==
"" )
456 $this->Grouping =
"GROUP BY ";
458 $this->Grouping .=
", ";
460 $this->Grouping .= clean_string($field);
479 function AddOrder( $field, $direction, $browser_array_key=0, $secondary=0 ) {
480 $field = check_by_regex($field,
'/^[^\'"!\\\\()\[\]|*\/{}&%@~;:?<>]+$/');
481 if ( ! isset($this->FieldNames[$field]) )
return;
483 if ( !isset($this->Order) || $this->Order ==
"" )
484 $this->Order =
"ORDER BY ";
486 $this->Order .=
", ";
488 if ( $secondary == 0 ) {
489 $this->OrderField = $field;
490 $this->OrderBrowserKey = $browser_array_key;
492 $this->Order .= $field;
494 if ( preg_match(
'/^A/i', $direction) ) {
495 $this->Order .=
" ASC";
496 if ( $secondary == 0)
497 $this->OrderDirection =
'A';
500 $this->Order .=
" DESC";
501 if ( $secondary == 0)
502 $this->OrderDirection =
'D';
513 function ForceOrder( $field, $direction ) {
514 $field = clean_string($field);
515 if ( ! isset($this->FieldNames[$field]) )
return;
517 if ( $this->Order ==
"" )
518 $this->Order =
"ORDER BY ";
520 $this->Order .=
", ";
522 $this->Order .= $field;
524 if ( preg_match(
'/^A/i', $direction) ) {
525 $this->Order .=
" ASC";
528 $this->Order .=
" DESC";
531 $this->ForcedOrder =
true;
540 function SetOrdering( $default_fld=
null, $default_dir=
'A' , $browser_array_key=0 ) {
541 if ( isset( $_GET[
'o'][$browser_array_key] ) && isset($_GET[
'd'][$browser_array_key] ) ) {
542 $this->
AddOrder( $_GET[
'o'][$browser_array_key], $_GET[
'd'][$browser_array_key], $browser_array_key );
545 if ( ! isset($default_fld) ) $default_fld = $this->Columns[0];
546 $this->
AddOrder( $default_fld, $default_dir, $browser_array_key );
562 function AddTotal( $column_name, $total_function =
false ) {
563 $this->Totals[$column_name] = 0;
564 if ( $total_function !=
false ) {
565 $this->TotalFuncs[$column_name] = $total_function;
575 function GetTotal( $column_name ) {
576 return $this->Totals[$column_name];
602 function RowFormat( $beginrow, $closerow, $rowargs )
604 $argc = func_num_args();
605 $this->BeginRow = func_get_arg(0);
606 $this->CloseRow = func_get_arg(1);
608 $this->BeginRowArgs = array();
609 for( $i=2; $i < $argc; $i++ ) {
610 $this->BeginRowArgs[] = func_get_arg($i);
627 function ExtraRowFormat( $beginrow, $closerow, $rowargs )
629 $argc = func_num_args();
630 $this->BeginExtraRow = func_get_arg(0);
631 $this->CloseExtraRow = func_get_arg(1);
633 $this->BeginExtraRowArgs = array();
634 for( $i=2; $i < $argc; $i++ ) {
635 $this->BeginExtraRowArgs[] = func_get_arg($i);
650 foreach( $this->Columns AS $k => $column ) {
651 if ( $target_fields !=
"" ) $target_fields .=
", ";
652 $target_fields .= $column->GetTarget();
654 if ( isset($this->HiddenColumns) ) {
655 foreach( $this->HiddenColumns AS $k => $column ) {
656 if ( $target_fields !=
"" ) $target_fields .=
", ";
657 $target_fields .= $column->GetTarget();
660 $where_clause = ((isset($this->Where) && $this->Where !=
"") ?
"WHERE $this->Where" :
"" );
661 $sql = sprintf(
"SELECT %s %s FROM %s %s %s ", $this->Distinct, $target_fields,
662 $this->Joins, $where_clause, $this->Grouping );
663 if (
"$this->Union" !=
"" ) {
664 $sql .=
"UNION $this->Union ";
666 $sql .= $this->Order .
' ' . $this->Limit .
' ' . $this->Offset;
667 $this->Query =
new AwlQuery( $sql );
668 return $this->Query->Exec(
"Browse:$this->Title:DoQuery");
677 function AddRow( $column_values ) {
678 if ( !isset($this->ExtraRows) || typeof($this->ExtraRows) !=
'array' ) $this->ExtraRows = array();
679 $this->ExtraRows[] = &$column_values;
690 function MatchedRow( $column, $value, $function ) {
691 $this->match_column = $column;
692 $this->match_value = $value;
693 $this->match_function = $function;
706 function ValueReplacement($matches)
712 $field_name = $matches[1];
713 if ( !isset($this->current_row->{$field_name}) && substr($field_name,0,4) ==
"URL:" ) {
714 $field_name = substr($field_name,4);
715 $replacement = urlencode($this->current_row->{$field_name});
718 $replacement = (isset($this->current_row->{$field_name}) ? $this->current_row->{$field_name} :
'');
720 dbg_error_log(
"Browser",
":ValueReplacement: Replacing %s with %s", $field_name, $replacement);
735 function Render( $title_tag =
null, $subtitle_tag =
null ) {
736 global $c, $BrowserCurrentRow;
738 if ( !isset($this->Query) ) $this->DoQuery();
740 dbg_error_log(
"Browser",
":Render: browser $this->Title");
741 $html = $this->DivOpen;
742 if ( $this->Title !=
"" ) {
743 if ( !isset($title_tag) ) $title_tag =
'h1';
744 $html .=
"<$title_tag>$this->Title</$title_tag>\n";
746 if ( $this->SubTitle !=
"" ) {
747 if ( !isset($subtitle_tag) ) $subtitle_tag =
'h2';
748 $html .=
"<$subtitle_tag>$this->SubTitle</$subtitle_tag>\n";
751 $html .=
"<table id=\"browse_table\">\n";
752 $html .=
"<thead><tr class=\"header\">\n";
753 foreach( $this->Columns AS $k => $column ) {
754 $html .= $column->RenderHeader( $this->OrderField, $this->OrderDirection, $this->OrderBrowserKey, $this->ForcedOrder );
756 $html .=
"</tr></thead>\n<tbody>";
758 $rowanswers = array();
759 while( $BrowserCurrentRow = $this->Query->Fetch() ) {
763 foreach( $this->BeginRowArgs AS $k => $fld ) {
764 if ( isset($BrowserCurrentRow->{$fld}) ) {
765 $rowanswers[$k] = $BrowserCurrentRow->{$fld};
770 $rowanswers[$k] = ($this->Query->rownum() % 2);
773 $rowanswers[$k] = $fld;
778 $row_html = vsprintf( preg_replace(
"/#@even@#/", ($this->Query->rownum() % 2), $this->BeginRow), $rowanswers);
780 if ( isset($this->match_column) && isset($this->match_value) && $BrowserCurrentRow->{$this->match_column} == $this->match_value ) {
781 $row_html .= call_user_func( $this->match_function, $BrowserCurrentRow );
785 foreach( $this->Columns AS $k => $column ) {
786 $row_html .= $column->RenderValue( (isset($BrowserCurrentRow->{$column->Field})?$BrowserCurrentRow->{$column->Field}:
'') );
787 if ( isset($this->Totals[$column->Field]) ) {
788 if ( isset($this->TotalFuncs[$column->Field]) && function_exists($this->TotalFuncs[$column->Field]) ) {
790 $this->Totals[$column->Field] += $this->TotalFuncs[$column->Field]( $BrowserCurrentRow, $BrowserCurrentRow->{$column->Field} );
794 $this->Totals[$column->Field] += doubleval( preg_replace(
'/[^0-9.-]/',
'', $BrowserCurrentRow->{$column->Field} ));
801 $row_html .= preg_replace(
"/#@even@#/", ($this->Query->rownum() % 2), $this->CloseRow);
802 $this->current_row = $BrowserCurrentRow;
803 $html .= preg_replace_callback(
"/##([^#]+)##/", array( &$this,
"ValueReplacement"), $row_html );
806 if ( count($this->Totals) > 0 ) {
807 $BrowserCurrentRow = (object)
"";
808 $row_html =
"<tr class=\"totals\">\n";
809 foreach( $this->Columns AS $k => $column ) {
810 if ( isset($this->Totals[$column->Field]) ) {
811 $row_html .= $column->RenderValue( $this->Totals[$column->Field],
"totals" );
814 $row_html .= $column->RenderValue(
"" );
817 $row_html .=
"</tr>\n";
818 $this->current_row = $BrowserCurrentRow;
819 $html .= preg_replace_callback(
"/##([^#]+)##/", array( &$this,
"ValueReplacement"), $row_html );
823 if ( is_array($this->ExtraRows) && count($this->ExtraRows) > 0 ) {
824 if ( !isset($this->BeginExtraRow) )
825 $this->BeginExtraRow = $this->BeginRow;
826 if ( !isset($this->CloseExtraRow) )
827 $this->CloseExtraRow = $this->CloseRow;
828 if ( !isset($this->BeginExtraRowArgs) )
829 $this->BeginExtraRowArgs = $this->BeginRowArgs;
831 foreach( $this->ExtraRows AS $k => $v ) {
832 $BrowserCurrentRow = (object) $v;
834 foreach( $this->BeginExtraRowArgs AS $k => $fld ) {
835 if ( isset( $BrowserCurrentRow->{$fld} ) ) {
836 $rowanswers[$k] = $BrowserCurrentRow->{$fld};
841 $rowanswers[$k] = ($this->Query->rownum() % 2);
844 $rowanswers[$k] = $fld;
850 $row_html = vsprintf( preg_replace(
"/#@even@#/", ($this->Query->rownum() % 2), $this->BeginExtraRow), $rowanswers);
852 if ( isset($this->match_column) && isset($this->match_value) && $BrowserCurrentRow->{$this->match_column} == $this->match_value ) {
853 $row_html .= call_user_func( $this->match_function, $BrowserCurrentRow );
857 foreach( $this->Columns AS $k => $column ) {
858 $row_html .= $column->RenderValue( (isset($BrowserCurrentRow->{$column->Field}) ? $BrowserCurrentRow->{$column->Field} :
'') );
863 $row_html .= preg_replace(
"/#@even@#/", ($this->Query->rownum() % 2), $this->CloseExtraRow);
864 $this->current_row = $BrowserCurrentRow;
865 $html .= preg_replace_callback(
"/##([^#]+)##/", array( &$this,
"ValueReplacement"), $row_html );
869 $html .=
"</tbody>\n</table>\n";
870 $html .= $this->DivClose;