Skip to content

Commit

Permalink
NEW Reinstated filters in ReportAdmin
Browse files Browse the repository at this point in the history
- Moved report table generation back to its original location in Report->getCMSFields(),
in order to keep it customisable rather than duplicating it in ReportAdmin.
- Using History.js to set URL state and reload panel
- Namespacing filter GET parameters in order to only include them in URL state
  • Loading branch information
chillu committed Jul 12, 2012
1 parent d77c43d commit 57c615d
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 157 deletions.
42 changes: 4 additions & 38 deletions code/controllers/ReportAdmin.php
Expand Up @@ -51,6 +51,7 @@ public function init() {


// Always block the HtmlEditorField.js otherwise it will be sent with an ajax request // Always block the HtmlEditorField.js otherwise it will be sent with an ajax request
Requirements::block(FRAMEWORK_DIR . '/javascript/HtmlEditorField.js'); Requirements::block(FRAMEWORK_DIR . '/javascript/HtmlEditorField.js');
Requirements::javascript(CMS_DIR . '/javascript/ReportAdmin.js');
} }


/** /**
Expand Down Expand Up @@ -147,48 +148,12 @@ function providePermissions() {
} }


public function getEditForm($id = null, $fields = null) { public function getEditForm($id = null, $fields = null) {
$fields = new FieldList();

$report = $this->reportObject; $report = $this->reportObject;

if($report) { if($report) {
// List all reports $fields = $report->getCMSFields();
$gridFieldConfig = GridFieldConfig::create()->addComponents(
new GridFieldToolbarHeader(),
new GridFieldSortableHeader(),
new GridFieldDataColumns(),
new GridFieldPaginator(),
new GridFieldPrintButton(),
new GridFieldExportButton()
);
$gridField = new GridField('Report',$report->title(), $report->sourceRecords(array(), null, null), $gridFieldConfig);
$columns = $gridField->getConfig()->getComponentByType('GridFieldDataColumns');
$displayFields = array();
$fieldCasting = array();
$fieldFormatting = array();

// Parse the column information
foreach($report->columns() as $source => $info) {
if(is_string($info)) $info = array('title' => $info);

if(isset($info['formatting'])) $fieldFormatting[$source] = $info['formatting'];
if(isset($info['csvFormatting'])) $csvFieldFormatting[$source] = $info['csvFormatting'];
if(isset($info['casting'])) $fieldCasting[$source] = $info['casting'];

if(isset($info['link']) && $info['link']) {
$link = singleton('CMSPageEditController')->Link('show');
$fieldFormatting[$source] = '<a href=\"' . $link . '/$ID\">$value</a>';
}

$displayFields[$source] = isset($info['title']) ? $info['title'] : $source;
}
$columns->setDisplayFields($displayFields);
$columns->setFieldCasting($fieldCasting);
$columns->setFieldFormatting($fieldFormatting);

$fields->push($gridField);
} else { } else {
// List all reports // List all reports
$fields = new FieldList();
$gridFieldConfig = GridFieldConfig::create()->addComponents( $gridFieldConfig = GridFieldConfig::create()->addComponents(
new GridFieldToolbarHeader(), new GridFieldToolbarHeader(),
new GridFieldSortableHeader(), new GridFieldSortableHeader(),
Expand All @@ -210,6 +175,7 @@ public function getEditForm($id = null, $fields = null) {
$actions = new FieldList(); $actions = new FieldList();
$form = new Form($this, "EditForm", $fields, $actions); $form = new Form($this, "EditForm", $fields, $actions);
$form->addExtraClass('cms-edit-form cms-panel-padded center ' . $this->BaseCSSClasses()); $form->addExtraClass('cms-edit-form cms-panel-padded center ' . $this->BaseCSSClasses());
$form->loadDataFrom($this->request->getVars());


$this->extend('updateEditForm', $form); $this->extend('updateEditForm', $form);


Expand Down
175 changes: 56 additions & 119 deletions code/reports/Report.php
Expand Up @@ -97,8 +97,7 @@ function description() {
*/ */
function sourceQuery($params) { function sourceQuery($params) {
if($this->hasMethod('sourceRecords')) { if($this->hasMethod('sourceRecords')) {
$query = new SS_Report_FakeQuery($this, 'sourceRecords', $params); return $this->sourceRecords()->dataQuery();
return $query;
} else { } else {
user_error("Please override sourceQuery()/sourceRecords() and columns() or, if necessary, override getReportField()", E_USER_ERROR); user_error("Please override sourceQuery()/sourceRecords() and columns() or, if necessary, override getReportField()", E_USER_ERROR);
} }
Expand All @@ -108,14 +107,20 @@ function sourceQuery($params) {
* Return a SS_List records for this report. * Return a SS_List records for this report.
*/ */
function records($params) { function records($params) {
if($this->hasMethod('sourceRecords')) return $this->sourceRecords($params, null, null); if($this->hasMethod('sourceRecords')) {
else { return $this->sourceRecords($params, null, null);
} else {
$query = $this->sourceQuery(); $query = $this->sourceQuery();
return singleton($this->dataClass())->buildDataObjectSet($query->execute(), "DataObjectSet", $query); $results = new ArrayList();
foreach($query->execute() as $data) {
$class = $this->dataClass();
$result = new $class($data);
$results->push($result);
}
return $results;
} }
} }



/** /**
* Return the data class for this report * Return the data class for this report
*/ */
Expand All @@ -132,8 +137,6 @@ function getLink($action = null) {
); );
} }




/** /**
* @deprecated 3.0 * @deprecated 3.0
* All subclasses of SS_Report now appear in the report admin, no need to register or unregister. * All subclasses of SS_Report now appear in the report admin, no need to register or unregister.
Expand Down Expand Up @@ -171,7 +174,6 @@ static function add_excluded_reports($reportClass) {
} }
} }



/** /**
* Return an array of excluded reports. That is, reports that will not be included in * Return an array of excluded reports. That is, reports that will not be included in
* the list of reports in report admin in the CMS. * the list of reports in report admin in the CMS.
Expand Down Expand Up @@ -225,31 +227,31 @@ static function get_reports() {
* @return FieldList * @return FieldList
*/ */
function getCMSFields() { function getCMSFields() {
$fields = new FieldList( $fields = new FieldList();
new LiteralField(
'ReportTitle', if($title = $this->title()) {
"<h3>{$this->title()}</h3>" $fields->push(new LiteralField('ReportTitle', "<h3>{$title}</h3>"));
) }
);


if($this->description()) $fields->push( if($description = $this->description()) {
new LiteralField('ReportDescription', "<p>" . $this->description() . "</p>")); $fields->push(new LiteralField('ReportDescription', "<p>" . $description . "</p>"));
}


// Add search fields is available // Add search fields is available
if($params = $this->parameterFields()) { if($fields = $this->parameterFields()) {
$filters = new FieldGroup('Filters'); foreach($fields as $field) {
foreach($params as $param) { // Namespace fields for easier handling in form submissions
if ($param instanceof HiddenField) $fields->push($param); $field->setName(sprintf('filters[%s]', $field->getName()));
else $filters->push($param); $field->addExtraClass('no-change-track'); // ignore in changetracker
$fields->push($field);
} }
$fields->push($filters);


// Add a search button // Add a search button
$fields->push(new FormAction('updatereport', 'Filter')); $fields->push(new FormAction('updatereport', _t('GridField.Filter')));
} }


$fields->push($this->getReportField()); $fields->push($this->getReportField());

$this->extend('updateCMSFields', $fields); $this->extend('updateCMSFields', $fields);


return $fields; return $fields;
Expand All @@ -263,7 +265,7 @@ function getCMSActions() {
} }


/** /**
* Return a field, such as a {@link ComplexTableField} that is * Return a field, such as a {@link GridField} that is
* used to show and manipulate data relating to this report. * used to show and manipulate data relating to this report.
* *
* Generally, you should override {@link columns()} and {@link records()} to make your report, * Generally, you should override {@link columns()} and {@link records()} to make your report,
Expand All @@ -272,40 +274,44 @@ function getCMSActions() {
* @return FormField subclass * @return FormField subclass
*/ */
function getReportField() { function getReportField() {
$columnTitles = array(); // TODO Remove coupling with global state
$fieldFormatting = array(); $params = isset($_REQUEST['filters']) ? $_REQUEST['filters'] : array();
$csvFieldFormatting = array(); $items = $this->sourceRecords($params, null, null);

$gridFieldConfig = GridFieldConfig::create()->addComponents(
new GridFieldToolbarHeader(),
new GridFieldSortableHeader(),
new GridFieldDataColumns(),
new GridFieldPaginator(),
new GridFieldPrintButton(),
new GridFieldExportButton()
);
$gridField = new GridField('Report',$this->title(), $items, $gridFieldConfig);
$columns = $gridField->getConfig()->getComponentByType('GridFieldDataColumns');
$displayFields = array();
$fieldCasting = array(); $fieldCasting = array();

$fieldFormatting = array();

// Parse the column information // Parse the column information
foreach($this->columns() as $source => $info) { foreach($this->columns() as $source => $info) {
if(is_string($info)) $info = array('title' => $info); if(is_string($info)) $info = array('title' => $info);


if(isset($info['formatting'])) $fieldFormatting[$source] = $info['formatting']; if(isset($info['formatting'])) $fieldFormatting[$source] = $info['formatting'];
if(isset($info['csvFormatting'])) $csvFieldFormatting[$source] = $info['csvFormatting']; if(isset($info['csvFormatting'])) $csvFieldFormatting[$source] = $info['csvFormatting'];
if(isset($info['casting'])) $fieldCasting[$source] = $info['casting']; if(isset($info['casting'])) $fieldCasting[$source] = $info['casting'];
$columnTitles[$source] = isset($info['title']) ? $info['title'] : $source;
} if(isset($info['link']) && $info['link']) {

$link = singleton('CMSPageEditController')->Link('show');
// To do: implement pagination $fieldFormatting[$source] = '<a href=\"' . $link . '/$ID\">$value</a>';
$query = $this->sourceQuery($_REQUEST); }


$tlf = new TableListField('ReportContent', $this->dataClass(), $columnTitles); $displayFields[$source] = isset($info['title']) ? $info['title'] : $source;
$tlf->setCustomQuery($query);
$tlf->setShowPagination(true);
$tlf->setPageSize(50);
$tlf->setPermissions(array('export', 'print'));

// Hack to figure out if we are printing
if (isset($_REQUEST['url']) && array_pop(explode('/', $_REQUEST['url'])) == 'printall') {
$tlf->setTemplate('SSReportTableField');
} }

$columns->setDisplayFields($displayFields);
if($fieldFormatting) $tlf->setFieldFormatting($fieldFormatting); $columns->setFieldCasting($fieldCasting);
if($csvFieldFormatting) $tlf->setCSVFieldFormatting($csvFieldFormatting); $columns->setFieldFormatting($fieldFormatting);
if($fieldCasting) $tlf->setFieldCasting($fieldCasting);


return $tlf; return $gridField;
} }


/** /**
Expand All @@ -332,76 +338,7 @@ function canView($member = null) {
function TreeTitle() { function TreeTitle() {
return $this->title(); return $this->title();
} }



}

/**
* This is an object that can be used to dress up a more complex querying mechanism in the clothing
* of a SQLQuery object. This means that you can inject it into a TableListField.
*
* Use it like this:
*
* function sourceQuery($params) {
* return new SS_Report_FakeQuery($this, 'sourceRecords', $params)
* }
* function sourceRecords($params, $sort, $limit) {
* // Do some stuff
* // Return a SS_List of actual objects.
* }
*
* This object is used by the default implementation of sourceQuery() on SS_Report, to make use of
* a sourceReords() method if one exists.
*/
class SS_Report_FakeQuery extends SQLQuery {
public $orderby;
public $limit;

protected $obj, $method, $params;

function __construct($obj, $method, $params) {
$this->obj = $obj;
$this->method = $method;
$this->params = $params;
}


/**
* Provide a method that will return a list of columns that can be used to sort.
*/
function setSortColumnMethod($sortColMethod) {
$this->sortColMethod = $sortColMethod;
}

function limit($limit, $offset = 0) {
$this->limit = $limit;
}

function unlimitedRowCount($column = null) {
$source = $this->obj->{$this->method}($this->params, null, null);
return $source ? $source->Count() : 0;
}

function execute() {
$output = array();
$source = $this->obj->{$this->method}($this->params, $this->orderby, $this->limit);
if($source) foreach($source as $item) {
$mapItem = $item->toMap();
$mapItem['RecordClassName'] = get_class($item);
$output[] = $mapItem;
}
return $output;
}

function canSortBy($fieldName) {
$fieldName = preg_replace('/(\s+?)(A|DE)SC$/', '', $fieldName);
if($this->sortColMethod) {
$columns = $this->obj->{$this->sortColMethod}();
return in_array($fieldName, $columns);
} else {
return false;
}
}
} }


/** /**
Expand Down
18 changes: 18 additions & 0 deletions javascript/ReportAdmin.js
@@ -0,0 +1,18 @@
/**
* File: ReportAdmin.js
*/

(function($) {
$.entwine('ss', function($){
$('.ReportAdmin .cms-edit-form').entwine({
onsubmit: function(e) {
var url = document.location.href, params = this.find(':input[name^=filters]').serializeArray();
params = $.grep(params, function(param) {return (param.value);}); // filter out empty
if(params) url = $.path.addSearchParams(url, params);
$('.cms-container').loadPanel(url);
return false;
}
});

});
})(jQuery);

0 comments on commit 57c615d

Please sign in to comment.