diff options
| author | Christian Weiske <cweiske@cweiske.de> | 2012-09-19 23:55:07 +0200 |
|---|---|---|
| committer | Christian Weiske <cweiske@cweiske.de> | 2012-09-19 23:55:07 +0200 |
| commit | c85fb1700ce938f28da420af9636e246912a996b (patch) | |
| tree | 4d95a1e62726e3d218335e63c983406e0da1e3cf | |
| parent | 8701af280fa5a9c83827cdd0e2ae335d2512a3a7 (diff) | |
| download | phorkie-c85fb1700ce938f28da420af9636e246912a996b.tar.gz phorkie-c85fb1700ce938f28da420af9636e246912a996b.zip | |
implement request #13: simple remote forking works now
| -rw-r--r-- | data/templates/fork-remote-multiple.htm | 27 | ||||
| -rw-r--r-- | data/templates/fork-remote-new.htm (renamed from data/templates/new-fork-remote.htm) | 4 | ||||
| -rw-r--r-- | data/templates/fork-remote.htm | 13 | ||||
| -rw-r--r-- | data/templates/new.htm | 2 | ||||
| -rw-r--r-- | src/phorkie/ForkRemote.php | 76 | ||||
| -rw-r--r-- | www/fork-remote.php | 31 |
6 files changed, 142 insertions, 11 deletions
diff --git a/data/templates/fork-remote-multiple.htm b/data/templates/fork-remote-multiple.htm new file mode 100644 index 0000000..f5a95b2 --- /dev/null +++ b/data/templates/fork-remote-multiple.htm @@ -0,0 +1,27 @@ +<form method="post" action="/fork-remote" enctype="multipart/form-data" class="well form-inline form-horizontal"> + <div class="control-group"> + <p> + The URL you provided contains links to several Git repositories. + Select one of them. + </p> + <select size="{{urlselsize}}" name="remote_url" id="sel-remote_url" style="width:100%"> + {% for grouptitle, groupurls in urls %} + {% if groupurls|length == 1 %} + <option value="{{groupurls.0}}">{{grouptitle}}</option> + {% else %} + <optgroup label="{{grouptitle}}"> + {% for url in groupurls %} + <option value="{{url}}">{{url}}</option> + {% endfor %} + </optgroup> + {% endif %} + {% endfor %} + </select> + </div> + <div style="text-align: right"> + <button type="submit" class="btn btn-primary"> + <i class="icon-share icon-white"></i> Fork + </button> + </div> + +</form>
\ No newline at end of file diff --git a/data/templates/new-fork-remote.htm b/data/templates/fork-remote-new.htm index 02a94e2..6b48ffe 100644 --- a/data/templates/new-fork-remote.htm +++ b/data/templates/fork-remote-new.htm @@ -5,8 +5,8 @@ </p> <button type="submit" class="btn btn-primary" style="float: right"> - <i class="icon-share icon-white"></i>Fork remote paste + <i class="icon-share icon-white"></i> Fork remote paste </button> <label for="remote-url">Remote paste URL</label> - <input type="text" name="remote_url" id="remote-url" value="{{remote_url}}" class="input-xlarge"/> + <input type="text" name="remote_url" id="remote-url" value="{{remote_url}}" class="span5"/> </form> diff --git a/data/templates/fork-remote.htm b/data/templates/fork-remote.htm index f599ec6..f651661 100644 --- a/data/templates/fork-remote.htm +++ b/data/templates/fork-remote.htm @@ -2,5 +2,16 @@ {% block title %}Fork remote paste{% endblock %} {% block content %} - {% include 'new-fork-remote.htm' %} + {% include 'fork-remote-new.htm' %} + + {% if error %} + <div class="alert alert-error"> + {{error}} + </div> + {% endif %} + + {% if urls %} + {% include 'fork-remote-multiple.htm' %} + {% endif %} + {% endblock %} diff --git a/data/templates/new.htm b/data/templates/new.htm index f846fe5..8029b8c 100644 --- a/data/templates/new.htm +++ b/data/templates/new.htm @@ -21,7 +21,7 @@ </form> -{% include 'new-fork-remote.htm' %} +{% include 'fork-remote-new.htm' %} <script type="application/javascript"> $(document).ready(function() { diff --git a/src/phorkie/ForkRemote.php b/src/phorkie/ForkRemote.php index f3639b2..524255a 100644 --- a/src/phorkie/ForkRemote.php +++ b/src/phorkie/ForkRemote.php @@ -5,6 +5,16 @@ class ForkRemote { protected $url; + /** + * Array with keys (URL title) and values (arrays of urls) + * Only supported URLs are included. + * + * @var array + */ + protected $arGitUrls; + + + public function __construct($url) { $this->url = $url; @@ -16,11 +26,11 @@ class ForkRemote switch ($scheme) { case 'git': //clearly a git url - $this->gitUrl = $this->url; + $this->arGitUrls = array(array($this->url)); return true; case 'ssh': - //FIXME: maybe loosen this when we know how to skip the + //FIXME: maybe loosen this when we know how to skip the //"do you trust this server" question of ssh $this->error = 'ssh:// URLs are not supported'; return false; @@ -36,6 +46,68 @@ class ForkRemote protected function extractUrlsFromHtml($url) { + //HTML is not necessarily well-formed, and Gitorious has many problems + // in this regard + //$sx = simplexml_load_file($url); + libxml_use_internal_errors(true); + $sx = simplexml_import_dom(\DomDocument::loadHtmlFile($url)); + $elems = $sx->xpath('//*[@rel="vcs-git"]'); + + $count = $anonymous = 0; + foreach ($elems as $elem) { + if (!isset($elem['href'])) { + continue; + } + $str = (string)$elem; + if (isset($elem['title'])) { + //<link href=".." rel="vcs-git" title="title" /> + $title = (string)$elem['title']; + } else if ($str != '') { + //<a href=".." rel="vcs-git">title</a> + $title = $str; + } else { + $title = 'Unnamed repository #' . ++$anonymous; + } + $url = (string)$elem['href']; + if ($this->isSupported($url)) { + ++$count; + $this->arGitUrls[$title][] = $url; + } + } + + return $count > 0; + } + + /** + * Iterate through all git urls and return one if there is only + * one supported one. + * + * @return mixed Boolean false or string + */ + public function getUniqueGitUrl() + { + $nFound = 0; + foreach ($this->arGitUrls as $title => $arUrls) { + foreach ($arUrls as $url) { + $nFound++; + $uniqueUrl = $url; + } + } + + if ($nFound == 1) { + return $uniqueUrl; + } + return false; + } + + public function getGitUrls() + { + return $this->arGitUrls; + } + + public function isSupported($url) + { + return parse_url($url, PHP_URL_SCHEME) == 'git'; } } diff --git a/www/fork-remote.php b/www/fork-remote.php index dd58165..374c8b8 100644 --- a/www/fork-remote.php +++ b/www/fork-remote.php @@ -6,19 +6,40 @@ namespace phorkie; */ require_once 'www-header.php'; +$error = null; +$urls = null; if (isset($_POST['remote_url'])) { $fr = new ForkRemote($_POST['remote_url']); - $fr->parse(); - if ($fr->hasUniqueGitUrl()) { - //FIXME: fork + if (false === $fr->parse()) { + //no url found + $error = 'No git:// clone URL found'; + } else if (false !== ($gitUrl = $fr->getUniqueGitUrl())) { + $forker = new Forker(); + $new = $forker->forkRemote($gitUrl); + redirect($new->getLink('display')); + } else { + //multiple urls found + $urls = $fr->getGitUrls(); + } +} + +$selsize = 0; +if (is_array($urls)) { + foreach ($urls as $group) { + ++$selsize; + if (count($group) > 1) { + $selsize += count($group); + } } - //FIXME: display error or selection list } render( 'fork-remote', array( - 'remote_url' => isset($_POST['remote_url']) ? $_POST['remote_url'] : '' + 'remote_url' => isset($_POST['remote_url']) ? $_POST['remote_url'] : '', + 'error' => $error, + 'urls' => $urls, + 'urlselsize' => $selsize, ) ); ?> |
