@@ -16,7 +16,8 @@ class SourceSVNPlugin extends MantisSourcePlugin {
1616 * Error constants
1717 */
1818 const ERROR_PATH_INVALID = 'path_invalid ' ;
19- const ERROR_RUN_SVN = 'run_svn ' ;
19+ const ERROR_SVN_RUN = 'svn_run ' ;
20+ const ERROR_SVN_CMD = 'svn_cmd ' ;
2021
2122 public function register () {
2223 $ this ->name = plugin_lang_get ( 'title ' );
@@ -45,7 +46,8 @@ public function config() {
4546 public function errors () {
4647 $ t_errors_list = array (
4748 self ::ERROR_PATH_INVALID ,
48- self ::ERROR_RUN_SVN ,
49+ self ::ERROR_SVN_RUN ,
50+ self ::ERROR_SVN_CMD ,
4951 );
5052
5153 foreach ( $ t_errors_list as $ t_error ) {
@@ -250,11 +252,10 @@ public function update_config() {
250252
251253 public function commit ( $ p_repo , $ p_data ) {
252254 if ( preg_match ( '/(\d+)/ ' , $ p_data , $ p_matches ) ) {
253- $ svn = $ this ->svn_call ( $ p_repo );
254255
255256 $ t_url = $ p_repo ->url ;
256257 $ t_revision = $ p_matches [1 ];
257- $ t_svnlog_xml = shell_exec ( "$ svn log -v $ t_url -r $ t_revision --xml " );
258+ $ t_svnlog_xml = $ this -> svn_run ( "log -v $ t_url -r $ t_revision --xml " , $ p_repo );
258259
259260 if ( SourceChangeset::exists ( $ p_repo ->id , $ t_revision ) ) {
260261 echo "Revision $ t_revision already committed! \n" ;
@@ -266,8 +267,6 @@ public function commit( $p_repo, $p_data ) {
266267 }
267268
268269 public function import_full ( $ p_repo ) {
269- $ this ->svn_check ();
270- $ svn = $ this ->svn_call ( $ p_repo );
271270
272271 $ t_changeset_table = plugin_table ( 'changeset ' , 'Source ' );
273272
@@ -279,18 +278,11 @@ public function import_full( $p_repo ) {
279278 $ t_url = $ p_repo ->url ;
280279 $ t_rev = ( false === $ t_db_revision ? 0 : $ t_db_revision + 1 );
281280
282-
283281 # finding max revision
284- $ t_svninfo_xml = shell_exec ( "$ svn info $ t_url --xml " );
285- try {
286- # create parser
287- $ t_svninfo_parsed_xml = new SimpleXMLElement ($ t_svninfo_xml );
288- }
289- catch ( Exception $ e ) {
290- # parsing error - no success here
291- echo '<pre>svn info returned invalid xml code</pre> ' ;
292- return array ();
293- }
282+ $ t_svninfo_xml = $ this ->svn_run ( "info $ t_url --xml " , $ p_repo );
283+ # create parser
284+ $ t_svninfo_parsed_xml = new SimpleXMLElement ($ t_svninfo_xml );
285+
294286 $ t_max_rev = (integer ) $ t_svninfo_parsed_xml ->entry ->commit ['revision ' ];
295287
296288 # this is required because invalid revision number render invalid xml output for svn log
@@ -299,12 +291,11 @@ public function import_full( $p_repo ) {
299291 return array ();
300292 }
301293
302-
303294 echo '<pre> ' ;
304295 echo "Requesting svn log for {$ p_repo ->name } starting with revision {$ t_rev }... \n" ;
305296
306297 # get the svn log in xml format
307- $ t_svnlog_xml = shell_exec ( "$ svn log -v -r $ t_rev:HEAD --limit 200 $ t_url --xml " );
298+ $ t_svnlog_xml = $ this -> svn_run ( "log -v -r $ t_rev:HEAD --limit 200 $ t_url --xml " , $ p_repo );
308299
309300 # parse the changesets
310301 $ t_changesets = $ this ->process_svn_log_xml ( $ p_repo , $ t_svnlog_xml );
@@ -317,12 +308,46 @@ public function import_latest( $p_repo ) {
317308 return $ this ->import_full ( $ p_repo );
318309 }
319310
320- private function svn_check () {
321- $ svn = self ::svn_call ();
311+ /**
312+ * Execute SVN command, catching & raising errors in both
313+ * execution and output
314+ * @param string $p_cmd Command and any parameters
315+ * @param SourceRepo $p_repo Repository to access
316+ * @return string Output of SVN command
317+ */
318+ private function svn_run ( $ p_cmd , $ p_repo = null )
319+ {
320+ # Get "base" SVN command, including any configured parameters
321+ $ t_svn_exe = self ::svn_call ( $ p_repo );
322+ # Append specific cmd & params
323+ $ t_svn_cmd = "$ t_svn_exe $ p_cmd " ;
324+
325+ $ t_svn_proc = proc_open (
326+ $ t_svn_cmd ,
327+ array ( array ( 'pipe ' , 'r ' ), array ( 'pipe ' , 'w ' ), array ( 'pipe ' , 'w ' ) ),
328+ $ t_pipes
329+ );
330+
331+ # Check & report execution failure
332+ if ( $ t_svn_proc === false ) {
333+ plugin_error ( self ::ERROR_SVN_RUN );
334+ }
322335
323- if ( is_blank ( shell_exec ( "$ svn help " ) ) ) {
324- plugin_error ( self ::ERROR_RUN_SVN );
336+ # Get output of the process & clean up
337+ $ t_stderr = stream_get_contents ( $ t_pipes [2 ] );
338+ fclose ( $ t_pipes [2 ] );
339+ $ t_svn_out = stream_get_contents ( $ t_pipes [1 ] );
340+ fclose ( $ t_pipes [1 ] );
341+ fclose ( $ t_pipes [0 ] );
342+ proc_close ( $ t_svn_proc );
343+
344+ # Error handling
345+ if ( $ t_stderr ) {
346+ error_parameters ( trim ( $ t_stderr ) );
347+ plugin_error ( self ::ERROR_SVN_CMD );
325348 }
349+
350+ return $ t_svn_out ;
326351 }
327352
328353 private function svn_call ( $ p_repo =null ) {
@@ -435,13 +460,7 @@ private function process_svn_log_xml( $p_repo, $p_svnlog_xml ) {
435460 return array ();
436461
437462 # parse XML
438- try {
439- $ t_xml = new SimpleXMLElement ($ p_svnlog_xml );
440- }
441- catch ( Exception $ e ) {
442- echo 'Parsing error of xml log... ' ;
443- return array ();
444- }
463+ $ t_xml = new SimpleXMLElement ($ p_svnlog_xml );
445464
446465 # timezone for conversions in loca
447466 $ t_utc = new DateTimeZone ('UTC ' );
0 commit comments