17 require_once(
"AWLUtilities.php");
22 $BrowserCurrentRow = (object) array();
69 function __construct( $field, $header=
"", $align=
"", $format=
"", $sql=
"", $class=
"", $datatype=
"", $hook=null ) {
70 $this->Field = $field;
72 $this->Header = $header;
73 $this->Format = $format;
74 $this->Class = $class;
75 $this->Align = $align;
76 $this->Type = $datatype;
77 $this->Translatable =
false;
87 if ( $this->Sql ==
"" )
return $this->Field;
88 return "$this->Sql AS $this->Field";
104 function RenderHeader( $order_field, $order_direction, $browser_array_key=0, $forced_order=
false ) {
106 if ( $this->Align ==
"" ) $this->Align =
"left";
107 $html =
'<th class="'.$this->Align.
'" '. ($this->Class ==
"" ?
"" :
"class=\"$this->Class\"") .
'>';
111 if ( !$forced_order && $order_field == $this->Field ) {
112 if ( strtoupper( substr( $order_direction, 0, 1) ) ==
'A' ) {
119 $image =
"<img class=\"order\" src=\"$c->images/$image.gif\" alt=\"$image\" />";
121 if ( !isset($browser_array_key) || $browser_array_key ==
'' ) $browser_array_key = 0;
122 if ( !$forced_order ) $html .=
'<a href="'.replace_uri_params( $_SERVER[
'REQUEST_URI'], array(
"o[$browser_array_key]" => $this->Field,
"d[$browser_array_key]" => $direction ) ).
'" class="order">';
123 $html .= ($this->Header ==
"" ? $this->Field : $this->Header);
124 if ( !$forced_order ) $html .=
"$image</a>";
129 function SetTranslatable() {
130 $this->Translatable =
true;
133 function RenderValue( $value, $extraclass =
"" ) {
136 if ( $this->Type ==
'date' || $this->Type ==
'timestamp') {
137 $value = $session->FormattedDate( $value, $this->Type );
140 if ( $this->Hook && function_exists($this->Hook) ) {
141 dbg_error_log(
"Browser",
":Browser: Hook for $this->Hook on column $this->Field");
142 $value = call_user_func( $this->Hook, $value, $this->Field, $this->current_row );
145 if ( $this->Translatable ) {
146 $value = translate($value);
149 $value = str_replace(
"\n",
"<br />", $value );
150 if ( substr(strtolower($this->Format),0,3) ==
"<td" ) {
151 $html = sprintf($this->Format,$value);
156 $class = $this->Align . ($this->Class ==
"" ?
"" :
" $this->Class") . ($extraclass ==
"" ?
"" :
" $extraclass");
157 if ( $class !=
"" ) $class =
' class="'.$class.
'"';
158 $html = sprintf(
'<td%s>',$class);
159 $html .= ($this->Format ==
"" ? $value : sprintf($this->Format,$value,$value));
188 var $OrderBrowserKey;
199 var $BeginExtraRowArgs;
216 $this->
Title = $title;
217 $this->SubTitle =
"";
218 $this->Distinct =
"";
222 $this->BeginRow =
"<tr class=\"row%d\">\n";
223 $this->CloseRow =
"</tr>\n";
224 $this->BeginRowArgs = array(
'#even');
225 $this->Totals = array();
226 $this->Columns = array();
227 $this->HiddenColumns = array();
228 $this->FieldNames = array();
229 $this->DivOpen =
'<div id="browser">';
230 $this->DivClose =
'</div>';
231 $this->ForcedOrder =
false;
232 dbg_error_log(
"Browser",
":Browser: New browser called $title");
260 function AddColumn( $field, $header=
"", $align=
"", $format=
"", $sql=
"", $class=
"", $datatype=
"", $hook=null ) {
261 $this->Columns[] =
new BrowserColumn( $field, $header, $align, $format, $sql, $class, $datatype, $hook );
262 $this->FieldNames[$field] = count($this->Columns) - 1;
276 $this->HiddenColumns[] =
new BrowserColumn( $field,
"",
"",
"", $sql );
277 $this->FieldNames[$field] = count($this->Columns) - 1;
290 $this->
Title = $new_title;
300 function Title( $new_title = null ) {
301 if ( isset($new_title) ) $this->
Title = $new_title;
312 $top = count($this->Columns);
313 for( $i=0; $i < $top; $i++ ) {
314 dbg_error_log(
"Browser",
"Comparing %s with column name list", $this->Columns[$i]->Field);
315 if ( in_array($this->Columns[$i]->Field,$column_list) ) $this->Columns[$i]->SetTranslatable();
317 $top = count($this->HiddenColumns);
318 for( $i=0; $i < $top; $i++ ) {
319 dbg_error_log(
"Browser",
"Comparing %s with column name list", $this->HiddenColumns[$i]->Field);
320 if ( in_array($this->HiddenColumns[$i]->Field,$column_list) ) $this->HiddenColumns[$i]->SetTranslatable();
330 $this->SubTitle = $sub_title;
339 function SetDiv( $open_div, $close_div ) {
340 $this->DivOpen = $open_div;
341 $this->DivClose = $close_div;
354 $this->Joins = $join_list;
367 $this->Union = $union_select;
378 $this->Where = $where_clause;
389 $this->Distinct =
"DISTINCT ".$distinct;
400 $this->Limit =
"LIMIT ".intval($limit_n);
411 $this->Offset =
"OFFSET ".intval($offset_n);
424 if ( $this->Where ==
"" ) {
425 $this->Where = $more_where;
428 $this->Where =
"$this->Where $operator $more_where";
449 function AddGrouping( $field, $browser_array_key=0 ) {
450 if ( $this->Grouping ==
"" )
451 $this->Grouping =
"GROUP BY ";
453 $this->Grouping .=
", ";
455 $this->Grouping .= clean_string($field);
474 function AddOrder( $field, $direction, $browser_array_key=0, $secondary=0 ) {
475 $field = check_by_regex($field,
'/^[^\'"!\\\\()\[\]|*\/{}&%@~;:?<>]+$/');
476 if ( ! isset($this->FieldNames[$field]) )
return;
478 if ( !isset($this->Order) || $this->Order ==
"" )
479 $this->Order =
"ORDER BY ";
481 $this->Order .=
", ";
483 if ( $secondary == 0 ) {
484 $this->OrderField = $field;
485 $this->OrderBrowserKey = $browser_array_key;
487 $this->Order .= $field;
489 if ( preg_match(
'/^A/i', $direction) ) {
490 $this->Order .=
" ASC";
491 if ( $secondary == 0)
492 $this->OrderDirection =
'A';
495 $this->Order .=
" DESC";
496 if ( $secondary == 0)
497 $this->OrderDirection =
'D';
509 $field = clean_string($field);
510 if ( ! isset($this->FieldNames[$field]) )
return;
512 if ( $this->Order ==
"" )
513 $this->Order =
"ORDER BY ";
515 $this->Order .=
", ";
517 $this->Order .= $field;
519 if ( preg_match(
'/^A/i', $direction) ) {
520 $this->Order .=
" ASC";
523 $this->Order .=
" DESC";
526 $this->ForcedOrder =
true;
535 function SetOrdering( $default_fld=null, $default_dir=
'A' , $browser_array_key=0 ) {
536 if ( isset( $_GET[
'o'][$browser_array_key] ) && isset($_GET[
'd'][$browser_array_key] ) ) {
537 $this->
AddOrder( $_GET[
'o'][$browser_array_key], $_GET[
'd'][$browser_array_key], $browser_array_key );
540 if ( ! isset($default_fld) ) $default_fld = $this->Columns[0];
541 $this->
AddOrder( $default_fld, $default_dir, $browser_array_key );
557 function AddTotal( $column_name, $total_function =
false ) {
558 $this->Totals[$column_name] = 0;
559 if ( $total_function !=
false ) {
560 $this->TotalFuncs[$column_name] = $total_function;
571 return $this->Totals[$column_name];
599 $argc = func_num_args();
600 $this->BeginRow = func_get_arg(0);
601 $this->CloseRow = func_get_arg(1);
603 $this->BeginRowArgs = array();
604 for( $i=2; $i < $argc; $i++ ) {
605 $this->BeginRowArgs[] = func_get_arg($i);
624 $argc = func_num_args();
625 $this->BeginExtraRow = func_get_arg(0);
626 $this->CloseExtraRow = func_get_arg(1);
628 $this->BeginExtraRowArgs = array();
629 for( $i=2; $i < $argc; $i++ ) {
630 $this->BeginExtraRowArgs[] = func_get_arg($i);
645 foreach( $this->Columns AS $k => $column ) {
646 if ( $target_fields !=
"" ) $target_fields .=
", ";
647 $target_fields .= $column->GetTarget();
649 if ( isset($this->HiddenColumns) ) {
650 foreach( $this->HiddenColumns AS $k => $column ) {
651 if ( $target_fields !=
"" ) $target_fields .=
", ";
652 $target_fields .= $column->GetTarget();
655 $where_clause = ((isset($this->Where) && $this->Where !=
"") ?
"WHERE $this->Where" :
"" );
656 $sql = sprintf(
"SELECT %s %s FROM %s %s %s ", $this->Distinct, $target_fields,
657 $this->Joins, $where_clause, $this->Grouping );
658 if (
"$this->Union" !=
"" ) {
659 $sql .=
"UNION $this->Union ";
661 $sql .= $this->Order .
' ' . $this->Limit .
' ' . $this->Offset;
662 $this->Query =
new AwlQuery( $sql );
663 return $this->Query->Exec(
"Browse:$this->Title:DoQuery");
672 function AddRow( $column_values ) {
673 if ( !isset($this->ExtraRows) || typeof($this->ExtraRows) !=
'array' ) $this->ExtraRows = array();
674 $this->ExtraRows[] = &$column_values;
686 $this->match_column = $column;
687 $this->match_value = $value;
688 $this->match_function = $function;
707 $field_name = $matches[1];
708 if ( !isset($this->current_row->{$field_name}) && substr($field_name,0,4) ==
"URL:" ) {
709 $field_name = substr($field_name,4);
710 $replacement = urlencode($this->current_row->{$field_name});
713 $replacement = (isset($this->current_row->{$field_name}) ? $this->current_row->{$field_name} :
'');
715 dbg_error_log(
"Browser",
":ValueReplacement: Replacing %s with %s", $field_name, $replacement);
730 function Render( $title_tag = null, $subtitle_tag = null ) {
731 global $c, $BrowserCurrentRow;
733 if ( !isset($this->Query) ) $this->DoQuery();
735 dbg_error_log(
"Browser",
":Render: browser $this->Title");
736 $html = $this->DivOpen;
737 if ( $this->Title !=
"" ) {
738 if ( !isset($title_tag) ) $title_tag =
'h1';
739 $html .=
"<$title_tag>$this->Title</$title_tag>\n";
741 if ( $this->SubTitle !=
"" ) {
742 if ( !isset($subtitle_tag) ) $subtitle_tag =
'h2';
743 $html .=
"<$subtitle_tag>$this->SubTitle</$subtitle_tag>\n";
746 $html .=
"<table id=\"browse_table\">\n";
747 $html .=
"<thead><tr class=\"header\">\n";
748 foreach( $this->Columns AS $k => $column ) {
749 $html .= $column->RenderHeader( $this->OrderField, $this->OrderDirection, $this->OrderBrowserKey, $this->ForcedOrder );
751 $html .=
"</tr></thead>\n<tbody>";
753 $rowanswers = array();
754 while( $BrowserCurrentRow = $this->Query->Fetch() ) {
758 foreach( $this->BeginRowArgs AS $k => $fld ) {
759 if ( isset($BrowserCurrentRow->{$fld}) ) {
760 $rowanswers[$k] = $BrowserCurrentRow->{$fld};
765 $rowanswers[$k] = ($this->Query->rownum() % 2);
768 $rowanswers[$k] = $fld;
773 $row_html = vsprintf( preg_replace(
"/#@even@#/", ($this->Query->rownum() % 2), $this->BeginRow), $rowanswers);
775 if ( isset($this->match_column) && isset($this->match_value) && $BrowserCurrentRow->{$this->match_column} == $this->match_value ) {
776 $row_html .= call_user_func( $this->match_function, $BrowserCurrentRow );
780 foreach( $this->Columns AS $k => $column ) {
781 $row_html .= $column->RenderValue( (isset($BrowserCurrentRow->{$column->Field})?$BrowserCurrentRow->{$column->Field}:
'') );
782 if ( isset($this->Totals[$column->Field]) ) {
783 if ( isset($this->TotalFuncs[$column->Field]) && function_exists($this->TotalFuncs[$column->Field]) ) {
785 $this->Totals[$column->Field] += $this->TotalFuncs[$column->Field]( $BrowserCurrentRow, $BrowserCurrentRow->{$column->Field} );
789 $this->Totals[$column->Field] += doubleval( preg_replace(
'/[^0-9.-]/',
'', $BrowserCurrentRow->{$column->Field} ));
796 $row_html .= preg_replace(
"/#@even@#/", ($this->Query->rownum() % 2), $this->CloseRow);
797 $this->current_row = $BrowserCurrentRow;
798 $html .= preg_replace_callback(
"/##([^#]+)##/", array( &$this,
"ValueReplacement"), $row_html );
801 if ( count($this->Totals) > 0 ) {
802 $BrowserCurrentRow = (object)
"";
803 $row_html =
"<tr class=\"totals\">\n";
804 foreach( $this->Columns AS $k => $column ) {
805 if ( isset($this->Totals[$column->Field]) ) {
806 $row_html .= $column->RenderValue( $this->Totals[$column->Field],
"totals" );
809 $row_html .= $column->RenderValue(
"" );
812 $row_html .=
"</tr>\n";
813 $this->current_row = $BrowserCurrentRow;
814 $html .= preg_replace_callback(
"/##([^#]+)##/", array( &$this,
"ValueReplacement"), $row_html );
818 if ( count($this->ExtraRows) > 0 ) {
819 if ( !isset($this->BeginExtraRow) )
820 $this->BeginExtraRow = $this->BeginRow;
821 if ( !isset($this->CloseExtraRow) )
822 $this->CloseExtraRow = $this->CloseRow;
823 if ( !isset($this->BeginExtraRowArgs) )
824 $this->BeginExtraRowArgs = $this->BeginRowArgs;
826 foreach( $this->ExtraRows AS $k => $v ) {
827 $BrowserCurrentRow = (object) $v;
829 foreach( $this->BeginExtraRowArgs AS $k => $fld ) {
830 if ( isset( $BrowserCurrentRow->{$fld} ) ) {
831 $rowanswers[$k] = $BrowserCurrentRow->{$fld};
836 $rowanswers[$k] = ($this->Query->rownum() % 2);
839 $rowanswers[$k] = $fld;
845 $row_html = vsprintf( preg_replace(
"/#@even@#/", ($this->Query->rownum() % 2), $this->BeginExtraRow), $rowanswers);
847 if ( isset($this->match_column) && isset($this->match_value) && $BrowserCurrentRow->{$this->match_column} == $this->match_value ) {
848 $row_html .= call_user_func( $this->match_function, $BrowserCurrentRow );
852 foreach( $this->Columns AS $k => $column ) {
853 $row_html .= $column->RenderValue( (isset($BrowserCurrentRow->{$column->Field}) ? $BrowserCurrentRow->{$column->Field} :
'') );
858 $row_html .= preg_replace(
"/#@even@#/", ($this->Query->rownum() % 2), $this->CloseExtraRow);
859 $this->current_row = $BrowserCurrentRow;
860 $html .= preg_replace_callback(
"/##([^#]+)##/", array( &$this,
"ValueReplacement"), $row_html );
864 $html .=
"</tbody>\n</table>\n";
865 $html .= $this->DivClose;
AddColumn($field, $header="", $align="", $format="", $sql="", $class="", $datatype="", $hook=null)
RenderHeader($order_field, $order_direction, $browser_array_key=0, $forced_order=false)
RowFormat($beginrow, $closerow, $rowargs)
Render($title_tag=null, $subtitle_tag=null)
AddTotal($column_name, $total_function=false)
AddOrder($field, $direction, $browser_array_key=0, $secondary=0)
MoreWhere($operator, $more_where)
AddHidden($field, $sql="")
ForceOrder($field, $direction)
SetDiv($open_div, $close_div)
ValueReplacement($matches)
MatchedRow($column, $value, $function)
ExtraRowFormat($beginrow, $closerow, $rowargs)
SetOrdering($default_fld=null, $default_dir='A', $browser_array_key=0)
SetTranslatable($column_list)
__construct($field, $header="", $align="", $format="", $sql="", $class="", $datatype="", $hook=null)