diff --git a/include/class.orm.php b/include/class.orm.php index cdf25599501b82e474893d2ccca18823804d38f1..ef04e3d3e9bb7bb2412c074e9c73e2c57d3d9157 100644 --- a/include/class.orm.php +++ b/include/class.orm.php @@ -319,6 +319,14 @@ class QuerySet implements IteratorAggregate, ArrayAccess { return $this->count() > 0; } + function delete() { + $class = $this->compiler; + $compiler = new $class(); + $ex = $compiler->compileDelete($this); + $ex->execute(); + return $ex->affected_rows(); + } + // IteratorAggregate interface function getIterator() { $class = $this->iterator; @@ -863,7 +871,28 @@ class MySqlCompiler extends SqlCompiler { function compileInsert() { } - function compileDelete() { + function compileDelete($queryset) { + $model = $queryset->model; + $table = $model::$meta['table']; + $where_pos = array(); + $where_neg = array(); + $joins = array(); + foreach ($queryset->constraints as $where) { + $where_pos[] = $this->compileWhere($where, $model); + } + foreach ($queryset->exclusions as $where) { + $where_neg[] = $this->compileWhere($where, $model); + } + + $where = ''; + if ($where_pos || $where_neg) { + $where = ' WHERE '.implode(' AND ', $where_pos) + .implode(' AND NOT ', $where_neg); + } + $joins = $this->getJoins(); + $sql = 'DELETE '.$this->quote($table).'.* FROM ' + .$this->quote($table).$joins.$where; + return new MysqlExecutor($sql, $this->params); } // Returns meta data about the table used to build queries @@ -885,14 +914,18 @@ class MysqlExecutor { } function _prepare() { + $this->execute(); + $this->_setup_output(); + $this->stmt->store_result(); + } + + function execute() { if (!($this->stmt = db_prepare($this->sql))) throw new Exception('Unable to prepare query: '.db_error() .' '.$this->sql); if (count($this->params)) $this->_bind($this->params); - $this->stmt->execute(); - $this->_setup_output(); - $this->stmt->store_result(); + return $this->stmt->execute(); } function _bind($params) { @@ -997,6 +1030,14 @@ class MysqlExecutor { $this->stmt = null; } + function affected_rows() { + return $this->stmt->affected_rows; + } + + function insert_id() { + return $this->stmt->insert_id; + } + function __toString() { return $this->sql; } diff --git a/include/staff/dynamic-form.inc.php b/include/staff/dynamic-form.inc.php index 0325331fec5a5de3e83288b9d865d3d38897201d..86adb1c1315d69c587afaf3ec16e164431fc69be 100644 --- a/include/staff/dynamic-form.inc.php +++ b/include/staff/dynamic-form.inc.php @@ -16,7 +16,7 @@ if($form && $_REQUEST['a']!='add') { $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); ?> -<form action="?id=<?php echo urlencode($_REQUEST['id']); ?>" method="post" id="save"> +<form id="manage-form" action="?id=<?php echo urlencode($_REQUEST['id']); ?>" method="post"> <?php csrf_token(); ?> <input type="hidden" name="do" value="<?php echo $action; ?>"> <input type="hidden" name="id" value="<?php echo $info['id']; ?>"> @@ -167,7 +167,9 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); if ($ferrors['name']) echo '<br/>'; echo $ferrors['name']; ?></font> </td> - <td><input type="checkbox" name="delete-<?php echo $id; ?>" + <td><input class="delete-box" type="checkbox" name="delete-<?php echo $id; ?>" + data-field-label="<?php echo $f->get('label'); ?>" + data-field-id="<?php echo $id; ?>" <?php echo $deletable; ?>/> <input type="hidden" name="sort-<?php echo $id; ?>" value="<?php echo $f->get('sort'); ?>"/> @@ -223,32 +225,33 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); </tr> </tbody> </table> -<p class="centered" id="actions"> +<p class="centered"> <input type="submit" name="submit" value="<?php echo $submit_text; ?>"> <input type="reset" name="reset" value="Reset"> <input type="button" name="cancel" value="Cancel" onclick='window.location.href="?"'> </p> -<div style="display:none;" class="dialog" id="confirm-action"> - <h3><i class="icon-trash"></i> Delete Existing Data?</h3> +<div style="display:none;" class="draggable dialog" id="delete-confirm"> + <h3><i class="icon-trash"></i> Remove Existing Data?</h3> <a class="close" href=""><i class="icon-remove-circle"></i></a> <hr/> - <p class="confirm-action" style="display:none;" id="submit-confirm"> + <p> + <strong>You are about to delete <span id="deleted-count"></span> fields.</strong> Would you also like to remove data currently entered for this field? - <em>If you say no, you will have the option to delete the the data when editing it</em> - <br><br>Deleted data CANNOT be recovered. - <hr> - <input type="checkbox" name="delete-data" /> - Remove all data entered for this field + <em>If you opt not to remove the data now, you will have the option + to delete the the data when editing it</em> + </p><p style="color:red"> + Deleted data CANNOT be recovered. </p> - <div>Please confirm to continue.</div> + <hr> + <div id="deleted-fields"></div> <hr style="margin-top:1em"/> <p class="full-width"> <span class="buttons" style="float:left"> <input type="button" value="No, Cancel" class="close"> </span> <span class="buttons" style="float:right"> - <input type="button" value="Save Changes!" class="confirm"> + <input type="submit" value="Continue" class="confirm"> </span> </p> <div class="clear"></div> @@ -258,3 +261,32 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); <div style="display:none;" class="dialog draggable" id="field-config"> <div class="body"></div> </div> + +<script type="text/javascript"> +$('#manage-form').on('submit.inline', function() { + var formObj = this, deleted = $('input.delete-box:checked', this); + if (deleted.length) { + $('#overlay').show(); + $('#deleted-fields').empty(); + deleted.each(function(i, e) { + $('#deleted-fields').append($('<p></p>') + .append($('<input/>').attr({type:'checkbox',name:'delete-data-' + + $(e).data('fieldId')}) + ).append($('<strong>').html( + 'Remove all data entered for <u>' + $(e).data('fieldLabel') + '</u>' + )) + ); + }); + $('#delete-confirm').show().delegate('input.confirm', 'click.confirm', function() { + $('.dialog#delete-confirm').hide(); + $(formObj).unbind('submit.inline'); + $(window).unbind('beforeunload'); + $('#loading').show(); + }) + return false; + } + // TODO: Popup the 'please wait' dialog + $(window).unbind('beforeunload'); + $('#loading').show(); +}); +</script> diff --git a/scp/forms.php b/scp/forms.php index 077b3e0ff409c5b84b0fa6babd4751ad775efad1..43e66242aa85f55ea2baad290a9fa29369990055 100644 --- a/scp/forms.php +++ b/scp/forms.php @@ -23,6 +23,11 @@ if($_POST) { foreach ($form->getDynamicFields() as $field) { $id = $field->get('id'); if ($_POST["delete-$id"] == 'on' && $field->isDeletable()) { + if ($_POST["delete-data-$id"]) { + DynamicFormEntryAnswer::objects() + ->filter(array('field_id'=>$id)) + ->delete(); + } $field->delete(); // Don't bother updating the field continue;