Compare commits
5 Commits
feature.we
...
feature.is
Author | SHA1 | Date | |
---|---|---|---|
|
813184f06c | ||
|
d860f299fd | ||
|
33882d4fa7 | ||
|
13fad756ab | ||
|
1f0791df0e |
@@ -13,7 +13,6 @@ or newer to properly run this version of Indefero!
|
||||
- Display monotone file and directory attributes in the tree and file view
|
||||
(needs a monotone with an interface version of 13.1 or newer)
|
||||
- The context area is now kept in view when a page scrolls down several pages
|
||||
- git repositories are now available under /r/projectname/
|
||||
|
||||
## Bugfixes
|
||||
|
||||
@@ -32,6 +31,7 @@ or newer to properly run this version of Indefero!
|
||||
a new project or monotone key, in case an error popped up in the middle (issue 697)
|
||||
- Indefero now sends the MD5 checksum as HTTP header when downloading a file from the
|
||||
download area. Additionally, a unneeded redirect has been removed. (issue 716)
|
||||
- Source links without a specific revision did not work due to a wrong regex (issue 730)
|
||||
- Better error detection and reporting in the SyncMonotone plugin
|
||||
ATTENTION: This needs Pluf 46b7f251 or newer!
|
||||
- Fix the branch links users of the Subversion frontend get when they enter a wrong revision
|
||||
|
@@ -1,57 +0,0 @@
|
||||
# Accessing git repositories over HTTP
|
||||
|
||||
Starting with indefero 1.2, git repositories are provided via http,
|
||||
featuring read-only and read-write access with full integration with
|
||||
indefero's access control mechanisms.
|
||||
|
||||
## Access git repositories
|
||||
|
||||
The repositories are available under http://YOURHOST/BASEPATH/r/PROJECT.
|
||||
|
||||
For authentication, use the "extra password" which you can find on your
|
||||
profile page.
|
||||
|
||||
## Setup
|
||||
|
||||
The main thing to setup is git_repositories and git_remote_url in
|
||||
src/IDF/conf/idf.php
|
||||
|
||||
git_remote_url should match http://YOURHOST/BASEPATH/r/%s, while
|
||||
git_repositories points to the local directory supposed to contain the
|
||||
repositories like /PATH/TO/REPOSITORIES/%s.git.
|
||||
|
||||
## Setup requirements when using PHP over FastCGI
|
||||
|
||||
There are a couple of things to setup when using PHP over FastCGI, as compared
|
||||
to mod_php or similar integrated mechanisms:
|
||||
|
||||
- You will need to setup a RewriteRule for mod_rewrite (in case of Apache,
|
||||
analogous mechanisms might need to be setup for other http daemons), which
|
||||
passes through the Authorization HTTP Header of a request.
|
||||
|
||||
In case of mod_rewrite, the necessary line is
|
||||
one of (depending on server configuration):
|
||||
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
|
||||
RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization},L]
|
||||
|
||||
- The FastCGI adaptor must allow large requests to be handled by PHP,
|
||||
otherwise push might fail.
|
||||
|
||||
For mod_fcgid, this is the FcgidMaxRequestLen option, or MaxRequestLen in
|
||||
older versions. Set this option to some large enough value - there is no
|
||||
issue with RAM use, as another option defines the limit after which the
|
||||
request is backed on disk, which can remain small.
|
||||
|
||||
## When migrating from syncgit
|
||||
|
||||
HTTP access can be used in parallel to syncgit.
|
||||
|
||||
If you want to disable syncgit, just undo the changes detailled
|
||||
in doc/syncgit.mdtext:
|
||||
- In src/IDF/conf/idf.php keep git_repositories
|
||||
- In src/IDF/conf/idf.php adapt git_remote_url to http://host/basepath/r/%s
|
||||
- In src/IDF/conf/idf.php remove idf_plugin_syncgit*
|
||||
- Remove the cronjob that called gitcron.php
|
||||
- Disable the git daemon (eg. /etc/event.d/local-git-daemon)
|
||||
- You can remove the git user and group, if you also adapt the git repositories
|
||||
to be owned by the www user.
|
@@ -44,7 +44,7 @@ class IDF_Middleware
|
||||
function process_request(&$request)
|
||||
{
|
||||
$match = array();
|
||||
if (preg_match('#^/(?:api/p|p|r)/([\-\w]+)/?#', $request->query, $match)) {
|
||||
if (preg_match('#^/(?:api/p|p)/([\-\w]+)/?#', $request->query, $match)) {
|
||||
try {
|
||||
$request->project = IDF_Project::getOr404($match[1]);
|
||||
} catch (Pluf_HTTP_Error404 $e) {
|
||||
@@ -88,6 +88,7 @@ class IDF_Middleware
|
||||
'showuser' => 'IDF_Template_ShowUser',
|
||||
'ashowuser' => 'IDF_Template_AssignShowUser',
|
||||
'appversion' => 'IDF_Template_AppVersion',
|
||||
'upload' => 'IDF_Template_Tag_UploadUrl',
|
||||
));
|
||||
$params['modifiers'] = array_merge($params['modifiers'],
|
||||
array(
|
||||
|
@@ -497,10 +497,5 @@ class IDF_Scm
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function repository($request, $match)
|
||||
{
|
||||
throw new Exception('This repository does not support web based repository access');
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -924,113 +924,4 @@ class IDF_Scm_Git extends IDF_Scm
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function repository($request, $match)
|
||||
{
|
||||
// handle a couple of workarounds for authenticating with FastCGI/PHP
|
||||
if (!empty($_SERVER['HTTP_AUTHORIZATION']))
|
||||
list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':' , base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));
|
||||
elseif (!empty($_SERVER['REDIRECT_HTTP_AUTHORIZATION']))
|
||||
list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':' , base64_decode(substr($_SERVER['REDIRECT_HTTP_AUTHORIZATION'], 6)));
|
||||
elseif (!empty($_SERVER['REDIRECT_REMOTE_USER']))
|
||||
list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':' , base64_decode(substr($_SERVER['REDIRECT_REMOTE_USER'], 6)));
|
||||
|
||||
// authenticate: authenticate connection through "extra" password
|
||||
if (!empty($_SERVER['PHP_AUTH_USER'])) {
|
||||
$sql = new Pluf_SQL('login=%s', array($_SERVER['PHP_AUTH_USER']));
|
||||
$users = Pluf::factory('Pluf_User')->getList(array('filter'=>$sql->gen()));
|
||||
if (count($users) == 1 && $users[0]->active) {
|
||||
$user = $users[0];
|
||||
$realkey = substr(sha1($user->password.Pluf::f('secret_key')), 0, 8);
|
||||
if ($_SERVER['PHP_AUTH_PW'] == $realkey) {
|
||||
$request->user = $user;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IDF_Precondition::accessSource($request) !== true) {
|
||||
$response = new Pluf_HTTP_Response("");
|
||||
$response->status_code = 401;
|
||||
$response->headers['WWW-Authenticate']='Basic realm="git for '.$this->project.'"';
|
||||
return $response;
|
||||
}
|
||||
|
||||
$path = $match[2];
|
||||
|
||||
if (!file_exists($this->repo)) {
|
||||
mkdir($this->repo, 0750, true);
|
||||
$out = array();
|
||||
$res = 0;
|
||||
exec(sprintf(Pluf::f('idf_exec_cmd_prefix', '').
|
||||
Pluf::f('git_path', 'git').' --git-dir=%s init', escapeshellarg($this->repo)),
|
||||
$out, $res);
|
||||
if ($res != 0) {
|
||||
Pluf_Log::error(array('IDF_Scm_Git::repository', $res, $this->repo));
|
||||
throw new Exception(sprintf('Init repository error, exit status %d.', $res));
|
||||
}
|
||||
}
|
||||
|
||||
// update files before delivering them
|
||||
if (($path == 'objects/info/pack') || ($path == 'info/refs')) {
|
||||
$cmd = sprintf(Pluf::f('idf_exec_cmd_prefix', '').
|
||||
'GIT_DIR=%s '.Pluf::f('git_path', 'git').' update-server-info -f',
|
||||
escapeshellarg($this->repo));
|
||||
self::shell_exec('IDF_Scm_Git::repository', $cmd);
|
||||
}
|
||||
|
||||
// smart HTTP discovery
|
||||
if ($path == 'info/refs' && !empty($request->GET['service'])){
|
||||
$service = $request->GET['service'];
|
||||
switch ($service) {
|
||||
case 'git-receive-pack':
|
||||
if (IDF_Precondition::projectMemberOrOwner($request) !== true) {
|
||||
$response = new Pluf_HTTP_Response("");
|
||||
$response->status_code = 401;
|
||||
$response->headers['WWW-Authenticate']='Basic realm="git for '.$this->project.'"';
|
||||
return $response;
|
||||
}
|
||||
case 'git-upload-pack':
|
||||
$content = sprintf('%04x',strlen($service)+15).
|
||||
'# service='.$service."\n0000";
|
||||
$content .= self::shell_exec('IDF_Scm_Git::repository',
|
||||
Pluf::f('idf_exec_cmd_prefix', '').
|
||||
$service.' --stateless-rpc --advertise-refs '.
|
||||
$this->repo);
|
||||
$response = new Pluf_HTTP_Response($content,
|
||||
'application/x-'.$service.'-advertisement');
|
||||
return $response;
|
||||
default:
|
||||
throw new Exception('unknown service: '.$service);
|
||||
}
|
||||
}
|
||||
|
||||
switch($path) {
|
||||
// smart HTTP RPC
|
||||
case 'git-receive-pack':
|
||||
if (IDF_Precondition::projectMemberOrOwner($request) !== true) {
|
||||
$response = new Pluf_HTTP_Response("");
|
||||
$response->status_code = 401;
|
||||
$response->headers['WWW-Authenticate']='Basic realm="git for '.$this->project.'"';
|
||||
return $response;
|
||||
}
|
||||
case 'git-upload-pack':
|
||||
$response = new Pluf_HTTP_Response_CommandPassThru(
|
||||
Pluf::f('idf_exec_cmd_prefix', '').$path.
|
||||
' --stateless-rpc '.$this->repo,
|
||||
'application/x-'.$path.'-result');
|
||||
$response->setStdin(fopen('php://input', 'rb'));
|
||||
return $response;
|
||||
|
||||
// regular file
|
||||
default:
|
||||
// make sure we're inside the repo hierarchy (ie. no break-out)
|
||||
if (is_file($this->repo.'/'.$path) &&
|
||||
strpos(realpath($this->repo.'/'.$path), $this->repo.'/') == 0) {
|
||||
return new Pluf_HTTP_Response_File($this->repo.'/'.$path,
|
||||
'application/octet-stream');
|
||||
} else {
|
||||
return new Pluf_HTTP_Response_NotFound($request);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -58,7 +58,7 @@ class IDF_Template_IssueComment extends Pluf_Template_Tag
|
||||
implode('|', $nouns);
|
||||
$text = IDF_Template_safePregReplace('#((?:'.$prefix.')(?:\s+r?))([0-9a-f]{1,40}((?:\s+and|\s+or|,)\s+r?[0-9a-f]{1,40})*)\b#i',
|
||||
array($this, 'callbackCommits'), $text);
|
||||
$text = IDF_Template_safePregReplace('=(src:)([^\s@#,\(\)\\\\]+(?:(\\\\)[\s@#][^\s@#,\(\)\\\\]+){0,})+(?:\@([^\s#,]+))(?:#(\d+))?=im',
|
||||
$text = IDF_Template_safePregReplace('=(src:)([^\s@#,\(\)\\\\]+(?:(\\\\)[\s@#][^\s@#,\(\)\\\\]+){0,})+(?:\@([^\s#,]+))?(?:#(\d+))?=im',
|
||||
array($this, 'callbackSource'), $text);
|
||||
}
|
||||
if ($wordwrap) $text = Pluf_Text::wrapHtml($text, 69, "\n");
|
||||
|
35
src/IDF/Template/Tag/UploadUrl.php
Normal file
35
src/IDF/Template/Tag/UploadUrl.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# This file is part of InDefero, an open source project management application.
|
||||
# Copyright (C) 2011 Céondo Ltd and contributors.
|
||||
#
|
||||
# InDefero is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# InDefero is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
# ***** END LICENSE BLOCK ***** */
|
||||
|
||||
class IDF_Template_Tag_UploadUrl extends Pluf_Template_Tag
|
||||
{
|
||||
function start($file='')
|
||||
{
|
||||
echo IDF_Template_Tag_UploadUrl::url($file);
|
||||
}
|
||||
|
||||
public static function url($file='')
|
||||
{
|
||||
return Pluf::f('url_upload', Pluf_Template_Tag_MediaUrl::url() . '/upload') . $file;
|
||||
}
|
||||
}
|
@@ -109,11 +109,13 @@ class IDF_Views_Issue
|
||||
foreach ($owners as $user => $nb) {
|
||||
if ($user === '') {
|
||||
$key = __('Not assigned');
|
||||
$login = null;
|
||||
} else {
|
||||
$obj = Pluf::factory('Pluf_User')->getOne(array('filter'=>'id='.$user));
|
||||
$key = $obj->first_name . ' ' . $obj->last_name;
|
||||
$login = $obj->login;
|
||||
}
|
||||
$ownerStatistics[$key] = array($nb, (int)(100 * $nb / $opened));
|
||||
$ownerStatistics[$key] = array($nb, (int)(100 * $nb / $opened), $login);
|
||||
}
|
||||
|
||||
// Issue class tag statistics
|
||||
@@ -313,42 +315,55 @@ class IDF_Views_Issue
|
||||
*
|
||||
* Only open issues are shown.
|
||||
*/
|
||||
public $myIssues_precond = array('IDF_Precondition::accessIssues',
|
||||
'Pluf_Precondition::loginRequired');
|
||||
public function myIssues($request, $match)
|
||||
public $userIssues_precond = array('IDF_Precondition::accessIssues');
|
||||
public function userIssues($request, $match)
|
||||
{
|
||||
$prj = $request->project;
|
||||
|
||||
$sql = new Pluf_SQL('login=%s', array($match[2]));
|
||||
$user = Pluf::factory('Pluf_User')->getOne(array('filter' => $sql->gen()));
|
||||
if ($user === null) {
|
||||
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Issue::index',
|
||||
array($prj->shortname));
|
||||
return new Pluf_HTTP_Response_Redirect($url);
|
||||
}
|
||||
|
||||
$otags = $prj->getTagIdsByStatus('open');
|
||||
$ctags = $prj->getTagIdsByStatus('closed');
|
||||
if (count($otags) == 0) $otags[] = 0;
|
||||
if (count($ctags) == 0) $ctags[] = 0;
|
||||
switch ($match[2]) {
|
||||
switch ($match[3]) {
|
||||
case 'submit':
|
||||
$title = sprintf(__('My Submitted %s Issues'), (string) $prj);
|
||||
$f_sql = new Pluf_SQL('project=%s AND submitter=%s AND status IN ('.implode(', ', $otags).')', array($prj->id, $request->user->id));
|
||||
$titleFormat = __('%s %s Submitted %s Issues');
|
||||
$f_sql = new Pluf_SQL('project=%s AND submitter=%s AND status IN ('.implode(', ', $otags).')', array($prj->id, $user->id));
|
||||
break;
|
||||
case 'submitclosed':
|
||||
$title = sprintf(__('My Closed Submitted %s Issues'), (string) $prj);
|
||||
$f_sql = new Pluf_SQL('project=%s AND submitter=%s AND status IN ('.implode(', ', $ctags).')', array($prj->id, $request->user->id));
|
||||
$titleFormat = __('%s %s Closed Submitted %s Issues');
|
||||
$f_sql = new Pluf_SQL('project=%s AND submitter=%s AND status IN ('.implode(', ', $ctags).')', array($prj->id, $user->id));
|
||||
break;
|
||||
case 'ownerclosed':
|
||||
$title = sprintf(__('My Closed Working %s Issues'), (string) $prj);
|
||||
$f_sql = new Pluf_SQL('project=%s AND owner=%s AND status IN ('.implode(', ', $ctags).')', array($prj->id, $request->user->id));
|
||||
$titleFormat = __('%s %s Closed Working %s Issues');
|
||||
$f_sql = new Pluf_SQL('project=%s AND owner=%s AND status IN ('.implode(', ', $ctags).')', array($prj->id, $user->id));
|
||||
break;
|
||||
default:
|
||||
$title = sprintf(__('My Working %s Issues'), (string) $prj);
|
||||
$f_sql = new Pluf_SQL('project=%s AND owner=%s AND status IN ('.implode(', ', $otags).')', array($prj->id, $request->user->id));
|
||||
$titleFormat = __('%s %s Working %s Issues');
|
||||
$f_sql = new Pluf_SQL('project=%s AND owner=%s AND status IN ('.implode(', ', $otags).')', array($prj->id, $user->id));
|
||||
break;
|
||||
}
|
||||
$title = sprintf($titleFormat,
|
||||
$user->first_name,
|
||||
$user->last_name,
|
||||
(string) $prj);
|
||||
|
||||
// Get stats about the issues
|
||||
$sql = new Pluf_SQL('project=%s AND submitter=%s AND status IN ('.implode(', ', $otags).')', array($prj->id, $request->user->id));
|
||||
$sql = new Pluf_SQL('project=%s AND submitter=%s AND status IN ('.implode(', ', $otags).')', array($prj->id, $user->id));
|
||||
$nb_submit = Pluf::factory('IDF_Issue')->getCount(array('filter'=>$sql->gen()));
|
||||
$sql = new Pluf_SQL('project=%s AND owner=%s AND status IN ('.implode(', ', $otags).')', array($prj->id, $request->user->id));
|
||||
$sql = new Pluf_SQL('project=%s AND owner=%s AND status IN ('.implode(', ', $otags).')', array($prj->id, $user->id));
|
||||
$nb_owner = Pluf::factory('IDF_Issue')->getCount(array('filter'=>$sql->gen()));
|
||||
// Closed issues
|
||||
$sql = new Pluf_SQL('project=%s AND submitter=%s AND status IN ('.implode(', ', $ctags).')', array($prj->id, $request->user->id));
|
||||
$sql = new Pluf_SQL('project=%s AND submitter=%s AND status IN ('.implode(', ', $ctags).')', array($prj->id, $user->id));
|
||||
$nb_submit_closed = Pluf::factory('IDF_Issue')->getCount(array('filter'=>$sql->gen()));
|
||||
$sql = new Pluf_SQL('project=%s AND owner=%s AND status IN ('.implode(', ', $ctags).')', array($prj->id, $request->user->id));
|
||||
$sql = new Pluf_SQL('project=%s AND owner=%s AND status IN ('.implode(', ', $ctags).')', array($prj->id, $user->id));
|
||||
$nb_owner_closed = Pluf::factory('IDF_Issue')->getCount(array('filter'=>$sql->gen()));
|
||||
|
||||
// Paginator to paginate the issues
|
||||
@@ -359,7 +374,7 @@ class IDF_Views_Issue
|
||||
'current_user' => $request->user);
|
||||
$pag->summary = __('This table shows the open issues.');
|
||||
$pag->forced_where = $f_sql;
|
||||
$pag->action = array('IDF_Views_Issue::myIssues', array($prj->shortname, $match[2]));
|
||||
$pag->action = array('IDF_Views_Issue::userIssues', array($prj->shortname, $match[2]));
|
||||
$pag->sort_order = array('modif_dtime', 'ASC'); // will be reverted
|
||||
$pag->sort_reverse_order = array('modif_dtime');
|
||||
$pag->sort_link_title = true;
|
||||
@@ -374,9 +389,10 @@ class IDF_Views_Issue
|
||||
$pag->items_per_page = 10;
|
||||
$pag->no_results_text = __('No issues were found.');
|
||||
$pag->setFromRequest($request);
|
||||
return Pluf_Shortcuts_RenderToResponse('idf/issues/my-issues.html',
|
||||
return Pluf_Shortcuts_RenderToResponse('idf/issues/userIssues.html',
|
||||
array('project' => $prj,
|
||||
'page_title' => $title,
|
||||
'login' => $user->login,
|
||||
'nb_submit' => $nb_submit,
|
||||
'nb_owner' => $nb_owner,
|
||||
'nb_submit_closed' => $nb_submit_closed,
|
||||
|
@@ -132,12 +132,6 @@ class IDF_Views_Source
|
||||
$request);
|
||||
}
|
||||
|
||||
public function repository($request, $match)
|
||||
{
|
||||
$scm = IDF_Scm::get($request->project);
|
||||
return $scm->repository($request, $match);
|
||||
}
|
||||
|
||||
public $treeBase_precond = array('IDF_Precondition::accessSource',
|
||||
'IDF_Views_Source_Precondition::scmAvailable',
|
||||
'IDF_Views_Source_Precondition::revisionValid');
|
||||
|
@@ -153,10 +153,10 @@ $ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/create/$#',
|
||||
'model' => 'IDF_Views_Issue',
|
||||
'method' => 'create');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/my/(\w+)/$#',
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/(.*)/(\w+)/$#',
|
||||
'base' => $base,
|
||||
'model' => 'IDF_Views_Issue',
|
||||
'method' => 'myIssues');
|
||||
'method' => 'userIssues');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/attachment/(\d+)/(.*)$#',
|
||||
'base' => $base,
|
||||
@@ -245,11 +245,6 @@ $ctl[] = array('regex' => '#^/p/([\-\w]+)/source/changesrev/$#',
|
||||
'model' => 'IDF_Views_Source_Svn',
|
||||
'method' => 'changelogRev');
|
||||
|
||||
$ctl[] = array('regex' => '#^/r/([\-\w]+)/(.*)$#',
|
||||
'base' => $base,
|
||||
'model' => 'IDF_Views_Source',
|
||||
'method' => 'repository');
|
||||
|
||||
// ---------- WIKI -----------------------------------------
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/doc/$#',
|
||||
|
@@ -4,7 +4,7 @@
|
||||
<div id="sub-tabs">
|
||||
<a {if $inSummaryIssues}class="active" {/if}href="{url 'IDF_Views_Issue::summary', array($project.shortname)}">{trans 'Summary'}</a>
|
||||
| <a {if $inOpenIssues}class="active" {/if}href="{url 'IDF_Views_Issue::index', array($project.shortname)}">{trans 'Open Issues'}</a>
|
||||
{if !$user.isAnonymous()} | <a {if $inCreate}class="active" {/if}href="{url 'IDF_Views_Issue::create', array($project.shortname)}">{trans 'New Issue'}</a> | <a {if $inMyIssues}class="active" {/if}href="{url 'IDF_Views_Issue::myIssues', array($project.shortname, 'submit')}">{trans 'My Issues'}</a>
|
||||
{if !$user.isAnonymous()} | <a {if $inCreate}class="active" {/if}href="{url 'IDF_Views_Issue::create', array($project.shortname)}">{trans 'New Issue'}</a> | <a {if $inMyIssues}class="active" {/if}href="{url 'IDF_Views_Issue::userIssues', array($project.shortname, $user.login, 'submit')}">{trans 'My Issues'}</a>
|
||||
| <a {if $inWatchList}class="active" {/if}href="{url 'IDF_Views_Issue::watchList', array($project.shortname, 'open')}">{trans 'My watch list'}</a>{/if} |
|
||||
<form class="star" action="{url 'IDF_Views_Issue::search', array($project.shortname)}" method="get">
|
||||
<input accesskey="4" type="text" value="{$q}" name="q" size="20" />
|
||||
|
@@ -71,7 +71,12 @@
|
||||
<tbody>
|
||||
{foreach $ownerStatistics as $key => $value}
|
||||
<tr>
|
||||
<td class="name">{$key}</td>
|
||||
<td class="name">
|
||||
{if !empty($value[2])}
|
||||
{aurl 'url', 'IDF_Views_Issue::userIssues', array($project.shortname, $value[2], 'owner')}
|
||||
<a href="{$url}">{$key}</a>
|
||||
{else}{$key}{/if}
|
||||
</td>
|
||||
<td class="count">{$value[0]}</td>
|
||||
<td class="graph">
|
||||
<table class='graph'>
|
||||
|
@@ -1,5 +1,5 @@
|
||||
{extends "idf/issues/base.html"}
|
||||
{block docclass}yui-t2{assign $inMyIssues = true}{/block}
|
||||
{block docclass}yui-t2{if $user.login == $login}{assign $inMyIssues = true}{/if}{/block}
|
||||
{block body}
|
||||
{$issues.render}
|
||||
{if !$user.isAnonymous()}
|
||||
@@ -8,10 +8,10 @@
|
||||
|
||||
{/block}
|
||||
{block context}
|
||||
{aurl 'owner_url', 'IDF_Views_Issue::myIssues', array($project.shortname, 'owner')}
|
||||
{aurl 'submit_url', 'IDF_Views_Issue::myIssues', array($project.shortname, 'submit')}
|
||||
{aurl 'owner_closed_url', 'IDF_Views_Issue::myIssues', array($project.shortname, 'ownerclosed')}
|
||||
{aurl 'submit_closed_url', 'IDF_Views_Issue::myIssues', array($project.shortname, 'submitclosed')}
|
||||
{aurl 'owner_url', 'IDF_Views_Issue::userIssues', array($project.shortname, $login, 'owner')}
|
||||
{aurl 'submit_url', 'IDF_Views_Issue::userIssues', array($project.shortname, $login, 'submit')}
|
||||
{aurl 'owner_closed_url', 'IDF_Views_Issue::userIssues', array($project.shortname, $login, 'ownerclosed')}
|
||||
{aurl 'submit_closed_url', 'IDF_Views_Issue::userIssues', array($project.shortname, $login, 'submitclosed')}
|
||||
<p><strong>{trans 'Submitted issues:'}</strong> <a href="{$submit_url}">{$nb_submit}</a>
|
||||
{if $nb_submit_closed}<br /><span class="helptext">{blocktrans $nb_submit_closed}See the <a href="{$submit_closed_url}">{$nb_submit_closed} closed</a>.{plural}See the <a href="{$submit_closed_url}">{$nb_submit_closed} closed</a>.{/blocktrans}</span>{/if}</p>
|
||||
{if $nb_owner > 0}
|
@@ -17,7 +17,7 @@
|
||||
{assign $submitter_data = $c.get_submitter_data()}
|
||||
<div class="issue-comment{if $i == 0} issue-comment-first{/if}{if $i == ($nc-1)} issue-comment-last{/if}" id="ic{$c.id}">
|
||||
{if $submitter_data.avatar != ''}
|
||||
<img style="float:right; position: relative; max-height: 60px; max-width: 60px;" src="{media}/upload/avatars/{$submitter_data.avatar}" alt=" " />
|
||||
<img style="float:right; position: relative; max-height: 60px; max-width: 60px;" src="{upload}/avatars/{$submitter_data.avatar}" alt=" " />
|
||||
{else}
|
||||
<img style="float:right; position: relative; max-height: 60px; max-width: 60px;" src="http://www.gravatar.com/avatar/{$submitter.email|md5}.jpg?s=60&d={media}/idf/img/spacer.gif" alt=" " />
|
||||
{/if}
|
||||
|
@@ -10,8 +10,8 @@
|
||||
{if $hasWikiAccess}{hotkey 'Shift+o', 'IDF_Views_Wiki::index', array($project.shortname)}{/if}
|
||||
{if $hasSourceAccess}{hotkey 'Shift+s', 'IDF_Views_Source::treeBase', array($project.shortname, $project.getScmRoot())}{/if}
|
||||
{if $hasIssuesAccess and !$user.isAnonymous()}
|
||||
{hotkey 'Shift+m', 'IDF_Views_Issue::myIssues', array($project.shortname, 'submit')}
|
||||
{hotkey 'Shift+w', 'IDF_Views_Issue::myIssues', array($project.shortname, 'owner')}
|
||||
{hotkey 'Shift+m', 'IDF_Views_Issue::userIssues', array($project.shortname, $user.login, 'submit')}
|
||||
{hotkey 'Shift+w', 'IDF_Views_Issue::userIssues', array($project.shortname, $user.login, 'owner')}
|
||||
{/if}{/if} //-->
|
||||
</script>
|
||||
|
||||
|
@@ -4,7 +4,7 @@
|
||||
<div id="sub-tabs">
|
||||
<a {if $inOpenReviews}class="active" {/if}href="{url 'IDF_Views_Review::index', array($project.shortname)}">{trans 'Open Reviews'}</a> {*
|
||||
|
||||
{if !$user.isAnonymous()} | <a {if $inCreate}class="active" {/if}href="{url 'IDF_Views_Issue::create', array($project.shortname)}">{trans 'New Issue'}</a> | <a {if $inMyIssues}class="active" {/if}href="{url 'IDF_Views_Issue::myIssues', array($project.shortname, 'submit')}">{trans 'My Issues'}</a>{/if} |
|
||||
{if !$user.isAnonymous()} | <a {if $inCreate}class="active" {/if}href="{url 'IDF_Views_Issue::create', array($project.shortname)}">{trans 'New Issue'}</a> | <a {if $inMyIssues}class="active" {/if}href="{url 'IDF_Views_Issue::userIssues', array($project.shortname, $user.login, 'submit')}">{trans 'My Issues'}</a>{/if} |
|
||||
<form class="star" action="{url 'IDF_Views_Issue::search', array($project.shortname)}" method="get">
|
||||
<input accesskey="4" type="text" value="{$q}" name="q" size="20" />
|
||||
<input type="submit" name="s" value="{trans 'Search'}" />
|
||||
|
@@ -109,7 +109,7 @@ to propose more contributions</strong>.
|
||||
{foreach $comments as $c}{ashowuser 'submitter', $c.get_submitter(), $request}{assign $submitter = $c.get_submitter()}{assign $submitter_data = $c.get_submitter_data()}
|
||||
<div class="issue-comment{if $i == 1} issue-comment-first{/if}{if $i == ($nc)} issue-comment-last{/if}" id="ic{$c.id}">
|
||||
{if $submitter_data.avatar != ''}
|
||||
<img style="float:right; position: relative; max-height: 60px; max-width: 60px;" src="{media}/upload/avatars/{$submitter_data.avatar}" alt=" " />
|
||||
<img style="float:right; position: relative; max-height: 60px; max-width: 60px;" src="{upload}/avatars/{$submitter_data.avatar}" alt=" " />
|
||||
{else}
|
||||
<img style="float:right; position: relative;" src="http://www.gravatar.com/avatar/{$submitter.email|md5}.jpg?s=60&d={media}/idf/img/spacer.gif" alt=" " />
|
||||
{/if}
|
||||
|
@@ -3,7 +3,7 @@
|
||||
<table class="form" summary="">
|
||||
<tr>
|
||||
<th style="text-align: right">{if $user_data.avatar != ''}
|
||||
<img style="max-height: 60px; max-width: 60px;" src="{media}/upload/avatars/{$user_data.avatar}" alt=" " />
|
||||
<img style="max-height: 60px; max-width: 60px;" src="{upload}/avatars/{$user_data.avatar}" alt=" " />
|
||||
{else}
|
||||
<img src="http://www.gravatar.com/avatar/{$member.email|md5}.jpg?s=60&d={media}/idf/img/spacer.gif" alt=" " />
|
||||
{/if}
|
||||
|
Reference in New Issue
Block a user