From db42713e1c28780b27fc4090ed21473e0e90ae15 Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Sun, 16 Sep 2007 01:50:07 +0000 Subject: [PATCH] mlanthaler: Bugfix: Class created invalid HTML (...). (merged from branches/gsoc) git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@42020 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- forms/ReportField.php | 210 ++++++++++++++++++++++++------------------ 1 file changed, 118 insertions(+), 92 deletions(-) diff --git a/forms/ReportField.php b/forms/ReportField.php index 94027a469..b3880edcd 100755 --- a/forms/ReportField.php +++ b/forms/ReportField.php @@ -1,4 +1,6 @@ Primary Key Column", E_USER_ERROR ); else { $this->tables = array_keys( $tables ); $this->primaryKeys = $tables; - $this->primaryClass = $this->tables[0]; + $this->primaryClass = $this->tables[0]; } - + if( !is_array( $fields ) ) $this->fields = array( $fields ); else $this->fields = $this->expandWildcards( $fields ); } - + + public function setExport($export){ $this->export = $export; } - + + protected function expandWildcards( $fields ) { - + $newFields = array(); - + foreach( $fields as $field ) if( preg_match( '/.*\.\*/', $field ) ) $newFields = $newFields + $this->expandWildcard( $field ); else $newFields[] = $field; - - return $newFields; + + return $newFields; } - + + protected function expandWildcard( $field ) { list( $table, $column ) = $this->parseField( $field ); - + foreach( $this->getColumnsInTable( $table ) as $newColumn ) $columns[] = $table.'.'.$newColumn; - - return $columns; + + return $columns; } - + + function exportToCSV( $fileName ) { - - + $fileData = $this->columnheaders( 'csvRow', 'csvCell' ) . $this->datacells( 'csvRow', 'csvCell' ); - + header("Content-Type: text/csv; name=\"" . addslashes($fileName) . "\""); header("Content-Disposition: attachment; filename=\"" . addslashes($fileName) . "\""); header("Content-length: " . strlen($fileData)); - + echo $fileData; exit(); } + function FieldHolder() { Requirements::javascript("sapphire/javascript/ReportField.js"); - + $headerHTML = $this->columnheaders(); $dataCellHTML = $this->datacells(); $id = $this->id() . '_exportToCSV'; @@ -92,7 +98,7 @@ HTML }else{ $exportButton = ""; } - + // display the table of results $html = << @@ -104,232 +110,249 @@ HTML $dataCellHTML - + HTML; return $html; } - + + /** * Returns the HTML for the data cells for the current report. * This can be used externally via ajax as the report might be filtered per column. * It is also used internally to display the data cells. */ public function datacells( $rowCallBack = 'htmlTableRow', $cellCallBack = 'htmlTableCell' ) { - + // get the primary records in the database, sorted according to the current sort // this will need to be corrected later on $primaryRecords = $this->getRecords(); - + /*echo "ERROR:"; Debug::show( $primaryRecords ); die();*/ - + $html = ""; - + foreach( $primaryRecords as $record ) { $rowOutput = ""; - + foreach( $this->fields as $field ) { if( $field{0} == '!' ) $field = substr( $field, 1 ); - + list( $table, $column ) = $this->parseField( $field ); - + if( $this->filter && !$this->filter->showColumn( $table, $column ) ) continue; - + $rowOutput .= $this->$cellCallBack( $record[$field], $table, $column ); } - + $html .= $this->$rowCallBack( $rowOutput, $table, null ); - + } - + return $html; } - + + /** * Returns the HTML for the headers of the columns. * Can also be called via ajax to reload the headers. */ public function columnheaders( $rowCallBack = 'htmlTableRow', $cellCallBack = 'htmlHeaderCell' ) { - + foreach( $this->fields as $field ) { list( $table, $column ) = $this->parseField( $field ); - + if( $this->filter && !$this->filter->showColumn( $table, $column ) ) continue; // replace this with some code to show a 'hidden' column - + /*if( $column == '*' ) foreach( $this->getColumnsInTable( $table ) as $extraColumn ) - $html .= $this->$cellCallBack( $extraColumn, $table, $extraColumn ); + $html .= $this->$cellCallBack( $extraColumn, $table, $extraColumn ); else */ $html .= $this->$cellCallBack( $column, $table, $column ); } - - return $this->$rowCallBack( $html, null, null ); + + return $this->$rowCallBack( $html, null, null ); } - + + protected function getColumnsInTable( $table ) { $result = DB::query( "SELECT * FROM `$table` LIMIT 1" ); return array_keys( $result->next() ); } - + + protected function parseField( $field ) { if( $field{0} == '!' ) $field = substr( $field, 1 ); - + if( strpos( $field, '.' ) !== FALSE ) return explode( '.', $field ); else return $field; } - + + /** * Joins the given record together with the extra information in the other tables. * This is only used in a situation in which the database can't do the join and I'll * correct it when I figure out how to use buildSQL */ protected function joinRecord( $object ) { - + return $object; - + // split the list of fields into table, column and group by table. /*$tableColumns = array(); - + foreach( $this->fields as $field ) { list( $table, $column ) = $this->parseField( $field ); $tableColumns[$table][] = $column; } - + $primaryKey = $this->primaryKeys[$object->class]; - + if( !$primaryKey ) foreach( ClassInfo::ancestry( $object->class ) as $baseClass ) $primaryKey = $this->primaryKeys[$baseClass]; - + $primaryKeyValue = $object->$primaryKey; - + // get the fields from the object $completeRecord = $this->joinFields( $object, $tableColumn[$this->primaryClass] ); foreach( $tableColumns as $className => $classFields ) { $joinKey = $this->primaryKeys[$className]; - + // get the all the extra fields. $recordObj = DataObject::get_one( $className, "`$className`.`$joinKey`='$primaryKeyValue'" ); - + $completeRecord = $completeRecord + $this->joinFields( $recordObj, $fields ); } - + return $completeRecord;*/ } - + + protected function joinFields( $object, $fields ) { $partialRecord = array(); foreach( $fields as $field ) $partialRecord[$object->class.'.'.$field] = $object->$field; - + return $partialRecord; } - + + /** - * Sort the data in the cells + * Sort the data in the cells */ public function sortdata() { - + } - + + /** * Get the primary set of records for the cells. This returns a data object set. */ protected function getRecords() { - + // $_REQUEST['showqueries'] = 1; - + $tableColumns = array(); $selectFields = array(); $joins = array( "`{$this->primaryClass}`" ); - + foreach( $this->fields as $field ) { if( $field{0} == '!' ) continue; - + list( $table, $column ) = $this->parseField( $field ); $tableColumns[$table][] = $column; - + if( $column == '*' ) $selectFields[] = "`$table`.*"; else $selectFields[] = "`$table`.`$column` AS '$table.$column'"; } - + foreach( array_keys( $tableColumns ) as $table ) { $tableKey = $this->primaryKeys[$table]; $primaryKey = $this->primaryKeys[$this->primaryClass]; - + if( $table != $this->primaryClass ) $joins[] = "LEFT JOIN `$table` ON `$table`.`$tableKey`=`{$this->primaryClass}`.`$primaryKey`"; } - + $query = new SQLQuery( $selectFields, $joins ); return $query->execute(); } - + + function htmlHeaderCell( $value, $table, $column ) { return "" . htmlentities( $value ) . ""; } - + + function htmlTableCell( $value, $table, $column ) { - return "" . htmlentities( $value ) . ""; + return "" . htmlentities( $value ) . ""; } - + + function htmlTableRow( $value, $table, $column ) { return "" . $value . ""; } - + + function csvCell( $value, $table, $column ) { return '"' . str_replace( '"', '""', $value ) . '",'; } - + + function csvRow( $value, $table, $column ) { return substr( $value, 0, strlen( $value ) - 1 )."\n"; } } + + /** * Assisting class. Determines whether or not a column is hidden. * Not so helpful here, but we could overload it in other classes. */ class ReportField_SimpleFilter extends Object { - + protected $hiddenFields; - + function __construct( $hiddenColumns ) { $this->hiddenFields = $hiddenColumns; } - + function columnIsVisible( $table, $column ) { return !isset( $this->hiddenFields[$table.'.'.$column] ); } - + function showColumn( $table, $column ) { unset( $this->hiddenFields[$table.'.'.$column] ); - } - + } + function hideColumn( $table, $column ) { $this->hiddenFields[$table.'.'.$column] = 1; } } + + /** * This class instantiates an instance of the report field and receives ajax requests * to the report field. */ class ReportField_Controller extends Controller { - + function exporttocsv() { - + if( $this->urlParams['Type'] != 'ReportField' && ClassInfo::exists( $this->urlParams['Type'].'_Controller' ) ) { $type = $this->urlParams['Type'].'_Controller'; $controller = new $type(); @@ -337,28 +360,31 @@ class ReportField_Controller extends Controller { } $pageID = $this->urlParams['ID']; - + if( !$pageID ) return "ERROR:Page does not exist"; - + $page = DataObject::get_by_id( 'SiteTree', $pageID ); - + if( !$page ) return "ERROR:Page does not exist"; - - $formName = substr( $this->urlParams['OtherID'], 0, -4 ); - + + $formName = substr( $this->urlParams['OtherID'], 0, -4 ); + $reportField = $page->getReportField( $formName ); - + // apply filters - + $fileName = $page->URLSegment . "-report.csv"; - + $reportField->exportToCSV( $fileName ); } - + + function Link() { return ""; } } + + ?> \ No newline at end of file