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
|
'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() {
|
function ReportFilterForm() {
|
||||||
return new SubmittedFormReportField_FilterForm( $this, 'ReportFilterForm' );
|
return new SubmittedFormReportField_FilterForm( $this, 'ReportFilterForm' );
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Allows CMS user to create forms dynamically.
|
* Allows CMS user to create forms dynamically.
|
||||||
* @package forms
|
*
|
||||||
* @subpackage fieldeditor
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
class FieldEditor extends FormField {
|
class FieldEditor extends FormField {
|
||||||
|
|
||||||
@ -63,8 +63,6 @@ class FieldEditor extends FormField {
|
|||||||
foreach($fields as $field => $title) {
|
foreach($fields as $field => $title) {
|
||||||
// get the nice title and strip out field
|
// get the nice title and strip out field
|
||||||
$niceTitle = trim(str_ireplace("Field", "", eval("return $title::\$singular_name;")));
|
$niceTitle = trim(str_ireplace("Field", "", eval("return $title::\$singular_name;")));
|
||||||
|
|
||||||
// keep old javascript happy
|
|
||||||
$title = trim(str_ireplace("Editable", "", $title));
|
$title = trim(str_ireplace("Editable", "", $title));
|
||||||
|
|
||||||
$output->push(new ArrayData(array(
|
$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() {
|
protected function onBeforeDelete() {
|
||||||
return $this->Parent()->Link().'deletesubmission/'.$this->ID;
|
if($this->FieldValues()) {
|
||||||
}
|
foreach($this->FieldValues() as $value) {
|
||||||
|
$value->delete();
|
||||||
function SubmitTime() {
|
}
|
||||||
return $this->Created;
|
}
|
||||||
|
parent::onBeforeDelete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
@ -1,7 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Data received from a UserDefinedForm submission
|
* Data received from a UserDefinedForm submission
|
||||||
* @package cms
|
*
|
||||||
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
class SubmittedFormField extends DataObject {
|
class SubmittedFormField extends DataObject {
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ class SubmittedFormReportField extends FormField {
|
|||||||
|
|
||||||
function Field() {
|
function Field() {
|
||||||
Requirements::css(SAPPHIRE_DIR . "/css/SubmittedFormReportField.css");
|
Requirements::css(SAPPHIRE_DIR . "/css/SubmittedFormReportField.css");
|
||||||
|
Requirements::javascript("userforms/javascript/UserForm.js");
|
||||||
return $this->renderWith("SubmittedFormReportField");
|
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() {
|
function RecordID() {
|
||||||
if($this->Submissions() && $this->Submissions()->Count() > 0) {
|
return $this->form->getRecord()->ID;
|
||||||
return $this->form->getRecord()->Link() . 'export/' . $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
|
* Delete all the submissions listed in the user defined form
|
||||||
*
|
*
|
||||||
* @return String
|
* @return Redirect|Boolean
|
||||||
*/
|
*/
|
||||||
function DeleteLink() {
|
public function deletesubmissions() {
|
||||||
if($this->Submissions() && $this->Submissions()->Count() > 0) {
|
$SQL_ID = (isset($_REQUEST['id'])) ? Convert::raw2sql($_REQUEST['id']) : false;
|
||||||
return $this->form->getRecord()->Link() . 'deletesubmissions/' . $this->form->getRecord()->ID;
|
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');
|
FieldEditorDropdown = Class.extend('FieldEditorRadioField');
|
||||||
|
|
||||||
Behaviour.register(
|
Behaviour.register({
|
||||||
{
|
|
||||||
'div.FieldEditor ul.Menu li a': {
|
'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
|
||||||
|
|
||||||
|
if( Element.hasClassName( $('Fields'), 'readonly' ) )
|
||||||
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)
|
|
||||||
});
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
},
|
|
||||||
|
|
||||||
appendNewField: function(response) {
|
action = this.urlForFieldMethod("addfield") + "&Type=" + this.id + ($('SecurityID') ? '&SecurityID=' + $('SecurityID').value : '');;
|
||||||
this.numNewFields++;
|
|
||||||
|
statusMessage('Adding new field' );
|
||||||
var el = document.createElement('div');
|
|
||||||
el.innerHTML = response.responseText;
|
new Ajax.Request(action, {
|
||||||
|
method: 'get',
|
||||||
var i=0;
|
onFailure: reportError,
|
||||||
while(!el.childNodes[i].tagName) i++;
|
onSuccess: this.appendNewField.bind(this)
|
||||||
var newField = el.childNodes[i];
|
});
|
||||||
$('Fields_fields').appendChild(newField);
|
|
||||||
|
return false;
|
||||||
// Behaviour.debug();
|
},
|
||||||
if(newField) {
|
|
||||||
Behaviour.apply(newField,true);
|
appendNewField: function(response) {
|
||||||
FieldEditor.applyTo('div.FieldEditor');
|
this.numNewFields++;
|
||||||
}
|
|
||||||
|
var el = document.createElement('div');
|
||||||
// do we want to make sorting explicit?
|
el.innerHTML = response.responseText;
|
||||||
Sortable.create('Fields_fields', {tag: 'div', handle:'handle'});
|
|
||||||
|
var i=0;
|
||||||
statusMessage('Added new field','good');
|
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){
|
function reportError(request){
|
||||||
// More complex error for developers
|
// 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>
|
||||||
<div class="reports" id="FormSubmissions">
|
<div class="reports" id="FormSubmissions">
|
||||||
|
|
||||||
<% if ExportLink %>
|
<% if Submissions %>
|
||||||
<a href="$ExportLink" title="<% _t('EXPORTCSVFILE', 'Export CSV file') %>"><strong><% _t('EXPORTSUBMISSIONS', 'Export submissions to CSV') %></strong></a>
|
|
||||||
<% end_if %>
|
<ul class="formSubmissionActions">
|
||||||
|
<!-- @todo work out why url_handlers dont like /export/2 -->
|
||||||
<!-- <% if DeleteLink %>
|
<li><a href="{$Top.Link}/export/?id={$RecordID}"><% _t('EXPORTSUBMISSIONS', 'Export submissions to CSV') %></a></li>
|
||||||
<a href="$DeleteLink" title="<% _t('DELETEALLSUBMISSIONS', 'Delete Submissions') %>"><strong><% _t('DELETEALLSUBMISSIONS', 'Delete Submissions') %></strong></a>
|
<li><a href="{$Top.Link}/deletesubmissions/?id={$RecordID}" class="deleteSubmission"><% _t('DELETEALLSUBMISSIONS', 'Delete All Submissions') %></a></li>
|
||||||
<% end_if %>
|
</ul>
|
||||||
-->
|
|
||||||
<% control Submissions %>
|
<% control Submissions %>
|
||||||
<div class="report">
|
<div class="report">
|
||||||
<span class="submitted"><% _t('SUBMITTED', 'Submitted at') %> $Created.Nice. <!--<a href="$DeleteLink"><% _t('DELETESUBMISSION', 'Delete Submission') %></a>--></span>
|
<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>
|
<table>
|
||||||
<% control FieldValues %>
|
<% control FieldValues %>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="field">$Title</td>
|
<td class="field">$Title</td>
|
||||||
<td class="value"><% if Link %><a href="$Link"><% end_if %>$Value<% if Link %></a><% end_if %></td>
|
<td class="value"><% if Link %><a href="$Link"><% end_if %>$Value<% if Link %></a><% end_if %></td>
|
||||||
</tr>
|
</tr>
|
||||||
<% end_control %>
|
<% end_control %>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<% end_control %>
|
<% end_control %>
|
||||||
|
<% else %>
|
||||||
|
<p><% _t('NOSUBMISSIONS', 'No Submissions') %></p>
|
||||||
|
<% end_if %>
|
||||||
</div>
|
</div>
|
Loading…
Reference in New Issue
Block a user