.gitignore000064400000000036144761607100006541 0ustar00/vendor/ /tests/ composer.lockREADME.md000064400000000012144761607100006022 0ustar00# borusvn composer.json000064400000000744144761607100007301 0ustar00{ "name": "boru/borusvn", "type": "library", "autoload": { "psr-4": { "boru\\borusvn\\": "src/" } }, "authors": [ { "name": "Daniel Hayes", "email": "dhayes@boruapps.com" } ], "repositories": [ { "type": "composer", "url": "https://satis.boruapps.com" } ], "require": { "boru/borudiff": "^1.0", "boru/borussh": "*" } } instructions-composer.txt000064400000000303144761607100011700 0ustar00{ "require": { "boru/borudiff": "*" }, "repositories": [ { "type": "composer", "url": "https://satis.boruapps.com" } ] }src/SVN.php000064400000016770144761607100006533 0ustar00user = $user; $this->pass = $pass; $this->host = $host; $this->port = $port; $this->svnuser = $user; $this->svnpass = $pass; } function setAuth($user,$pass) { $this->svnuser = $user; $this->svnpass = $pass; } function log($url,$limit=5,$revision_start=null) { if($revision_start !== null) { $rev = "-r $revision_start"; } else { $rev = "-r HEAD"; } $output = $this->xml($this->svncmd("log -l$limit $rev:0 --xml --verbose $url")); if(!isset($output->logentry)) { return array(); } $outarr = array(); //echo "
";var_dump($output);echo "
"; if(!is_array($output->logentry)) { $logentry_arr[] = $output->logentry; } else { $logentry_arr = $output->logentry; } //echo "
";var_dump($logentry_arr);echo "
"; foreach($logentry_arr as $k=>$obj) { $revision =$obj->{"@attributes"}->revision; $author = $obj->author; $date = $this->convertDateFormat($obj->date); $changes = $this->pathsToArray($obj->paths); $arr = array(); $arr["revision"] = $revision; $arr["author"] = $author; $arr["date"] = $date; $arr["changes"] = $changes; $outarr[] = $arr; } return $outarr; } function files($url,$full=false,$revision=null) { $cmd = "list --xml"; if($full) $cmd.=" --depth infinity"; $cmd .=" ".$url; if($revision !== null) $cmd.=" -r $revision"; $data = $this->xml($this->svncmd($cmd)); $entries = array(); if(!is_array($data->{"list"}->entry)) { $entries[] = $data->{"list"}->entry; } else { $entries = $data->{"list"}->entry; } //echo "
"; var_dump($entries); echo "
"; $output = array(); foreach($entries as $k=>$entry) { $name = $entry->name; $kind = $entry->{"@attributes"}->kind; if($kind == "file") $size = $entry->size; else $size=0; $revision = $entry->commit->{"@attributes"}->revision; $author = $entry->commit->author; $date = $this->convertDateFormat($entry->commit->date); $output[$name]["type"] = $kind; $output[$name]["size"] = $size; $output[$name]["revision"] = $revision; $output[$name]["author"] = $author; $output[$name]["date"] = $date; } if($full) { $split_array = array(); foreach($output as $path=>$info) { if($info["type"] != "dir") { $parts = explode("/",$path); $leaf = array_pop($parts); $parentArr = &$split_array; foreach($parts as $part) { if(!isset($parentArr[$part])) { $parentArr[$part] = array(); } elseif (!is_array($parentArr[$part])) { $parentArr[$part] = array(); } $parentArr = &$parentArr[$part]; } $parentArr[$leaf] = $info; } } return $split_array; } else { $folders = array(); $files = array(); foreach($output as $path=>$info) { if($info["type"] == "dir") { $folders[] = $path; } else { $files[] = $path; } } natcasesort($folders); natcasesort($files); $newoutput = array(); foreach($folders as $k=>$path) { $newoutput[$path]=$output[$path]; } foreach($files as $k=>$path) { $newoutput[$path]=$output[$path]; } return $newoutput; } } function diff($url,$revision_start=0,$revision_end="HEAD",$type="side",$ignoreWhitespace=true,$ignoreCase=false,$blame=false){ if($blame) { $data1 = explode("\n",$this->blame($url,$revision_start)); $data2 = explode("\n",$this->blame($url,$revision_end)); } else { $data1 = explode("\n",$this->cat($url,$revision_start)); $data2 = explode("\n",$this->cat($url,$revision_end)); } $options = array('ignoreWhitespace'=>$ignoreWhitespace,'ignoreCase'=>$ignoreCase); $diff = new Diff($data1,$data2,$options); if($type == "side") { return $diff->toHtmlSideBySide(); } else { return $diff->toHtmlInline(); } } function diffFiles($url1,$revision1,$url2,$revision2,$type="side",$ignoreWhitespace=true,$ignoreCase=false,$blame=false){ if($blame) { $data1 = explode("\n",$this->blame($url1,$revision1)); $data2 = explode("\n",$this->blame($url2,$revision2)); } else { $data1 = explode("\n",$this->cat($url1,$revision1)); $data2 = explode("\n",$this->cat($url2,$revision2)); } $options = array('ignoreWhitespace'=>$ignoreWhitespace,'ignoreCase'=>$ignoreCase); $diff = new Diff($data1,$data2,$options); if($type == "side") { return $diff->toHtmlSideBySide(); } else { return $diff->toHtmlInline(); } } function summary($url,$revision_start=0,$revision_end="HEAD") { $output = $this->xml($this->svncmd("diff --summarize --revision $revision_start:$revision_end --xml $url")); $outarr = $this->pathsToArray($output->paths,$url); return $outarr; } function cat($url,$revision="HEAD") { if($revision != "HEAD") { $rev = "--revision $revision"; } return $this->svncmd("cat $rev $url"); } function blame($url,$revision="HEAD") { if($revision != "HEAD") { $rev = "--revision $revision"; } return $this->svncmd("blame $rev $url"); } function info($url) { return $this->xml($this->svncmd("info --xml $url")); } function svncmd($command) { $cmd = "svn --username=".$this->svnuser." --password=".$this->svnpass." ".$command; $this->printDebug($cmd); return $this->exec($cmd); } /* data utilities*/ function xml($string) { $sxml = new SimpleXML(); return $sxml->xml_load_file($string); } function convertDateFormat($input) { return date("Y-m-d H:i:s",strtotime($input)); } function pathsToArray($pathsObj,$url="") { if(!isset($pathsObj->path)) { return false; } $paths = array(); if(is_object($pathsObj->path)) { $paths[] = $pathsObj->path; } else { $paths = $pathsObj->path; } $output = array(); foreach($paths as $k=>$path) { $file = $path->{"@content"}; if($url != "") $file=str_replace($url,"",$file); if(isset($path->{"@attributes"}->item)) { $type = $path->{"@attributes"}->item; if($type == "modified") { $td = "M"; } if($type == "added") { $td = "A"; } if($type == "deleted") { $td = "D"; } } if(isset($path->{"@attributes"}->action)) { $td = $path->{"@attributes"}->action; } $arr=array(); $arr["file"] = $file; $arr["type"] = $td; $output[] = $arr; } return $output; } /*Server connection utilities*/ function connect($shell=false) { if(!$shell) { $this->shell = new SSH(); } else { $this->shell = $shell; } $this->shell->debug(false); if(!$this->connected) { if( ($this->connected = $this->shell->login($this->user,$this->pass,$this->host,$this->port)) === false) { throw new \Exception("SSH: unable to connect to ".$this->host.":".$this->port); } } return true; } function disconnect() { if($this->connected) { $this->shell->disconnect(); } } function exec($cmd,$block=true) { if(!$this->connected) { $this->connect(); } if($this->connected) { return $this->shell->exec_cmd($cmd,$block); } } function printDebug($data) { if($this->debug) echo date("H:i:s")." - ".$data."\n"; } }src/lib/SimpleXML.php000064400000017326144761607100010443 0ustar00ignore_level + 1; $c < $level + 1; $c++) { if (isset($tags[$c]) && (is_numeric(trim($tags[$c])) || trim($tags[$c]))) { if (is_numeric($tags[$c])) { $temp .= '[' . $tags[$c] . ']'; } else { $temp .= '["' . $tags[$c] . '"]'; } } } $this->evalCode .= '$this->result' . $temp . "=\"" . addslashes($value) . "\";//(" . $type . ")\n"; #echo $code. "\n"; } /** * Define the repeated tags in XML file so we can set an index * * @param array $array * @return array */ function xml_tags($array) { $repeats_temp = array(); $repeats_count = array(); $repeats = array(); if (is_array($array)) { $n = count($array) - 1; for ($i = 0; $i < $n; $i++) { $idn = $array[$i]['tag'].$array[$i]['level']; if(in_array($idn,$repeats_temp)){ $repeats_count[array_search($idn,$repeats_temp)]+=1; }else{ array_push($repeats_temp,$idn); $repeats_count[array_search($idn,$repeats_temp)]=1; } } } $n = count($repeats_count); for($i=0;$i<$n;$i++){ if($repeats_count[$i]>1){ array_push($repeats,$repeats_temp[$i]); } } unset($repeats_temp); unset($repeats_count); return array_unique($repeats); } /** * Converts Array Variable to Object Variable * * @param array $arg_array * @return $tmp */ function array2object ($arg_array) { if (is_array($arg_array)) { $keys = array_keys($arg_array); if(!is_numeric($keys[0])) $tmp = new SimpleXMLObject; foreach ($keys as $key) { if (is_numeric($key)) $has_number = true; if (is_string($key)) $has_string = true; } if (isset($has_number) and !isset($has_string)) { foreach ($arg_array as $key => $value) { $tmp[] = $this->array2object($value); } } elseif (isset($has_string)) { foreach ($arg_array as $key => $value) { if (is_string($key)) $tmp->$key = $this->array2object($value); } } } elseif (is_object($arg_array)) { $tmp = new SimpleXMLObject; foreach ($arg_array as $key => $value) { if (is_array($value) or is_object($value)) $tmp->$key = $this->array2object($value); else $tmp->$key = $value; } } else { $tmp = $arg_array; } return $tmp; //return the object } /** * Reindexes the whole array with ascending numbers * * @param array $array * @return array */ function array_reindex($array) { if (is_array($array)) { if(count($array) == 1 && $array[0]){ return $this->array_reindex($array[0]); }else{ foreach($array as $keys => $items) { if (is_array($items)) { if (is_numeric($keys)) { $array[$keys] = $this->array_reindex($items); } else { $array[$keys] = $this->array_reindex(array_merge(array(), $items)); } } } } } return $array; } /** * Parse the XML generation to array object * * @param array $array * @return array */ function xml_reorganize($array) { $count = count($array); $repeat = $this->xml_tags($array); $repeatedone = false; $tags = array(); $k = 0; for ($i = 0; $i < $count; $i++) { switch ($array[$i]['type']) { case 'open': array_push($tags, $array[$i]['tag']); if ($i > 0 && ($array[$i]['tag'] == $array[$i-1]['tag']) && ($array[$i-1]['type'] == 'close')) $k++; if (isset($array[$i]['value']) && ($array[$i]['value'] || !$this->skip_empty_values)) { array_push($tags, '@content'); $this->array_insert(count($tags), $tags, $array[$i]['value'], "open"); array_pop($tags); } if (in_array($array[$i]['tag'] . $array[$i]['level'], $repeat)) { if (($repeatedone == $array[$i]['tag'] . $array[$i]['level']) && ($repeatedone)) { array_push($tags, strval($k++)); } else { $repeatedone = $array[$i]['tag'] . $array[$i]['level']; array_push($tags, strval($k)); } } if (isset($array[$i]['attributes']) && $array[$i]['attributes'] && $array[$i]['level'] != $this->ignore_level) { array_push($tags, '@attributes'); foreach ($array[$i]['attributes'] as $attrkey => $attr) { array_push($tags, $attrkey); $this->array_insert(count($tags), $tags, $attr, "open"); array_pop($tags); } array_pop($tags); } break; case 'close': array_pop($tags); if (in_array($array[$i]['tag'] . $array[$i]['level'], $repeat)) { if ($repeatedone == $array[$i]['tag'] . $array[$i]['level']) { array_pop($tags); } else { $repeatedone = $array[$i + 1]['tag'] . $array[$i + 1]['level']; array_pop($tags); } } break; case 'complete': array_push($tags, $array[$i]['tag']); if (in_array($array[$i]['tag'] . $array[$i]['level'], $repeat)) { if ($repeatedone == $array[$i]['tag'] . $array[$i]['level'] && $repeatedone) { array_push($tags, strval($k)); } else { $repeatedone = $array[$i]['tag'] . $array[$i]['level']; array_push($tags, strval($k)); } } if (isset($array[$i]['value']) && ($array[$i]['value'] || !$this->skip_empty_values)) { if (isset($array[$i]['attributes']) && $array[$i]['attributes']) { array_push($tags, '@content'); $this->array_insert(count($tags), $tags, $array[$i]['value'], "complete"); array_pop($tags); } else { $this->array_insert(count($tags), $tags, $array[$i]['value'], "complete"); } } if (isset($array[$i]['attributes']) && $array[$i]['attributes']) { array_push($tags, '@attributes'); foreach ($array[$i]['attributes'] as $attrkey => $attr) { array_push($tags, $attrkey); $this->array_insert(count($tags), $tags, $attr, "complete"); array_pop($tags); } array_pop($tags); } if (in_array($array[$i]['tag'] . $array[$i]['level'], $repeat)) { array_pop($tags); $k++; } array_pop($tags); break; } } eval($this->evalCode); $last = $this->array_reindex($this->result); return $last; } /** * Get the XML contents and parse like SimpleXML * * @param string $file * @param string $resulttype * @param string $encoding * @return array/object */ function xml_load_file($file, $resulttype = 'object', $encoding = 'UTF-8') { $php_errormsg=""; $this->result=""; $this->evalCode=""; $values=""; //$data = file_get_contents($file); $data = $file; if (!$data) return 'Cannot open xml document: ' . (isset($php_errormsg) ? $php_errormsg : $file); $parser = xml_parser_create($encoding); xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); $ok = xml_parse_into_struct($parser, $data, $values); if (!$ok) { $errmsg = sprintf("XML parse error %d '%s' at line %d, column %d (byte index %d)", xml_get_error_code($parser), xml_error_string(xml_get_error_code($parser)), xml_get_current_line_number($parser), xml_get_current_column_number($parser), xml_get_current_byte_index($parser)); } xml_parser_free($parser); if (!$ok) return $errmsg; if ($resulttype == 'array') return $this->xml_reorganize($values); // default $resulttype is 'object' return $this->array2object($this->xml_reorganize($values)); } }src/lib/SimpleXMLObject.php000064400000000504144761607100011560 0ustar00