Add an option to configure an external URL per project, e.g. to allow the

linking of the home page of the project.

This feature was kindly sponsored by Scilab.
develop
Thomas Keller 2011-09-25 01:27:36 +02:00
parent 4ae0019e0f
commit 7f610fd2f3
15 changed files with 427 additions and 35 deletions

View File

@ -0,0 +1,284 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="190.51302"
height="182.16527"
id="svg2"
version="1.1"
inkscape:version="0.47 r22583"
sodipodi:docname="external_link.svg"
inkscape:export-filename="/Users/tommyd/Entwicklung/Open Source/indefero/www/media/idf/img/external_link.png"
inkscape:export-xdpi="7.4108529"
inkscape:export-ydpi="7.4108529"
enable-background="new">
<defs
id="defs4">
<inkscape:path-effect
effect="skeletal"
id="path-effect4079"
is_visible="true"
pattern="M 0,5 10,10 10,0 z"
copytype="single_stretched"
prop_scale="1"
scale_y_rel="false"
spacing="0"
normal_offset="0"
tang_offset="0"
prop_units="false"
vertical_pattern="false"
fuse_tolerance="0" />
<inkscape:path-effect
effect="skeletal"
id="path-effect4071"
is_visible="true"
pattern="M 0,5 10,10 10,0 z"
copytype="single_stretched"
prop_scale="1"
scale_y_rel="false"
spacing="0"
normal_offset="0"
tang_offset="0"
prop_units="false"
vertical_pattern="false"
fuse_tolerance="0" />
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lend"
style="overflow:visible">
<path
id="path3627"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(-0.8,0,0,-0.8,-10,0)" />
</marker>
<inkscape:path-effect
effect="skeletal"
id="path-effect3619"
is_visible="true"
pattern="M 0,5 10,10 10,0 z"
copytype="single_stretched"
prop_scale="1"
scale_y_rel="false"
spacing="0"
normal_offset="0"
tang_offset="0"
prop_units="false"
vertical_pattern="false"
fuse_tolerance="0" />
<inkscape:path-effect
effect="skeletal"
id="path-effect3615"
is_visible="true"
pattern="M 0,5 10,10 10,0 z"
copytype="single_stretched"
prop_scale="1"
scale_y_rel="false"
spacing="0"
normal_offset="0"
tang_offset="0"
prop_units="false"
vertical_pattern="false"
fuse_tolerance="0" />
<inkscape:path-effect
effect="skeletal"
id="path-effect3611"
is_visible="true"
pattern="M 0,5 10,10 10,0 z"
copytype="single_stretched"
prop_scale="1"
scale_y_rel="false"
spacing="0"
normal_offset="0"
tang_offset="0"
prop_units="false"
vertical_pattern="false"
fuse_tolerance="0" />
<inkscape:path-effect
effect="skeletal"
id="path-effect3607"
is_visible="true"
pattern="M 0,5 10,10 10,0 z"
copytype="single_stretched"
prop_scale="1"
scale_y_rel="false"
spacing="0"
normal_offset="0"
tang_offset="0"
prop_units="false"
vertical_pattern="false"
fuse_tolerance="0" />
<inkscape:path-effect
effect="skeletal"
id="path-effect3603"
is_visible="true"
pattern="M 0,5 10,10 10,0 z"
copytype="single_stretched"
prop_scale="1"
scale_y_rel="false"
spacing="0"
normal_offset="0"
tang_offset="0"
prop_units="false"
vertical_pattern="false"
fuse_tolerance="0" />
<inkscape:path-effect
effect="skeletal"
id="path-effect3599"
is_visible="true"
pattern="M 0,5 10,10 10,0 z"
copytype="single_stretched"
prop_scale="1"
scale_y_rel="false"
spacing="0"
normal_offset="0"
tang_offset="0"
prop_units="false"
vertical_pattern="false"
fuse_tolerance="0" />
<inkscape:path-effect
effect="skeletal"
id="path-effect3595"
is_visible="true"
pattern="M 0,5 10,10 10,0 z"
copytype="single_stretched"
prop_scale="1"
scale_y_rel="false"
spacing="0"
normal_offset="0"
tang_offset="0"
prop_units="false"
vertical_pattern="false"
fuse_tolerance="0" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective10" />
<inkscape:perspective
id="perspective4900"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<filter
inkscape:collect="always"
id="filter4921"
x="-0.12982728"
width="1.2596545"
y="-0.092135489"
height="1.184271"
color-interpolation-filters="sRGB">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="6.8004762"
id="feGaussianBlur4923" />
</filter>
<inkscape:perspective
id="perspective4933"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<filter
color-interpolation-filters="sRGB"
inkscape:collect="always"
id="filter4921-3"
x="-0.12982728"
width="1.2596545"
y="-0.092135489"
height="1.184271">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="6.8004762"
id="feGaussianBlur4923-8" />
</filter>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="1.78"
inkscape:cx="138.94497"
inkscape:cy="111.09667"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1389"
inkscape:window-height="803"
inkscape:window-x="47"
inkscape:window-y="0"
inkscape:window-maximized="0" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Ebene"
transform="translate(16.297732,13.906157)"
style="display:inline"
sodipodi:insensitive="true">
<g
id="g2818-7"
style="fill:#e6e6e6;fill-opacity:1;stroke:#a0a0a0;stroke-width:2.26057386;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;filter:url(#filter4921-3)"
transform="matrix(0.97722285,0,0,-0.85847241,-166.837,487.59193)">
<rect
ry="9.2957697"
rx="8.07693"
y="389.50504"
x="171.42857"
height="177.14285"
width="125.71429"
id="rect2816-9"
style="opacity:0.79710143;fill:#000000;fill-opacity:1;stroke:#a0a0a0;stroke-width:2.26057386;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
</g>
</g>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-155.26623,-395.13431)"
style="display:inline;">
<rect
style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:#a0a0a0;stroke-width:2.41343927;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect4985"
width="129.92365"
height="152.95734"
x="168.88869"
y="407.28156"
rx="9.9356585"
ry="11.003931" />
<path
style="fill:#00000f;fill-opacity:0.94117647;stroke:none;stroke-width:2.17028474999999998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 205.32036,460.1042 67.83031,0 0,-32.45771 71.54343,60.58773 -72.50161,61.39918 0,-33.26916 -66.75258,0 0,-56.26004"
id="path4081"
sodipodi:nodetypes="cccccccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.6 KiB

View File

@ -72,6 +72,13 @@ class IDF_Form_Admin_ProjectCreate extends Pluf_Form
'widget_attrs' => array('size' => '35'), 'widget_attrs' => array('size' => '35'),
)); ));
$this->fields['external_project_url'] = new Pluf_Form_Field_Varchar(
array('required' => false,
'label' => __('External URL'),
'widget_attrs' => array('size' => '35'),
'initial' => '',
));
$this->fields['scm'] = new Pluf_Form_Field_Varchar( $this->fields['scm'] = new Pluf_Form_Field_Varchar(
array('required' => true, array('required' => true,
'label' => __('Repository type'), 'label' => __('Repository type'),
@ -235,6 +242,11 @@ class IDF_Form_Admin_ProjectCreate extends Pluf_Form
return $shortname; return $shortname;
} }
public function clean_external_project_url()
{
return IDF_Form_ProjectConf::checkWebURL($this->cleaned_data['external_project_url']);
}
public function clean() public function clean()
{ {
if ($this->cleaned_data['scm'] != 'svn') { if ($this->cleaned_data['scm'] != 'svn') {
@ -298,7 +310,7 @@ class IDF_Form_Admin_ProjectCreate extends Pluf_Form
$conf = new IDF_Conf(); $conf = new IDF_Conf();
$conf->setProject($project); $conf->setProject($project);
$keys = array('scm', 'svn_remote_url', 'svn_username', $keys = array('scm', 'svn_remote_url', 'svn_username',
'svn_password', 'mtn_master_branch'); 'svn_password', 'mtn_master_branch', 'external_project_url');
foreach ($keys as $key) { foreach ($keys as $key) {
$this->cleaned_data[$key] = (!empty($this->cleaned_data[$key])) ? $this->cleaned_data[$key] = (!empty($this->cleaned_data[$key])) ?
$this->cleaned_data[$key] : ''; $this->cleaned_data[$key] : '';

View File

@ -53,6 +53,13 @@ class IDF_Form_Admin_ProjectUpdate extends Pluf_Form
'widget_attrs' => array('size' => '35'), 'widget_attrs' => array('size' => '35'),
)); ));
$this->fields['external_project_url'] = new Pluf_Form_Field_Varchar(
array('required' => false,
'label' => __('External URL'),
'widget_attrs' => array('size' => '35'),
'initial' => $conf->getVal('external_project_url'),
));
if ($this->project->getConf()->getVal('scm') == 'mtn') { if ($this->project->getConf()->getVal('scm') == 'mtn') {
$this->fields['mtn_master_branch'] = new Pluf_Form_Field_Varchar( $this->fields['mtn_master_branch'] = new Pluf_Form_Field_Varchar(
array('required' => false, array('required' => false,
@ -115,6 +122,11 @@ class IDF_Form_Admin_ProjectUpdate extends Pluf_Form
return IDF_Form_MembersConf::checkBadLogins($this->cleaned_data['members']); return IDF_Form_MembersConf::checkBadLogins($this->cleaned_data['members']);
} }
public function clean_external_project_url()
{
return IDF_Form_ProjectConf::checkWebURL($this->cleaned_data['external_project_url']);
}
public function save($commit=true) public function save($commit=true)
{ {
if (!$this->isValid()) { if (!$this->isValid()) {
@ -127,10 +139,16 @@ class IDF_Form_Admin_ProjectUpdate extends Pluf_Form
$this->project->shortdesc = $this->cleaned_data['shortdesc']; $this->project->shortdesc = $this->cleaned_data['shortdesc'];
$this->project->update(); $this->project->update();
$keys = array('mtn_master_branch'); $conf = $this->project->getConf();
$keys = array('mtn_master_branch', 'external_project_url');
foreach ($keys as $key) { foreach ($keys as $key) {
if (!empty($this->cleaned_data[$key])) { if (array_key_exists($key, $this->cleaned_data)) {
$this->project->getConf()->setVal($key, $this->cleaned_data[$key]); if (!empty($this->cleaned_data[$key])) {
$conf->setVal($key, $this->cleaned_data[$key]);
}
else {
$conf->delVal($key);
}
} }
} }
} }

View File

@ -32,6 +32,7 @@ class IDF_Form_ProjectConf extends Pluf_Form
public function initFields($extra=array()) public function initFields($extra=array())
{ {
$this->project = $extra['project']; $this->project = $extra['project'];
$conf = $this->project->getConf();
// Basic part // Basic part
$this->fields['name'] = new Pluf_Form_Field_Varchar(array('required' => true, $this->fields['name'] = new Pluf_Form_Field_Varchar(array('required' => true,
@ -51,6 +52,11 @@ class IDF_Form_ProjectConf extends Pluf_Form
), ),
'widget' => 'Pluf_Form_Widget_TextareaInput', 'widget' => 'Pluf_Form_Widget_TextareaInput',
)); ));
$this->fields['external_project_url'] = new Pluf_Form_Field_Varchar(array('required' => false,
'label' => __('External URL'),
'widget_attrs' => array('size' => '68'),
'initial' => $conf->getVal('external_project_url'),
));
// Logo part // Logo part
$upload_path = Pluf::f('upload_path', false); $upload_path = Pluf::f('upload_path', false);
@ -118,20 +124,48 @@ class IDF_Form_ProjectConf extends Pluf_Form
return $this->cleaned_data['logo']; return $this->cleaned_data['logo'];
} }
public function clean_external_project_url()
{
return self::checkWebURL($this->cleaned_data['external_project_url']);
}
public static function checkWebURL($url)
{
$url = trim($url);
if (empty($url)) {
return '';
}
$parsed = parse_url($url);
if ($parsed === false || !array_key_exists('scheme', $parsed) ||
($parsed['scheme'] != 'http' && $parsed['scheme'] != 'https')) {
throw new Pluf_Form_Invalid(__('The entered URL is invalid. Only http and https URLs are allowed.'));
}
return $url;
}
public function save($commit=true) public function save($commit=true)
{ {
$conf = $this->project->getConf();
// Basic part // Basic part
$this->project->name = $this->cleaned_data['name']; $this->project->name = $this->cleaned_data['name'];
$this->project->shortdesc = $this->cleaned_data['shortdesc']; $this->project->shortdesc = $this->cleaned_data['shortdesc'];
$this->project->description = $this->cleaned_data['description']; $this->project->description = $this->cleaned_data['description'];
$this->project->update(); $this->project->update();
// Logo part $conf = $this->project->getConf();
if ($this->cleaned_data['logo'] !== "") { $keys = array('logo', 'external_project_url');
$conf->setVal('logo', $this->cleaned_data['logo']); foreach ($keys as $key) {
if (array_key_exists($key, $this->cleaned_data)) {
if (!empty($this->cleaned_data[$key])) {
$conf->setVal($key, $this->cleaned_data[$key]);
}
else {
$conf->delVal($key);
}
}
} }
if ($this->cleaned_data['logo_remove'] === true) { if ($this->cleaned_data['logo_remove'] === true) {
@unlink(Pluf::f('upload_path') . '/' . $this->project->shortname . $conf->getVal('logo')); @unlink(Pluf::f('upload_path') . '/' . $this->project->shortname . $conf->getVal('logo'));
$conf->delVal('logo'); $conf->delVal('logo');

View File

@ -132,7 +132,7 @@ class IDF_Project extends Pluf_Model
} }
return $projects[0]; return $projects[0];
} }
/** /**
* Returns the number of open/closed issues. * Returns the number of open/closed issues.
* *
@ -167,7 +167,7 @@ GROUP BY uid";
$key = ($v['id'] === '-1') ? null : $v['id']; $key = ($v['id'] === '-1') ? null : $v['id'];
$ownerStatistics[$key] = (int)$v['nb']; $ownerStatistics[$key] = (int)$v['nb'];
} }
arsort($ownerStatistics); arsort($ownerStatistics);
return $ownerStatistics; return $ownerStatistics;
@ -552,6 +552,22 @@ GROUP BY uid";
return $this->_pconf; return $this->_pconf;
} }
/**
* Magic overload that falls back to the values of the internal configuration
* if no getter / caller matched
*
* @param string $key
*/
public function __get($key)
{
try {
return parent::__get($key);
}
catch (Exception $e) {
return $this->getConf()->getVal($key);
}
}
/** /**
* Get simple statistics about the project. * Get simple statistics about the project.
* *

View File

@ -40,10 +40,10 @@ class IDF_Views
public function index($request, $match, $api=false) public function index($request, $match, $api=false)
{ {
$projects = self::getProjects($request->user); $projects = self::getProjects($request->user);
$stats = self::getProjectsStatistics ($projects); $stats = self::getProjectsStatistics($projects);
if ($api == true) return $projects; if ($api == true) return $projects;
return Pluf_Shortcuts_RenderToResponse('idf/index.html', return Pluf_Shortcuts_RenderToResponse('idf/index.html',
array('page_title' => __('Projects'), array('page_title' => __('Projects'),
'projects' => $projects, 'projects' => $projects,
'stats' => new Pluf_Template_ContextVars($stats)), 'stats' => new Pluf_Template_ContextVars($stats)),
@ -55,7 +55,7 @@ class IDF_Views
*/ */
public function login($request, $match) public function login($request, $match)
{ {
if (isset($request->POST['action']) if (isset($request->POST['action'])
and $request->POST['action'] == 'new-user') { and $request->POST['action'] == 'new-user') {
$login = (isset($request->POST['login'])) ? $request->POST['login'] : ''; $login = (isset($request->POST['login'])) ? $request->POST['login'] : '';
$url = Pluf_HTTP_URL_urlForView('IDF_Views::register', array(), $url = Pluf_HTTP_URL_urlForView('IDF_Views::register', array(),
@ -91,7 +91,7 @@ class IDF_Views
$params = array('request'=>$request); $params = array('request'=>$request);
if ($request->method == 'POST') { if ($request->method == 'POST') {
$form = new IDF_Form_Register(array_merge( $form = new IDF_Form_Register(array_merge(
(array)$request->POST, (array)$request->POST,
(array)$request->FILES (array)$request->FILES
), $params); ), $params);
if ($form->isValid()) { if ($form->isValid()) {
@ -108,7 +108,7 @@ class IDF_Views
$context = new Pluf_Template_Context(array()); $context = new Pluf_Template_Context(array());
$tmpl = new Pluf_Template('idf/terms.html'); $tmpl = new Pluf_Template('idf/terms.html');
$terms = Pluf_Template::markSafe($tmpl->render($context)); $terms = Pluf_Template::markSafe($tmpl->render($context));
return Pluf_Shortcuts_RenderToResponse('idf/register/index.html', return Pluf_Shortcuts_RenderToResponse('idf/register/index.html',
array('page_title' => $title, array('page_title' => $title,
'form' => $form, 'form' => $form,
'terms' => $terms), 'terms' => $terms),
@ -133,7 +133,7 @@ class IDF_Views
} else { } else {
$form = new IDF_Form_RegisterInputKey(); $form = new IDF_Form_RegisterInputKey();
} }
return Pluf_Shortcuts_RenderToResponse('idf/register/inputkey.html', return Pluf_Shortcuts_RenderToResponse('idf/register/inputkey.html',
array('page_title' => $title, array('page_title' => $title,
'form' => $form), 'form' => $form),
$request); $request);
@ -168,7 +168,7 @@ class IDF_Views
$request->session->clear(); $request->session->clear();
$request->session->setData('login_time', gmdate('Y-m-d H:i:s')); $request->session->setData('login_time', gmdate('Y-m-d H:i:s'));
$user->last_login = gmdate('Y-m-d H:i:s'); $user->last_login = gmdate('Y-m-d H:i:s');
$user->update(); $user->update();
$request->user->setMessage(__('Welcome! You can now participate in the life of your project of choice.')); $request->user->setMessage(__('Welcome! You can now participate in the life of your project of choice.'));
$url = Pluf_HTTP_URL_urlForView('IDF_Views::index'); $url = Pluf_HTTP_URL_urlForView('IDF_Views::index');
return new Pluf_HTTP_Response_Redirect($url); return new Pluf_HTTP_Response_Redirect($url);
@ -176,7 +176,7 @@ class IDF_Views
} else { } else {
$form = new IDF_Form_RegisterConfirmation(null, $extra); $form = new IDF_Form_RegisterConfirmation(null, $extra);
} }
return Pluf_Shortcuts_RenderToResponse('idf/register/confirmation.html', return Pluf_Shortcuts_RenderToResponse('idf/register/confirmation.html',
array('page_title' => $title, array('page_title' => $title,
'new_user' => $user, 'new_user' => $user,
'form' => $form), 'form' => $form),
@ -213,7 +213,7 @@ class IDF_Views
/** /**
* If the key is valid, provide a nice form to reset the password * If the key is valid, provide a nice form to reset the password
* and automatically login the user. * and automatically login the user.
* *
* This is also firing the password change event for the plugins. * This is also firing the password change event for the plugins.
*/ */
@ -238,7 +238,7 @@ class IDF_Views
$request->session->clear(); $request->session->clear();
$request->session->setData('login_time', gmdate('Y-m-d H:i:s')); $request->session->setData('login_time', gmdate('Y-m-d H:i:s'));
$user->last_login = gmdate('Y-m-d H:i:s'); $user->last_login = gmdate('Y-m-d H:i:s');
$user->update(); $user->update();
$request->user->setMessage(__('Welcome back! Next time, you can use your broswer options to remember the password.')); $request->user->setMessage(__('Welcome back! Next time, you can use your broswer options to remember the password.'));
$url = Pluf_HTTP_URL_urlForView('IDF_Views::index'); $url = Pluf_HTTP_URL_urlForView('IDF_Views::index');
return new Pluf_HTTP_Response_Redirect($url); return new Pluf_HTTP_Response_Redirect($url);
@ -246,12 +246,12 @@ class IDF_Views
} else { } else {
$form = new IDF_Form_PasswordReset(null, $extra); $form = new IDF_Form_PasswordReset(null, $extra);
} }
return Pluf_Shortcuts_RenderToResponse('idf/user/passrecovery.html', return Pluf_Shortcuts_RenderToResponse('idf/user/passrecovery.html',
array('page_title' => $title, array('page_title' => $title,
'new_user' => $user, 'new_user' => $user,
'form' => $form), 'form' => $form),
$request); $request);
} }
/** /**
@ -270,7 +270,7 @@ class IDF_Views
} else { } else {
$form = new IDF_Form_PasswordInputKey(); $form = new IDF_Form_PasswordInputKey();
} }
return Pluf_Shortcuts_RenderToResponse('idf/user/passrecovery-inputkey.html', return Pluf_Shortcuts_RenderToResponse('idf/user/passrecovery-inputkey.html',
array('page_title' => $title, array('page_title' => $title,
'form' => $form), 'form' => $form),
$request); $request);
@ -283,7 +283,7 @@ class IDF_Views
{ {
$title = __('Here to Help You!'); $title = __('Here to Help You!');
$projects = self::getProjects($request->user); $projects = self::getProjects($request->user);
return Pluf_Shortcuts_RenderToResponse('idf/faq.html', return Pluf_Shortcuts_RenderToResponse('idf/faq.html',
array( array(
'page_title' => $title, 'page_title' => $title,
'projects' => $projects, 'projects' => $projects,
@ -299,7 +299,7 @@ class IDF_Views
{ {
$title = __('InDefero API (Application Programming Interface)'); $title = __('InDefero API (Application Programming Interface)');
$projects = self::getProjects($request->user); $projects = self::getProjects($request->user);
return Pluf_Shortcuts_RenderToResponse('idf/faq-api.html', return Pluf_Shortcuts_RenderToResponse('idf/faq-api.html',
array( array(
'page_title' => $title, 'page_title' => $title,
'projects' => $projects, 'projects' => $projects,
@ -335,7 +335,7 @@ class IDF_Views
); );
$sql = new Pluf_SQL("model_class='IDF_Project' AND owner_class='Pluf_User' AND owner_id=%s AND negative=".$false, $user->id); $sql = new Pluf_SQL("model_class='IDF_Project' AND owner_class='Pluf_User' AND owner_id=%s AND negative=".$false, $user->id);
$rows = Pluf::factory('Pluf_RowPermission')->getList(array('filter' => $sql->gen())); $rows = Pluf::factory('Pluf_RowPermission')->getList(array('filter' => $sql->gen()));
$sql = sprintf('%s=%s', $db->qn('private'), $false); $sql = sprintf('%s=%s', $db->qn('private'), $false);
if ($rows->count() > 0) { if ($rows->count() > 0) {
$ids = array(); $ids = array();
@ -347,7 +347,7 @@ class IDF_Views
return Pluf::factory('IDF_Project')->getList(array('filter' => $sql, return Pluf::factory('IDF_Project')->getList(array('filter' => $sql,
'order' => 'name ASC')); 'order' => 'name ASC'));
} }
/** /**
* Returns statistics on a list of projects. * Returns statistics on a list of projects.
* *
@ -362,7 +362,7 @@ class IDF_Views
'issues' => 0, 'issues' => 0,
'docpages' => 0, 'docpages' => 0,
'commits' => 0); 'commits' => 0);
// Count for each projects // Count for each projects
foreach ($projects as $p) { foreach ($projects as $p) {
$pstats = $p->getStats (); $pstats = $p->getStats ();
@ -372,7 +372,7 @@ class IDF_Views
$forgestats['docpages'] += $pstats['docpages']; $forgestats['docpages'] += $pstats['docpages'];
$forgestats['commits'] += $pstats['commits']; $forgestats['commits'] += $pstats['commits'];
} }
// Count projects // Count projects
$forgestats['projects'] = count($projects); $forgestats['projects'] = count($projects);
@ -380,7 +380,7 @@ class IDF_Views
$sql = new Pluf_SQL('first_name != %s', array('---')); $sql = new Pluf_SQL('first_name != %s', array('---'));
$forgestats['members'] = Pluf::factory('Pluf_User') $forgestats['members'] = Pluf::factory('Pluf_User')
->getCount(array('filter' => $sql->gen())); ->getCount(array('filter' => $sql->gen()));
return $forgestats; return $forgestats;
} }
} }

View File

@ -305,7 +305,7 @@ class IDF_Views_Project
return new Pluf_HTTP_Response_Redirect($url); return new Pluf_HTTP_Response_Redirect($url);
} }
} else { } else {
$form = new IDF_Form_ProjectConf($prj->getData(), $extra); $form = new IDF_Form_ProjectConf(null, $extra);
} }
$logo = $prj->getConf()->getVal('logo'); $logo = $prj->getConf()->getVal('logo');

View File

@ -25,6 +25,12 @@
</td> </td>
</tr> </tr>
<tr> <tr>
<th><strong>{$form.f.external_project_url.labelTag}:</strong></th>
<td>{if $form.f.external_project_url.errors}{$form.f.external_project_url.fieldErrors}{/if}
{$form.f.external_project_url|unsafe}
</td>
</tr>
<tr>
<th><strong>{$form.f.description.labelTag}:</strong></th> <th><strong>{$form.f.description.labelTag}:</strong></th>
<td>{if $form.f.description.errors}{$form.f.description.fieldErrors}{/if} <td>{if $form.f.description.errors}{$form.f.description.fieldErrors}{/if}
{$form.f.description|unsafe} {$form.f.description|unsafe}

View File

@ -37,7 +37,7 @@
<body> <body>
<div id="{block docid}doc3{/block}"> <div id="{block docid}doc3{/block}">
<div id="hd"> <div id="hd">
{if $project}<h1 class="project-title">{$project}<img class="logo" src="{url 'IDF_Views_Project::logo', array($project.shortname)}" alt="{trans 'Project logo'}" />{if $project.private}<img class="lock" src="{media '/idf/img/lock.png'}" alt="{trans 'Private project'}" />{/if}{$p}</h1>{/if} {if $project}<h1 class="project-title">{$project}<img class="logo" src="{url 'IDF_Views_Project::logo', array($project.shortname)}" alt="{trans 'Project logo'}" />{if $project.private}<img class="lock" src="{media '/idf/img/lock.png'}" alt="{trans 'Private project'}" />{/if}{$p}{assign $url = $project.external_project_url}{if $url != ''}<a href="{$url}" target="_blank" class="external-link" title="{trans 'External link to project'}" />&nbsp;</a>{/if}</h1>{/if}
{include 'idf/main-menu.html'} {include 'idf/main-menu.html'}
<div id="header"> <div id="header">
<div id="main-tabs"> <div id="main-tabs">

View File

@ -37,7 +37,7 @@
<body> <body>
<div id="{block docid}doc3{/block}" class="{block docclass}yui-t3{/block}"> <div id="{block docid}doc3{/block}" class="{block docclass}yui-t3{/block}">
<div id="hd"> <div id="hd">
{if $project}<h1 class="project-title">{$project}<img class="logo" src="{url 'IDF_Views_Project::logo', array($project.shortname)}" alt="{trans 'Project logo'}" />{if $project.private}<img class="lock" src="{media '/idf/img/lock.png'}" alt="{trans 'Private project'}" />{/if}{$p}</h1>{/if} {if $project}<h1 class="project-title">{$project}<img class="logo" src="{url 'IDF_Views_Project::logo', array($project.shortname)}" alt="{trans 'Project logo'}" />{if $project.private}<img class="lock" src="{media '/idf/img/lock.png'}" alt="{trans 'Private project'}" />{/if}{$p}{assign $url = $project.external_project_url}{if $url != ''}<a href="{$url}" target="_blank" class="external-link" title="{trans 'External link to project'}" />&nbsp;</a>{/if}</h1>{/if}
{include 'idf/main-menu.html'} {include 'idf/main-menu.html'}
<div id="header"> <div id="header">
<div id="main-tabs"> <div id="main-tabs">

View File

@ -37,6 +37,12 @@
</td> </td>
</tr> </tr>
<tr> <tr>
<th><strong>{$form.f.external_project_url.labelTag}:</strong></th>
<td>{if $form.f.external_project_url.errors}{$form.f.external_project_url.fieldErrors}{/if}
{$form.f.external_project_url|unsafe}
</td>
</tr>
<tr>
<th><strong>{$form.f.scm.labelTag}:</strong></th> <th><strong>{$form.f.scm.labelTag}:</strong></th>
<td>{if $form.f.scm.errors}{$form.f.scm.fieldErrors}{/if} <td>{if $form.f.scm.errors}{$form.f.scm.fieldErrors}{/if}
{$form.f.scm|unsafe} {$form.f.scm|unsafe}

View File

@ -25,6 +25,12 @@
<span class="helptext">{$form.f.shortdesc.help_text}</span> <span class="helptext">{$form.f.shortdesc.help_text}</span>
</td> </td>
</tr> </tr>
<tr>
<th><strong>{$form.f.external_project_url.labelTag}:</strong></th>
<td>{if $form.f.external_project_url.errors}{$form.f.external_project_url.fieldErrors}{/if}
{$form.f.external_project_url|unsafe}
</td>
</tr>
{if $project.getConf().getVal('scm') == 'mtn'} {if $project.getConf().getVal('scm') == 'mtn'}
<tr class="mtn-form"> <tr class="mtn-form">
<th><strong>{$form.f.mtn_master_branch.labelTag}:</strong></th> <th><strong>{$form.f.mtn_master_branch.labelTag}:</strong></th>

View File

@ -25,6 +25,10 @@
<div class="p-list-prj"> <div class="p-list-prj">
<p> <p>
<a href="{url 'IDF_Views_Project::home', array($p.shortname)}"><strong>{$p}</strong></a> <a href="{url 'IDF_Views_Project::home', array($p.shortname)}"><strong>{$p}</strong></a>
{assign $url = $p.external_project_url}
{if $url != ''}
<a href="{$url}" target="_blank" class="external-link" title="{trans 'External link to project'}" />&nbsp;</a>
{/if}
{if $p.private} - {trans 'Private project'}{/if} {if $p.private} - {trans 'Private project'}{/if}
</p> </p>
<p>{$p.shortdesc}</p> <p>{$p.shortdesc}</p>

View File

@ -1105,6 +1105,12 @@ div.p-list-private {
position: relative; position: relative;
} }
a.external-link {
background: url(../img/external_link.png) no-repeat right center;
padding-right: 15px;
text-decoration: none;
}
/* /*
* Issue summary * Issue summary
*/ */

Binary file not shown.

After

Width:  |  Height:  |  Size: 509 B