enabled the code folder view to delete selected files/directories.

This commit is contained in:
hyung-hwan 2015-08-27 08:55:33 +00:00
parent 05ef3af213
commit 779ba51a8f
4 changed files with 253 additions and 13 deletions

View File

@ -645,6 +645,7 @@ PHP_MINIT_FUNCTION(svn)
REGISTER_LONG_CONSTANT("SVN_ALL", SVN_ALL, CONST_CS|CONST_PERSISTENT); /* --verbose in svn status */ REGISTER_LONG_CONSTANT("SVN_ALL", SVN_ALL, CONST_CS|CONST_PERSISTENT); /* --verbose in svn status */
REGISTER_LONG_CONSTANT("SVN_SHOW_UPDATES", SVN_SHOW_UPDATES, CONST_CS|CONST_PERSISTENT); /* --show-updates */ REGISTER_LONG_CONSTANT("SVN_SHOW_UPDATES", SVN_SHOW_UPDATES, CONST_CS|CONST_PERSISTENT); /* --show-updates */
REGISTER_LONG_CONSTANT("SVN_NO_IGNORE", SVN_NO_IGNORE, CONST_CS|CONST_PERSISTENT); /* --no-ignore */ REGISTER_LONG_CONSTANT("SVN_NO_IGNORE", SVN_NO_IGNORE, CONST_CS|CONST_PERSISTENT); /* --no-ignore */
REGISTER_LONG_CONSTANT("SVN_IGNORE_EXTERNALS", SVN_IGNORE_EXTERNALS, CONST_CS|CONST_PERSISTENT); /* --ignore-externals */
REGISTER_LONG_CONSTANT("SVN_WC_STATUS_NONE", svn_wc_status_none, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SVN_WC_STATUS_NONE", svn_wc_status_none, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SVN_WC_STATUS_UNVERSIONED", svn_wc_status_unversioned, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SVN_WC_STATUS_UNVERSIONED", svn_wc_status_unversioned, CONST_CS|CONST_PERSISTENT);

View File

@ -457,6 +457,70 @@ class Code extends Controller
print $status; print $status;
} }
function xhr_delete ($projectid = '', $path = '')
{
$this->load->model ('ProjectModel', 'projects');
$this->load->model ('SubversionModel', 'subversion');
$this->load->library ('upload');
$login = $this->login->getUser ();
$revision_saved = -1;
if ($login['id'] == '')
{
$status = 'signin';
}
else
{
$path = $this->converter->HexToAscii ($path);
if ($path == '.') $path = ''; /* treat a period specially */
$path = $this->_normalize_path ($path);
$project = $this->projects->get ($projectid);
if ($project === FALSE)
{
$status = "dberr - failed to get the project {$projectid}";
}
else if ($project === NULL)
{
$status = "noent - no such project {$projectid}";
}
else
{
$post_delete_message = $this->input->post('code_folder_delete_message');
$post_delete_file_count = $this->input->post('code_folder_delete_file_count');
if ($post_delete_message !== FALSE && $post_delete_file_count !== FALSE)
{
$delete_files = array ();
for ($i = 0; $i < $post_delete_file_count; $i++)
{
$d = $this->input->post("code_folder_delete_file_$i");
if (strlen($d) > 0)
{
array_push ($delete_files, $d);
}
}
if (count($delete_files) > 0 && $this->subversion->deleteFiles ($projectid, $path, $login['id'], $post_delete_message, $delete_files, $this->upload) === FALSE)
{
$status = 'repoerr - ' . $this->subversion->delete_files_errmsg;
}
else
{
$status = 'ok';
}
}
else
{
$status = 'posterr - invalid post data';
}
}
}
print $status;
}
function enjson_save ($projectid = '', $path = '') function enjson_save ($projectid = '', $path = '')
{ {
$this->load->model ('ProjectModel', 'projects'); $this->load->model ('ProjectModel', 'projects');

View File

@ -251,6 +251,7 @@ class SubversionModel extends Model
public $store_file_errmsg = ''; public $store_file_errmsg = '';
public $import_files_errmsg = ''; public $import_files_errmsg = '';
public $delete_files_errmsg = '';
function capture_save_error ($errno, $errmsg) function capture_save_error ($errno, $errmsg)
{ {
@ -262,6 +263,11 @@ class SubversionModel extends Model
$this->import_files_errmsg = $errmsg; $this->import_files_errmsg = $errmsg;
} }
function capture_delete_error ($errno, $errmsg)
{
$this->delete_files_errmsg = $errmsg;
}
function storeFile ($projectid, $path, $committer, $commit_message, $text) function storeFile ($projectid, $path, $committer, $commit_message, $text)
{ {
$store_file_errmsg = ''; $store_file_errmsg = '';
@ -304,7 +310,7 @@ class SubversionModel extends Model
function importFiles ($projectid, $path, $committer, $commit_message, $files, $uploader) function importFiles ($projectid, $path, $committer, $commit_message, $files, $uploader)
{ {
$import_files_errmsg = ''; $this->import_files_errmsg = '';
//$url = 'file://'.CODEPOT_SVNREPO_DIR."/{$projectid}/{$path}"; //$url = 'file://'.CODEPOT_SVNREPO_DIR."/{$projectid}/{$path}";
$full_path = CODEPOT_SVNREPO_DIR."/{$projectid}"; $full_path = CODEPOT_SVNREPO_DIR."/{$projectid}";
@ -327,7 +333,7 @@ class SubversionModel extends Model
set_error_handler (array ($this, 'capture_import_error')); set_error_handler (array ($this, 'capture_import_error'));
if (@svn_auth_set_parameter (SVN_AUTH_PARAM_DEFAULT_USERNAME, $committer) === FALSE || if (@svn_auth_set_parameter (SVN_AUTH_PARAM_DEFAULT_USERNAME, $committer) === FALSE ||
@svn_checkout ($dirurl, $actual_tfname, SVN_REVISION_HEAD, SVN_NON_RECURSIVE) === FALSE) @svn_checkout ($dirurl, $actual_tfname, SVN_REVISION_HEAD, 0) === FALSE)
{ {
restore_error_handler (); restore_error_handler ();
codepot_delete_files ($actual_tfname, TRUE); codepot_delete_files ($actual_tfname, TRUE);
@ -438,6 +444,66 @@ class SubversionModel extends Model
return TRUE; return TRUE;
} }
function deleteFiles ($projectid, $path, $committer, $commit_message, $files, $uploader)
{
$this->delete_files_errmsg = '';
//$url = 'file://'.CODEPOT_SVNREPO_DIR."/{$projectid}/{$path}";
$full_path = CODEPOT_SVNREPO_DIR."/{$projectid}";
if (strlen($path) > 0) $full_path .= "/{$path}";
$canon_path = $this->_canonical_path($full_path);
$dirurl = 'file://' . $canon_path;
set_error_handler (array ($this, 'capture_delete_error'));
$tfname = @tempnam(__FILE__, 'codepot-delete-files-');
restore_error_handler ();
if ($tfname === FALSE)
{
return FALSE;
}
$actual_tfname = $tfname . '.d';
codepot_delete_files ($actual_tfname, TRUE); // delete the directory in case it exists
mkdir ($actual_tfname);
set_error_handler (array ($this, 'capture_delete_error'));
if (@svn_auth_set_parameter (SVN_AUTH_PARAM_DEFAULT_USERNAME, $committer) === FALSE ||
@svn_checkout ($dirurl, $actual_tfname, SVN_REVISION_HEAD, 0) === FALSE)
{
restore_error_handler ();
codepot_delete_files ($actual_tfname, TRUE);
@unlink ($tfname);
return FALSE;
}
foreach ($files as $f)
{
$xname = $actual_tfname . '/' . $f;
if (@svn_delete ($xname, TRUE) === FALSE)
{
restore_error_handler ();
codepot_delete_files ($actual_tfname, TRUE);
@unlink ($tfname);
return FALSE;
}
}
if (($result = @svn_commit ($commit_message, $actual_tfname)) === FALSE)
{
restore_error_handler ();
codepot_delete_files ($actual_tfname, TRUE);
@unlink ($tfname);
return FALSE;
}
restore_error_handler ();
codepot_delete_files ($actual_tfname, TRUE); // delete the directory in case it exists
@unlink ($tfname);
return TRUE;
}
function getRevHistory ($projectid, $path, $rev) function getRevHistory ($projectid, $path, $rev)
{ {
//$url = 'file:///'.CODEPOT_SVNREPO_DIR."/{$projectid}/{$path}"; //$url = 'file:///'.CODEPOT_SVNREPO_DIR."/{$projectid}/{$path}";

View File

@ -200,6 +200,7 @@ function render_readme()
var new_item_no = 0; var new_item_no = 0;
var import_in_progress = false; var import_in_progress = false;
var delete_in_progress = false;
function get_new_item_html(no, type, name) function get_new_item_html(no, type, name)
{ {
@ -310,10 +311,101 @@ $(function () {
} }
); );
$('#code_folder_mainarea_delete_form_div').dialog (
{
title: '<?php print $this->lang->line('Delete');?>',
resizable: true,
autoOpen: false,
width: 'auto',
height: 'auto',
modal: true,
buttons: {
'<?php print $this->lang->line('OK')?>': function () {
if (delete_in_progress) return;
$('#code_folder_mainarea_new_item_count').val (new_item_no + 1);
if (!!window.FormData)
{
// FormData is supported
delete_in_progress = true;
var form_data = new FormData();
form_data.append ('code_folder_delete_message', $('#code_folder_mainarea_delete_message').val());
var xi = 0;
for (var i = 0; i < <?php print $file_count; ?>; i++)
{
var f = $('#code_folder_mainarea_result_table_file_selector_' + i);
if (f != null && f.is(':checked'))
{
form_data.append ('code_folder_delete_file_' + xi, f.val());
xi++;
}
}
form_data.append ('code_folder_delete_file_count', xi);
$('#code_folder_mainarea_delete_form_div').dialog('disable');
$.ajax({
url: codepot_merge_path('<?php print site_url() ?>', '<?php print "/code/xhr_delete/{$project->id}/{$hex_headpath}"; ?>'),
type: 'POST',
data: form_data,
mimeType: 'multipart/form-data',
contentType: false,
processData: false,
cache: false,
success: function (data, textStatus, jqXHR) {
delete_in_progress = false;
$('#code_folder_mainarea_delete_form_div').dialog('enable');
$('#code_folder_mainarea_delete_form_div').dialog('close');
if (data == 'ok')
{
// refresh the page to the head revision
$(location).attr ('href', codepot_merge_path('<?php print site_url(); ?>', '<?php print "/code/file/{$project->id}/{$hex_headpath}"; ?>'));
}
else
{
show_alert ('<pre>' + codepot_htmlspecialchars(data) + '</pre>', "<?php print $this->lang->line('Error')?>");
}
},
error: function (jqXHR, textStatus, errorThrown) {
delete_in_progress = false;
$('#code_folder_mainarea_delete_form_div').dialog('enable');
$('#code_folder_mainarea_delete_form_div').dialog('close');
show_alert ('Failed - ' + errorThrown, "<?php print $this->lang->line('Error')?>");
}
});
}
else
{
show_alert ('<pre>NOT SUPPORTED</pre>', "<?php print $this->lang->line('Error')?>");
}
},
'<?php print $this->lang->line('Cancel')?>': function () {
if (delete_in_progress) return;
$('#code_folder_mainarea_delete_form_div').dialog('close');
}
},
beforeClose: function() {
// if importing is in progress, prevent dialog closing
return !delete_in_progress;
}
}
);
$('#code_folder_mainarea_new_button').button().click (function() { $('#code_folder_mainarea_new_button').button().click (function() {
$('#code_folder_mainarea_new_form_div').dialog('open'); $('#code_folder_mainarea_new_form_div').dialog('open');
}); });
$('#code_folder_mainarea_delete_button').button().click (function() {
$('#code_folder_mainarea_delete_form_div').dialog('open');
});
<?php endif; ?> <?php endif; ?>
<?php if ($file_count > 0): ?> <?php if ($file_count > 0): ?>
@ -368,6 +460,12 @@ $(function () {
}); });
<?php endif; ?> <?php endif; ?>
<?php if (isset($login['id']) && $login['id'] != ''): ?>
$('#code_folder_mainarea_result_table_select_all').button().click (function() {
$('.file_selector').prop('checked', $('#code_folder_mainarea_result_table_select_all').is(':checked'));
});
<?php endif; ?>
$('#code_search_submit').button().click (function () { $('#code_search_submit').button().click (function () {
if ($.trim($("#code_search_string").val()) != "") if ($.trim($("#code_search_string").val()) != "")
{ {
@ -376,14 +474,6 @@ $(function () {
$('#code_search_form').submit (); $('#code_search_form').submit ();
} }
}); });
/*
$('#code_search_form').submit (function(e) {
if ($.trim($("#code_search_string").val()) === "")
{
// prevent submission when the search string is empty.
e.preventDefault();
}
});*/
$('#code_search_invertedly').button(); $('#code_search_invertedly').button();
$('#code_search_case_insensitively').button(); $('#code_search_case_insensitively').button();
@ -405,7 +495,6 @@ $(function () {
render_readme (); render_readme ();
<?php if (strlen($popup_error_message) > 0): ?> <?php if (strlen($popup_error_message) > 0): ?>
show_alert (<?php print codepot_json_encode('<pre>' . htmlspecialchars($popup_error_message) . '</pre>'); ?>, "<?php print $this->lang->line('Error')?>"); show_alert (<?php print codepot_json_encode('<pre>' . htmlspecialchars($popup_error_message) . '</pre>'); ?>, "<?php print $this->lang->line('Error')?>");
<?php endif; ?> <?php endif; ?>
@ -565,7 +654,6 @@ $this->load->view (
print form_hidden('search_wildcard_pattern', set_value('search_wildcard_pattern', $wildcard_pattern)); print form_hidden('search_wildcard_pattern', set_value('search_wildcard_pattern', $wildcard_pattern));
print ' '; print ' ';
//print form_submit('search_submit', $this->lang->line('Search'), 'id="code_search_submit"');
printf ('<a id="code_search_submit" href="#">%s</a>', $this->lang->line('Search')); printf ('<a id="code_search_submit" href="#">%s</a>', $this->lang->line('Search'));
print ' | '; print ' | ';
} }
@ -596,6 +684,7 @@ $this->load->view (
if (isset($login['id']) && $login['id'] != '') if (isset($login['id']) && $login['id'] != '')
{ {
printf ('<a id="code_folder_mainarea_new_button" href="#">%s</a>', $this->lang->line('New')); printf ('<a id="code_folder_mainarea_new_button" href="#">%s</a>', $this->lang->line('New'));
printf ('<a id="code_folder_mainarea_delete_button" href="#">%s</a>', $this->lang->line('Delete'));
} }
if ($file_count > 0) if ($file_count > 0)
@ -664,6 +753,10 @@ $this->load->view (
print '<table id="code_folder_mainarea_result_table" class="fit-width-result-table">'; print '<table id="code_folder_mainarea_result_table" class="fit-width-result-table">';
print '<tr class="heading">'; print '<tr class="heading">';
if (isset($login['id']) && $login['id'] != '')
{
print '<th align="middle"><input type="checkbox" id="code_folder_mainarea_result_table_select_all", "select_all" /><label for="code_folder_mainarea_result_table_select_all"><i class="fa fa-check"></i></label></th>';
}
print '<th>' . $this->lang->line('Name') . '</th>'; print '<th>' . $this->lang->line('Name') . '</th>';
print '<th>' . $this->lang->line('Revision') . '</th>'; print '<th>' . $this->lang->line('Revision') . '</th>';
print '<th>' . $this->lang->line('Size') . '</th>'; print '<th>' . $this->lang->line('Size') . '</th>';
@ -687,6 +780,12 @@ $this->load->view (
// directory // directory
$hexpath = $this->converter->AsciiToHex($fullpath); $hexpath = $this->converter->AsciiToHex($fullpath);
print "<tr class='{$rowclass}'>"; print "<tr class='{$rowclass}'>";
if (isset($login['id']) && $login['id'] != '')
{
print '<td align="middle">';
printf ('<input type="checkbox" name="code_folder_file_%d" value="%s" class="file_selector" id="code_folder_mainarea_result_table_file_selector_%d" />', $rownum, addslashes($f['name']), $rownum);
print '</td>';
}
print '<td>'; print '<td>';
print '<i class="fa fa-folder-o"></i> '; print '<i class="fa fa-folder-o"></i> ';
print anchor ( print anchor (
@ -701,7 +800,6 @@ $this->load->view (
print htmlspecialchars($f['last_author']); print htmlspecialchars($f['last_author']);
print '</td>'; print '</td>';
print '<td><code>'; print '<td><code>';
//print date('r', $f['time_t']);
print date('Y-m-d', $f['time_t']); print date('Y-m-d', $f['time_t']);
print '</code></td>'; print '</code></td>';
print '<td></td>'; print '<td></td>';
@ -715,6 +813,12 @@ $this->load->view (
$hexpath = $this->converter->AsciiToHex($fullpath); $hexpath = $this->converter->AsciiToHex($fullpath);
$executable_class = array_key_exists('executable', $f)? 'executable': ''; $executable_class = array_key_exists('executable', $f)? 'executable': '';
print "<tr class='{$rowclass} {$executable_class}'>"; print "<tr class='{$rowclass} {$executable_class}'>";
if (isset($login['id']) && $login['id'] != '')
{
print '<td align="middle">';
printf ('<input type="checkbox" name="code_folder_file_%d", value="%s" class="file_selector" id="code_folder_mainarea_result_table_file_selector_%d" />', $rownum, addslashes($f['name']), $rownum);
print '</td>';
}
print '<td>'; print '<td>';
$fa_type = codepot_get_fa_file_type ($f['name']); $fa_type = codepot_get_fa_file_type ($f['name']);
print "<i class='fa fa-{$fa_type}-o'></i> "; print "<i class='fa fa-{$fa_type}-o'></i> ";
@ -856,6 +960,11 @@ $this->load->view (
<?php print form_close();?> <?php print form_close();?>
</div> </div>
<div id="code_folder_mainarea_delete_form_div">
<div><?php print $this->lang->line('Message'); ?>:</div>
<div><textarea type='textarea' id='code_folder_mainarea_delete_message' name='code_folder_delete_message' style='width:100%;'></textarea></div>
</div>
<?php endif; ?> <?php endif; ?>
<div id='code_folder_mainarea_alert'></div> <div id='code_folder_mainarea_alert'></div>