mirror of
https://github.com/silverstripe/silverstripe-userforms.git
synced 2024-10-22 17:05:42 +02:00
FEATURE: added ability to delete 1 submission or all the submissions from the userdefined form
This commit is contained in:
parent
6368c972d1
commit
8926ad082b
@ -256,99 +256,6 @@ class UserDefinedForm_Controller extends Page_Controller {
|
||||
'Form' => $this->Form
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Export each of the form submissions for this UserDefinedForm
|
||||
* instance into a CSV file.
|
||||
*
|
||||
* In order to run this export function, the user must be
|
||||
* able to edit the page, so we check canEdit()
|
||||
*
|
||||
* @return HTTPResponse / bool
|
||||
*/
|
||||
public function export() {
|
||||
if(!$this->canEdit()) return false;
|
||||
|
||||
$now = Date("Y-m-d_h.i.s");
|
||||
$fileName = "export-$now.csv";
|
||||
$separator = ",";
|
||||
|
||||
// Get the UserDefinedForm to export data from the URL
|
||||
$SQL_ID = Convert::raw2sql(Director::urlParam('ID'));
|
||||
|
||||
if($SQL_ID) {
|
||||
$udf = DataObject::get_by_id("UserDefinedForm", $SQL_ID);
|
||||
if($udf) {
|
||||
$submissions = $udf->Submissions();
|
||||
if($submissions && $submissions->Count() > 0) {
|
||||
|
||||
// Get all the submission IDs (so we know what names/titles to get - helps for sites with many UDF's)
|
||||
$inClause = array();
|
||||
foreach($submissions as $submission) {
|
||||
$inClause[] = $submission->ID;
|
||||
}
|
||||
|
||||
// Get the CSV header rows from the database
|
||||
$tmp = DB::query("SELECT DISTINCT Name, Title FROM SubmittedFormField LEFT JOIN SubmittedForm ON SubmittedForm.ID = SubmittedFormField.ParentID WHERE SubmittedFormField.ParentID IN (" . implode(',', $inClause) . ")");
|
||||
|
||||
// Sort the Names and Titles from the database query into separate keyed arrays
|
||||
foreach($tmp as $array) {
|
||||
$csvHeaderNames[] = $array['Name'];
|
||||
$csvHeaderTitle[] = $array['Title'];
|
||||
}
|
||||
|
||||
// For every submission...
|
||||
$i = 0;
|
||||
foreach($submissions as $submission) {
|
||||
|
||||
// Get the rows for this submission (One row = one form field)
|
||||
$dataRow = $submission->FieldValues();
|
||||
$rows[$i] = array();
|
||||
|
||||
// For every row/field, get all the columns
|
||||
foreach($dataRow as $column) {
|
||||
|
||||
// If the Name of this field is in the $csvHeaderNames array, get an array of all the places it exists
|
||||
if($index = array_keys($csvHeaderNames, $column->Name)) {
|
||||
if(is_array($index)) {
|
||||
|
||||
// Set the final output array for each index that we want to insert this value into
|
||||
foreach($index as $idx) {
|
||||
$rows[$i][$idx] = $column->Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$i++;
|
||||
}
|
||||
|
||||
// CSV header row
|
||||
$csvData = '"' . implode('","', $csvHeaderTitle) . '"' . "\n";
|
||||
|
||||
// For every row of data (one form submission = one row)
|
||||
foreach($rows as $row) {
|
||||
|
||||
// Loop over all the names we can use
|
||||
for($i=0;$i<count($csvHeaderNames);$i++) {
|
||||
if(!$row[$i]) $csvData .= '"",'; // If there is no data for this column, output it as blank instead
|
||||
else $csvData .= '"'.$row[$i].'",'; // Otherwise, output the value for this column
|
||||
}
|
||||
// Start a new row for each submission
|
||||
$csvData .= "\n";
|
||||
}
|
||||
} else {
|
||||
user_error("No submissions to export.", E_USER_ERROR);
|
||||
}
|
||||
|
||||
HTTPRequest::send_file($csvData, $fileName)->output();
|
||||
} else {
|
||||
user_error("'$SQL_ID' is a valid type, but we can't find a UserDefinedForm in the database that matches the ID.", E_USER_ERROR);
|
||||
}
|
||||
} else {
|
||||
user_error("'$SQL_ID' is not a valid UserDefinedForm ID.", E_USER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
function ReportFilterForm() {
|
||||
return new SubmittedFormReportField_FilterForm( $this, 'ReportFilterForm' );
|
||||
|
@ -1,8 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* Allows CMS user to create forms dynamically.
|
||||
* @package forms
|
||||
* @subpackage fieldeditor
|
||||
*
|
||||
* @package userforms
|
||||
*/
|
||||
class FieldEditor extends FormField {
|
||||
|
||||
@ -63,8 +63,6 @@ class FieldEditor extends FormField {
|
||||
foreach($fields as $field => $title) {
|
||||
// get the nice title and strip out field
|
||||
$niceTitle = trim(str_ireplace("Field", "", eval("return $title::\$singular_name;")));
|
||||
|
||||
// keep old javascript happy
|
||||
$title = trim(str_ireplace("Editable", "", $title));
|
||||
|
||||
$output->push(new ArrayData(array(
|
||||
|
@ -14,16 +14,17 @@ class SubmittedForm extends DataObject {
|
||||
);
|
||||
|
||||
/**
|
||||
* Return the Link to DeleteLink
|
||||
* Before we delete this form make sure we delete all the
|
||||
* field values so that we don't leave old data round
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public function DeleteLink() {
|
||||
return $this->Parent()->Link().'deletesubmission/'.$this->ID;
|
||||
}
|
||||
|
||||
function SubmitTime() {
|
||||
return $this->Created;
|
||||
protected function onBeforeDelete() {
|
||||
if($this->FieldValues()) {
|
||||
foreach($this->FieldValues() as $value) {
|
||||
$value->delete();
|
||||
}
|
||||
}
|
||||
parent::onBeforeDelete();
|
||||
}
|
||||
}
|
||||
?>
|
@ -1,7 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* Data received from a UserDefinedForm submission
|
||||
* @package cms
|
||||
*
|
||||
* @package userforms
|
||||
*/
|
||||
class SubmittedFormField extends DataObject {
|
||||
|
||||
|
@ -8,7 +8,7 @@ class SubmittedFormReportField extends FormField {
|
||||
|
||||
function Field() {
|
||||
Requirements::css(SAPPHIRE_DIR . "/css/SubmittedFormReportField.css");
|
||||
|
||||
Requirements::javascript("userforms/javascript/UserForm.js");
|
||||
return $this->renderWith("SubmittedFormReportField");
|
||||
}
|
||||
|
||||
@ -22,25 +22,142 @@ class SubmittedFormReportField extends FormField {
|
||||
}
|
||||
|
||||
/**
|
||||
* Link to the export function of the controller
|
||||
* ID of this forms record
|
||||
*
|
||||
* @return String
|
||||
* @return int
|
||||
*/
|
||||
function ExportLink() {
|
||||
if($this->Submissions() && $this->Submissions()->Count() > 0) {
|
||||
return $this->form->getRecord()->Link() . 'export/' . $this->form->getRecord()->ID;
|
||||
function RecordID() {
|
||||
return $this->form->getRecord()->ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Export each of the form submissions for this UserDefinedForm
|
||||
* instance into a CSV file.
|
||||
*
|
||||
* In order to run this export function, the user must be
|
||||
* able to edit the page, so we check canEdit()
|
||||
*
|
||||
* @return HTTPResponse / bool
|
||||
*/
|
||||
public function export() {
|
||||
$now = Date("Y-m-d_h.i.s");
|
||||
$fileName = "export-$now.csv";
|
||||
$separator = ",";
|
||||
|
||||
// Get the UserDefinedForm to export data from the URL
|
||||
$SQL_ID = (isset($_REQUEST['id'])) ? Convert::raw2sql($_REQUEST['id']) : false;
|
||||
|
||||
if($SQL_ID) {
|
||||
$udf = DataObject::get_by_id("UserDefinedForm", $SQL_ID);
|
||||
if($udf) {
|
||||
$submissions = $udf->Submissions();
|
||||
if($submissions && $submissions->Count() > 0) {
|
||||
|
||||
// Get all the submission IDs (so we know what names/titles to get - helps for sites with many UDF's)
|
||||
$inClause = array();
|
||||
foreach($submissions as $submission) {
|
||||
$inClause[] = $submission->ID;
|
||||
}
|
||||
|
||||
// Get the CSV header rows from the database
|
||||
$tmp = DB::query("SELECT DISTINCT Name, Title FROM SubmittedFormField LEFT JOIN SubmittedForm ON SubmittedForm.ID = SubmittedFormField.ParentID WHERE SubmittedFormField.ParentID IN (" . implode(',', $inClause) . ")");
|
||||
|
||||
// Sort the Names and Titles from the database query into separate keyed arrays
|
||||
foreach($tmp as $array) {
|
||||
$csvHeaderNames[] = $array['Name'];
|
||||
$csvHeaderTitle[] = $array['Title'];
|
||||
}
|
||||
|
||||
// For every submission...
|
||||
$i = 0;
|
||||
foreach($submissions as $submission) {
|
||||
|
||||
// Get the rows for this submission (One row = one form field)
|
||||
$dataRow = $submission->FieldValues();
|
||||
$rows[$i] = array();
|
||||
|
||||
// For every row/field, get all the columns
|
||||
foreach($dataRow as $column) {
|
||||
|
||||
// If the Name of this field is in the $csvHeaderNames array, get an array of all the places it exists
|
||||
if($index = array_keys($csvHeaderNames, $column->Name)) {
|
||||
if(is_array($index)) {
|
||||
|
||||
// Set the final output array for each index that we want to insert this value into
|
||||
foreach($index as $idx) {
|
||||
$rows[$i][$idx] = $column->Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$i++;
|
||||
}
|
||||
|
||||
// CSV header row
|
||||
$csvData = '"' . implode('","', $csvHeaderTitle) . '"' . "\n";
|
||||
|
||||
// For every row of data (one form submission = one row)
|
||||
foreach($rows as $row) {
|
||||
|
||||
// Loop over all the names we can use
|
||||
for($i=0;$i<count($csvHeaderNames);$i++) {
|
||||
if(!$row[$i]) $csvData .= '"",'; // If there is no data for this column, output it as blank instead
|
||||
else $csvData .= '"'.$row[$i].'",'; // Otherwise, output the value for this column
|
||||
}
|
||||
// Start a new row for each submission
|
||||
$csvData .= "\n";
|
||||
}
|
||||
} else {
|
||||
user_error("No submissions to export.", E_USER_ERROR);
|
||||
}
|
||||
|
||||
HTTPRequest::send_file($csvData, $fileName)->output();
|
||||
} else {
|
||||
user_error("'$SQL_ID' is a valid type, but we can't find a UserDefinedForm in the database that matches the ID.", E_USER_ERROR);
|
||||
}
|
||||
} else {
|
||||
user_error("'$SQL_ID' is not a valid UserDefinedForm ID.", E_USER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Link to the delete the submission
|
||||
*
|
||||
* @return String
|
||||
* Delete all the submissions listed in the user defined form
|
||||
*
|
||||
* @return Redirect|Boolean
|
||||
*/
|
||||
function DeleteLink() {
|
||||
if($this->Submissions() && $this->Submissions()->Count() > 0) {
|
||||
return $this->form->getRecord()->Link() . 'deletesubmissions/' . $this->form->getRecord()->ID;
|
||||
}
|
||||
public function deletesubmissions() {
|
||||
$SQL_ID = (isset($_REQUEST['id'])) ? Convert::raw2sql($_REQUEST['id']) : false;
|
||||
if($SQL_ID) {
|
||||
$udf = DataObject::get_by_id("UserDefinedForm", $SQL_ID);
|
||||
$submissions = $udf->Submissions();
|
||||
if($submissions) {
|
||||
foreach($submissions as $submission) {
|
||||
// delete the submission @see $submission->onBeforeDelete() for more info
|
||||
$submission->delete();
|
||||
}
|
||||
return (Director::is_ajax()) ? true : Director::redirectBack();
|
||||
}
|
||||
}
|
||||
return (Director::is_ajax()) ? false : Director::redirectBack();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a given submission from a user defined form
|
||||
*
|
||||
* @return Redirect|Boolean
|
||||
*/
|
||||
public function deletesubmission() {
|
||||
$SQL_ID = (isset($_REQUEST['id'])) ? Convert::raw2sql($_REQUEST['id']) : false;
|
||||
if($SQL_ID) {
|
||||
$submission = DataObject::get_by_id("SubmittedForm", $SQL_ID);
|
||||
if($submission) {
|
||||
$submission->delete();
|
||||
|
||||
return (Director::is_ajax()) ? true : Director::redirectBack();
|
||||
}
|
||||
}
|
||||
return (Director::is_ajax()) ? false : Director::redirectBack();
|
||||
}
|
||||
}
|
||||
?>
|
@ -492,64 +492,61 @@ FieldEditorCheckboxGroupField = Class.extend('FieldEditorRadioField');
|
||||
|
||||
FieldEditorDropdown = Class.extend('FieldEditorRadioField');
|
||||
|
||||
Behaviour.register(
|
||||
{
|
||||
'div.FieldEditor ul.Menu li a': {
|
||||
Behaviour.register({
|
||||
|
||||
'div.FieldEditor ul.Menu li a': {
|
||||
urlForFieldMethod: function(methodName) {
|
||||
return this.ownerForm().action + '/field/Fields/' + methodName + '?NewID=' + this.numNewFields;
|
||||
},
|
||||
ownerForm: function() {
|
||||
var f = this.parentNode;
|
||||
while(f && f.tagName.toLowerCase() != 'form') f = f.parentNode;
|
||||
return f;
|
||||
},
|
||||
|
||||
onclick: function() {
|
||||
// get the ID of the field editor here
|
||||
|
||||
|
||||
urlForFieldMethod: function(methodName) {
|
||||
return this.ownerForm().action + '/field/Fields/' + methodName + '?NewID=' + this.numNewFields;
|
||||
},
|
||||
ownerForm: function() {
|
||||
var f = this.parentNode;
|
||||
while(f && f.tagName.toLowerCase() != 'form') f = f.parentNode;
|
||||
return f;
|
||||
},
|
||||
|
||||
onclick: function() {
|
||||
// get the ID of the field editor here
|
||||
|
||||
if( Element.hasClassName( $('Fields'), 'readonly' ) )
|
||||
return false;
|
||||
|
||||
action = this.urlForFieldMethod("addfield") + "&Type=" + this.id + ($('SecurityID') ? '&SecurityID=' + $('SecurityID').value : '');;
|
||||
|
||||
statusMessage('Adding new field' );
|
||||
|
||||
new Ajax.Request(action, {
|
||||
method: 'get',
|
||||
onFailure: reportError,
|
||||
onSuccess: this.appendNewField.bind(this)
|
||||
});
|
||||
|
||||
if( Element.hasClassName( $('Fields'), 'readonly' ) )
|
||||
return false;
|
||||
},
|
||||
|
||||
appendNewField: function(response) {
|
||||
this.numNewFields++;
|
||||
|
||||
var el = document.createElement('div');
|
||||
el.innerHTML = response.responseText;
|
||||
|
||||
var i=0;
|
||||
while(!el.childNodes[i].tagName) i++;
|
||||
var newField = el.childNodes[i];
|
||||
$('Fields_fields').appendChild(newField);
|
||||
|
||||
// Behaviour.debug();
|
||||
if(newField) {
|
||||
Behaviour.apply(newField,true);
|
||||
FieldEditor.applyTo('div.FieldEditor');
|
||||
}
|
||||
|
||||
// do we want to make sorting explicit?
|
||||
Sortable.create('Fields_fields', {tag: 'div', handle:'handle'});
|
||||
|
||||
statusMessage('Added new field','good');
|
||||
action = this.urlForFieldMethod("addfield") + "&Type=" + this.id + ($('SecurityID') ? '&SecurityID=' + $('SecurityID').value : '');;
|
||||
|
||||
statusMessage('Adding new field' );
|
||||
|
||||
new Ajax.Request(action, {
|
||||
method: 'get',
|
||||
onFailure: reportError,
|
||||
onSuccess: this.appendNewField.bind(this)
|
||||
});
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
appendNewField: function(response) {
|
||||
this.numNewFields++;
|
||||
|
||||
var el = document.createElement('div');
|
||||
el.innerHTML = response.responseText;
|
||||
|
||||
var i=0;
|
||||
while(!el.childNodes[i].tagName) i++;
|
||||
var newField = el.childNodes[i];
|
||||
$('Fields_fields').appendChild(newField);
|
||||
|
||||
// Behaviour.debug();
|
||||
if(newField) {
|
||||
Behaviour.apply(newField,true);
|
||||
FieldEditor.applyTo('div.FieldEditor');
|
||||
}
|
||||
|
||||
// do we want to make sorting explicit?
|
||||
Sortable.create('Fields_fields', {tag: 'div', handle:'handle'});
|
||||
|
||||
statusMessage('Added new field','good');
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
function reportError(request){
|
||||
// More complex error for developers
|
||||
|
11
javascript/UserForm.js
Normal file
11
javascript/UserForm.js
Normal file
@ -0,0 +1,11 @@
|
||||
(function($) {
|
||||
$(document).ready(function() {
|
||||
$("#FormSubmissions .deleteSubmission").click(function() {
|
||||
var deletedSubmission = $(this);
|
||||
$.post($(this).attr('href'), function(data) {
|
||||
deletedSubmission.parents('div.report').fadeOut();
|
||||
});
|
||||
return false;
|
||||
});
|
||||
})
|
||||
})(jQuery);
|
@ -3,25 +3,28 @@
|
||||
</div>
|
||||
<div class="reports" id="FormSubmissions">
|
||||
|
||||
<% if ExportLink %>
|
||||
<a href="$ExportLink" title="<% _t('EXPORTCSVFILE', 'Export CSV file') %>"><strong><% _t('EXPORTSUBMISSIONS', 'Export submissions to CSV') %></strong></a>
|
||||
<% end_if %>
|
||||
|
||||
<!-- <% if DeleteLink %>
|
||||
<a href="$DeleteLink" title="<% _t('DELETEALLSUBMISSIONS', 'Delete Submissions') %>"><strong><% _t('DELETEALLSUBMISSIONS', 'Delete Submissions') %></strong></a>
|
||||
<% end_if %>
|
||||
-->
|
||||
<% control Submissions %>
|
||||
<div class="report">
|
||||
<span class="submitted"><% _t('SUBMITTED', 'Submitted at') %> $Created.Nice. <!--<a href="$DeleteLink"><% _t('DELETESUBMISSION', 'Delete Submission') %></a>--></span>
|
||||
<table>
|
||||
<% control FieldValues %>
|
||||
<tr>
|
||||
<td class="field">$Title</td>
|
||||
<td class="value"><% if Link %><a href="$Link"><% end_if %>$Value<% if Link %></a><% end_if %></td>
|
||||
</tr>
|
||||
<% end_control %>
|
||||
</table>
|
||||
</div>
|
||||
<% end_control %>
|
||||
<% if Submissions %>
|
||||
|
||||
<ul class="formSubmissionActions">
|
||||
<!-- @todo work out why url_handlers dont like /export/2 -->
|
||||
<li><a href="{$Top.Link}/export/?id={$RecordID}"><% _t('EXPORTSUBMISSIONS', 'Export submissions to CSV') %></a></li>
|
||||
<li><a href="{$Top.Link}/deletesubmissions/?id={$RecordID}" class="deleteSubmission"><% _t('DELETEALLSUBMISSIONS', 'Delete All Submissions') %></a></li>
|
||||
</ul>
|
||||
|
||||
<% control Submissions %>
|
||||
<div class="report">
|
||||
<h4 class="submitted"><% _t('SUBMITTED', 'Submitted at') %> $Created.Nice. <a href="{$Top.Link}/deletesubmission/?id={$ID}" class="deleteSubmission"><% _t('DELETESUBMISSION', 'Delete Submission') %></a></h4>
|
||||
<table>
|
||||
<% control FieldValues %>
|
||||
<tr>
|
||||
<td class="field">$Title</td>
|
||||
<td class="value"><% if Link %><a href="$Link"><% end_if %>$Value<% if Link %></a><% end_if %></td>
|
||||
</tr>
|
||||
<% end_control %>
|
||||
</table>
|
||||
</div>
|
||||
<% end_control %>
|
||||
<% else %>
|
||||
<p><% _t('NOSUBMISSIONS', 'No Submissions') %></p>
|
||||
<% end_if %>
|
||||
</div>
|
Loading…
Reference in New Issue
Block a user