BUG Performance improvements of SubmittedFormField queries.

When there are a lot of SubmittedForm records the UserDefinedForm
page takes a long time to load in the CMS, and oftens exceeds
the PHP memory limit well beyond 128M.

Previously UserDefinedForm::getCMSFields() would build a list of
name => value from all SubmittedFormField records, but it would
do this twice, once in getCMSFields() and another time in
UserFormsGridFieldFilterHeader. It would also use the full ORM
to build this list, when all it needs is a map of the Name
and Value columns.

This fixes that to build the columns once in getCMSFields() using
DB::query() and it'll pass those columns along to
UserFormsGridFieldFilterHeader as well so it doesn't do it twice.
This commit is contained in:
Sean Harvey 2013-11-13 16:46:13 +13:00
parent 93db1189eb
commit 425881257b
2 changed files with 29 additions and 22 deletions

View File

@ -9,6 +9,16 @@
*/
class UserFormsGridFieldFilterHeader extends GridFieldFilterHeader {
/**
* A map of name => value of columns from all submissions
* @var array
*/
protected $columns;
public function setColumns($columns) {
$this->columns = $columns;
}
public function handleAction(GridField $gridField, $actionName, $arguments, $data) {
if(!$this->checkDataType($gridField->getList())) {
return;
@ -36,18 +46,10 @@ class UserFormsGridFieldFilterHeader extends GridFieldFilterHeader {
// submitted in this form.
$params = $gridField->getForm()->getController()->getURLParams();
// this is for you SQL server I know you don't see '' as a number
$parentID = (!empty($params['ID'])) ? Convert::raw2sql($params['ID']) : 0;
$formFields = SubmittedFormField::get()
->where(sprintf("SubmittedForm.ParentID = '%s'", $parentID))
->leftJoin('SubmittedForm', 'SubmittedFormField.ParentID = SubmittedForm.ID')
->sort('Title', 'ASC')
->map('Name', 'Title');
// show dropdown of all the fields available from the submitted form fields
// that have been saved. Takes the titles from the currently live form.
$columnField = new DropdownField('FieldNameFilter', '');
$columnField->setSource($formFields->toArray());
$columnField->setSource($this->columns);
$columnField->setEmptyString(_t('UserFormsGridFieldFilterHeader.FILTERSUBMISSIONS', 'Filter Submissions..'));
$columnField->setHasEmptyDefault(true);
$columnField->setValue($selectedField);

View File

@ -62,7 +62,6 @@ class UserDefinedForm extends Page {
SiteTree::disableCMSFieldsExtensions();
$fields = parent::getCMSFields();
SiteTree::enableCMSFieldsExtensions();
// define tabs
$fields->findOrMakeTab('Root.FormContent', _t('UserDefinedForm.FORM', 'Form'));
$fields->findOrMakeTab('Root.FormOptions', _t('UserDefinedForm.CONFIGURATION', 'Configuration'));
@ -111,6 +110,19 @@ class UserDefinedForm extends Page {
$this->Submissions()->sort('Created', 'DESC')
);
// make sure a numeric not a empty string is checked against this int column for SQL server
$parentID = (!empty($this->ID)) ? $this->ID : 0;
// get a list of all field names and values used for print and export CSV views of the GridField below.
$columnSQL = <<<SQL
SELECT "Name", "Title"
FROM "SubmittedFormField"
LEFT JOIN "SubmittedForm" ON "SubmittedForm"."ID" = "SubmittedFormField"."ParentID"
WHERE "SubmittedForm"."ParentID" = '$parentID'
ORDER BY "Title" ASC
SQL;
$columns = DB::query($columnSQL)->map();
$config = new GridFieldConfig();
$config->addComponent(new GridFieldToolbarHeader());
$config->addComponent($sort = new GridFieldSortableHeader());
@ -129,16 +141,9 @@ class UserDefinedForm extends Page {
$filter->setThrowExceptionOnBadDataType(false);
$pagination->setThrowExceptionOnBadDataType(false);
// make sure a numeric not a empty string is checked against this int column for SQL server
$parentID = (!empty($this->ID)) ? $this->ID : 0;
// attach every column to the print view from
$columns = SubmittedFormField::get()
->where("\"SubmittedForm\".\"ParentID\" = '$parentID'")
->leftJoin('SubmittedForm', '"SubmittedFormField"."ParentID" = "SubmittedForm"."ID"')
->map('Name', 'Title');
$columns = $columns->toArray();
$columns['Created'] = "Created";
// attach every column to the print view form
$columns['Created'] = 'Created';
$filter->setColumns($columns);
// print configuration
$print->setPrintHasHeader(true);