From 779ba51a8f9c10f4fded7fd0995cd155328c273b Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Thu, 27 Aug 2015 08:55:33 +0000 Subject: [PATCH] enabled the code folder view to delete selected files/directories. --- codepot/pecl-svn/svn.c | 1 + codepot/src/codepot/controllers/code.php | 64 +++++++++ .../src/codepot/models/subversionmodel.php | 70 +++++++++- codepot/src/codepot/views/code_folder.php | 131 ++++++++++++++++-- 4 files changed, 253 insertions(+), 13 deletions(-) diff --git a/codepot/pecl-svn/svn.c b/codepot/pecl-svn/svn.c index 5c500e1a..aef590b2 100755 --- a/codepot/pecl-svn/svn.c +++ b/codepot/pecl-svn/svn.c @@ -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_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_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_UNVERSIONED", svn_wc_status_unversioned, CONST_CS|CONST_PERSISTENT); diff --git a/codepot/src/codepot/controllers/code.php b/codepot/src/codepot/controllers/code.php index ccfdc754..d3e55d09 100644 --- a/codepot/src/codepot/controllers/code.php +++ b/codepot/src/codepot/controllers/code.php @@ -457,6 +457,70 @@ class Code extends Controller 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 = '') { $this->load->model ('ProjectModel', 'projects'); diff --git a/codepot/src/codepot/models/subversionmodel.php b/codepot/src/codepot/models/subversionmodel.php index b85f42c4..44c61bbb 100644 --- a/codepot/src/codepot/models/subversionmodel.php +++ b/codepot/src/codepot/models/subversionmodel.php @@ -251,6 +251,7 @@ class SubversionModel extends Model public $store_file_errmsg = ''; public $import_files_errmsg = ''; + public $delete_files_errmsg = ''; function capture_save_error ($errno, $errmsg) { @@ -262,6 +263,11 @@ class SubversionModel extends Model $this->import_files_errmsg = $errmsg; } + function capture_delete_error ($errno, $errmsg) + { + $this->delete_files_errmsg = $errmsg; + } + function storeFile ($projectid, $path, $committer, $commit_message, $text) { $store_file_errmsg = ''; @@ -304,7 +310,7 @@ class SubversionModel extends Model function importFiles ($projectid, $path, $committer, $commit_message, $files, $uploader) { - $import_files_errmsg = ''; + $this->import_files_errmsg = ''; //$url = 'file://'.CODEPOT_SVNREPO_DIR."/{$projectid}/{$path}"; $full_path = CODEPOT_SVNREPO_DIR."/{$projectid}"; @@ -327,7 +333,7 @@ class SubversionModel extends Model set_error_handler (array ($this, 'capture_import_error')); 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 (); codepot_delete_files ($actual_tfname, TRUE); @@ -438,6 +444,66 @@ class SubversionModel extends Model 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) { //$url = 'file:///'.CODEPOT_SVNREPO_DIR."/{$projectid}/{$path}"; diff --git a/codepot/src/codepot/views/code_folder.php b/codepot/src/codepot/views/code_folder.php index 358d038e..2c18469d 100644 --- a/codepot/src/codepot/views/code_folder.php +++ b/codepot/src/codepot/views/code_folder.php @@ -200,6 +200,7 @@ function render_readme() var new_item_no = 0; var import_in_progress = false; +var delete_in_progress = false; function get_new_item_html(no, type, name) { @@ -310,10 +311,101 @@ $(function () { } ); + $('#code_folder_mainarea_delete_form_div').dialog ( + { + title: 'lang->line('Delete');?>', + resizable: true, + autoOpen: false, + width: 'auto', + height: 'auto', + modal: true, + buttons: { + '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 < ; 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('', '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('', 'id}/{$hex_headpath}"; ?>')); + } + else + { + show_alert ('
' + codepot_htmlspecialchars(data) + '
', "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, "lang->line('Error')?>"); + } + }); + } + else + { + show_alert ('
NOT SUPPORTED
', "lang->line('Error')?>"); + } + + }, + '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_form_div').dialog('open'); }); + $('#code_folder_mainarea_delete_button').button().click (function() { + $('#code_folder_mainarea_delete_form_div').dialog('open'); + }); + 0): ?> @@ -368,6 +460,12 @@ $(function () { }); + + $('#code_folder_mainarea_result_table_select_all').button().click (function() { + $('.file_selector').prop('checked', $('#code_folder_mainarea_result_table_select_all').is(':checked')); + }); + + $('#code_search_submit').button().click (function () { if ($.trim($("#code_search_string").val()) != "") { @@ -376,14 +474,6 @@ $(function () { $('#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_case_insensitively').button(); @@ -405,7 +495,6 @@ $(function () { render_readme (); - 0): ?> show_alert (' . htmlspecialchars($popup_error_message) . ''); ?>, "lang->line('Error')?>"); @@ -565,7 +654,6 @@ $this->load->view ( print form_hidden('search_wildcard_pattern', set_value('search_wildcard_pattern', $wildcard_pattern)); print ' '; - //print form_submit('search_submit', $this->lang->line('Search'), 'id="code_search_submit"'); printf ('%s', $this->lang->line('Search')); print ' | '; } @@ -596,6 +684,7 @@ $this->load->view ( if (isset($login['id']) && $login['id'] != '') { printf ('%s', $this->lang->line('New')); + printf ('%s', $this->lang->line('Delete')); } if ($file_count > 0) @@ -664,6 +753,10 @@ $this->load->view ( print ''; print ''; + if (isset($login['id']) && $login['id'] != '') + { + print ''; + } print ''; print ''; print ''; @@ -687,6 +780,12 @@ $this->load->view ( // directory $hexpath = $this->converter->AsciiToHex($fullpath); print ""; + if (isset($login['id']) && $login['id'] != '') + { + print ''; + } print ''; print ''; print ''; @@ -715,6 +813,12 @@ $this->load->view ( $hexpath = $this->converter->AsciiToHex($fullpath); $executable_class = array_key_exists('executable', $f)? 'executable': ''; print ""; + if (isset($login['id']) && $login['id'] != '') + { + print ''; + } print '
' . $this->lang->line('Name') . '' . $this->lang->line('Revision') . '' . $this->lang->line('Size') . '
'; + printf ('', $rownum, addslashes($f['name']), $rownum); + print ''; print ' '; print anchor ( @@ -701,7 +800,6 @@ $this->load->view ( print htmlspecialchars($f['last_author']); print ''; - //print date('r', $f['time_t']); print date('Y-m-d', $f['time_t']); print '
'; + printf ('', $rownum, addslashes($f['name']), $rownum); + print ''; $fa_type = codepot_get_fa_file_type ($f['name']); print " "; @@ -856,6 +960,11 @@ $this->load->view ( +
+
lang->line('Message'); ?>:
+
+
+