Merge branch 'develop' into feature.issue-due-date

This commit is contained in:
Simon Holywell 2012-05-02 12:21:44 +01:00
commit c0035061b0
14 changed files with 282 additions and 217 deletions

View File

@ -22,6 +22,7 @@ Much appreciated contributors (in alphabetical order):
Janez Troha <http://www.dz0ny.info> - Slovenian translation Janez Troha <http://www.dz0ny.info> - Slovenian translation
Jean-Philippe Fleury <jpfleury> Jean-Philippe Fleury <jpfleury>
Jerry <lxb429@gmail.com> - Chinese translation Jerry <lxb429@gmail.com> - Chinese translation
Jonathan Aillet - French translation
Julien Issler <julien@issler.net> Julien Issler <julien@issler.net>
Litew <litew9@gmail.com> - Russian translation Litew <litew9@gmail.com> - Russian translation
Ludovic Bellière <xrogaan> Ludovic Bellière <xrogaan>

View File

@ -1,9 +1,23 @@
# InDefero 1.3 - xxx xxx xx xx:xx 2011 UTC # InDefero 1.3.1 - xxx xxx xx xx:xx 2012 UTC
The development of this version of Indefero has been sponsored ## Bugfixes
by the friendly folks from Scilab <http://www.scilab.org/>!
ATTENTION: You need Pluf [4121ca4](http://projects.ceondo.com/p/pluf/source/commit/4121ca4) - Compatiblity fixes for PostgreSQL
## Language and Translations
- French translation updated (thanks to Jonathan Aillet!)
# InDefero 1.3 - Sun Apr 15 21:10 2012 UTC
This new major release of Indefero is possible thanks to the sponsor of
[Scilab Enterprises](http://www.scilab-enterprises.com/).
Scilab Enterprises is proud to share with the Indefero community the new
changes which greatly improves the overall quality of the Indefero
forge.
**ATTENTION**: InDefero now requires a PHP 5.3 compatible setup! You also
need Pluf [4121ca4](http://projects.ceondo.com/p/pluf/source/commit/4121ca4)
or newer to properly run this version of Indefero! or newer to properly run this version of Indefero!
## Changes ## Changes
@ -14,9 +28,9 @@ or newer to properly run this version of Indefero!
`$cfg['webhook_processing']` flag to "compat", we urge you to change the `$cfg['webhook_processing']` flag to "compat", we urge you to change the
implementations of this web hook as this setting is likely to be removed implementations of this web hook as this setting is likely to be removed
in future versions of Indefero. in future versions of Indefero.
- Indefero now needs PHP's zip module which is not enabled by default. - Indefero now needs PHP's zip module which is usually not enabled by default.
- Existing email notifications now have to be explicitely activated in the - Previously configured email notifications now have to be explicitely
project's administrative area. activated in the project's administrative area.
## New Features ## New Features
@ -28,7 +42,7 @@ or newer to properly run this version of Indefero!
mail addresses are notified about updates in a certain section, such as mail addresses are notified about updates in a certain section, such as
issues, downloads, reviews, and so on. We now also ensure that notification issues, downloads, reviews, and so on. We now also ensure that notification
emails for one object are uniquely identifyable to support a grouped view emails for one object are uniquely identifyable to support a grouped view
in email clients that support that. (fixes issues 334, 452, and 480) in email clients that support that. (fixes issues 334, 452, 480, and 791)
- Indefero can now be configured to record activity metrics for all projects - Indefero can now be configured to record activity metrics for all projects
in a forge. This needs a special cron job named 'activitycron.php` in a forge. This needs a special cron job named 'activitycron.php`
(under `scripts`) that is run on a regular basis. The metrics can be (under `scripts`) that is run on a regular basis. The metrics can be
@ -53,22 +67,19 @@ or newer to properly run this version of Indefero!
## Bugfixes ## Bugfixes
- Ensure that IDF does not break UTF-8 encoded strings when
shortening them for view rendering (issue 785)
- Indefero no longer confuses a non-owner of an issue with a notification that - Indefero no longer confuses a non-owner of an issue with a notification that
a particular ticket has been opened and assigned to him (fixes issue 562) a particular ticket has been opened and assigned to him (fixes issue 562)
# InDefero 1.2.1 - XXX XXX XX XX:XX:XX UTC 201X
## Bugfixes
- The diff view now renders properly in Firefox when a minimum font size - The diff view now renders properly in Firefox when a minimum font size
is configured or the user zooms the web page (fixes issue 773) is configured or the user zooms the web page (fixes issue 773)
- Ensure that IDF does not break UTF-8 encoded strings when
shortening them for view rendering (issue 785)
- Two XSS holes in the issue and review details views are closed (fixes issue 793)
## Language and Translations ## Language and Translations
- Multiple fixes to English source strings (fixes issues 763, 766, and 772, - Multiple fixes to English source strings (fixes issues 763, 766, and 772,
thanks to JP Fleury!) thanks to JP Fleury!)
- Updates to the French translation (thanks to Victor Quinault)
# InDefero 1.2 - Sun Nov 6 23:04:00 UTC 2011 # InDefero 1.2 - Sun Nov 6 23:04:00 UTC 2011

View File

@ -141,7 +141,12 @@ class IDF_ActivityTaxonomy
$cache[$argIdent] = 0; $cache[$argIdent] = 0;
list($higher, $lower) = $dateBoundaries; list($higher, $lower) = $dateBoundaries;
$sql = new Pluf_SQL('model_class IN ("'.implode('","', $classes).'") '. $db = Pluf::db();
$classes_esc = array();
foreach ($classes as $class) {
$classes_esc[] = $db->esc($class);
}
$sql = new Pluf_SQL('model_class IN ('.implode(',', $classes_esc).') '.
'AND creation_dtime >= %s AND creation_dtime <= %s', 'AND creation_dtime >= %s AND creation_dtime <= %s',
array($lower, $higher)); array($lower, $higher));

View File

@ -53,7 +53,7 @@ class IDF_Forge
} }
public function getProjectLabelsWithCounts() { public function getProjectLabelsWithCounts() {
$sql = new Pluf_SQL('project=0'); $sql = new Pluf_SQL('project IS NULL');
$tagList = Pluf::factory('IDF_Tag')->getList(array( $tagList = Pluf::factory('IDF_Tag')->getList(array(
'filter' => $sql->gen(), 'filter' => $sql->gen(),
'view' => 'join_projects', 'view' => 'join_projects',
@ -92,4 +92,4 @@ class IDF_Forge
public function setCustomForgePageContent($content) { public function setCustomForgePageContent($content) {
$this->conf->setVal('custom_forge_page_content', $content); $this->conf->setVal('custom_forge_page_content', $content);
} }
} }

View File

@ -0,0 +1,46 @@
<?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) 2008-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 ***** */
function IDF_Migrations_25NullableProjectInTag_up($params=null)
{
$engine = Pluf::f('db_engine');
$db = Pluf::db();
if ($engine === 'PostgreSQL') {
$db->execute('ALTER TABLE '.$db->pfx.'idf_tags ALTER COLUMN project DROP NOT NULL');
} else if ($engine === 'MySQL') {
$db->execute('ALTER TABLE '.$db->pfx.'idf_tags MODIFY project MEDIUMINT NULL');
// this is only needed for non-transactional setups where MySQL set 0 as default value
$db->execute('UPDATE '.$db->pfx.'idf_tags SET project=NULL WHERE project=0');
}
}
function IDF_Migrations_25NullableProjectInTag_down($params=null)
{
$db = Pluf::db();
if ($engine === 'PostgreSQL') {
$db->execute('ALTER TABLE '.$db->pfx.'idf_tags ALTER COLUMN project SET NOT NULL');
} else if ($engine === 'MySQL') {
$db->execute('ALTER TABLE '.$db->pfx.'idf_tags MODIFY project MEDIUMINT NOT NULL');
}
}

View File

@ -115,8 +115,7 @@ class IDF_Project extends Pluf_Model
array( array(
'join' => 'LEFT JOIN '.$activityTable.' ON current_activity='.$activityTable.'.id ' 'join' => 'LEFT JOIN '.$activityTable.' ON current_activity='.$activityTable.'.id '
.'LEFT JOIN '.$tagTable.' ON idf_project_id='.$this->getSqlTable().'.id', .'LEFT JOIN '.$tagTable.' ON idf_project_id='.$this->getSqlTable().'.id',
'select' => $this->getSelect().', date, value', 'select' => 'DISTINCT '.$this->getSelect().', date, value',
'group' => $this->getSqlTable().'.id',
'props' => array( 'props' => array(
'date' => 'current_activity_date', 'date' => 'current_activity_date',
'value' => 'current_activity_value' 'value' => 'current_activity_value'

View File

@ -48,7 +48,8 @@ class IDF_Tag extends Pluf_Model
array( array(
'type' => 'Pluf_DB_Field_Foreignkey', 'type' => 'Pluf_DB_Field_Foreignkey',
'model' => 'IDF_Project', 'model' => 'IDF_Project',
'blank' => false, 'blank' => true,
'is_null' => true,
'verbose' => __('project'), 'verbose' => __('project'),
), ),
'class' => 'class' =>
@ -76,13 +77,14 @@ class IDF_Tag extends Pluf_Model
); );
$table = $this->_con->pfx.'idf_project_idf_tag_assoc'; $table = $this->_con->pfx.'idf_project_idf_tag_assoc';
$cols = implode(', ', array_keys($this->_a['cols']));
$this->_a['views'] = array( $this->_a['views'] = array(
'join_projects' => 'join_projects' =>
array( array(
'join' => 'LEFT JOIN '.$table 'join' => 'LEFT JOIN '.$table
.' ON idf_tag_id=id', .' ON idf_tag_id=id',
'select' => $this->getSelect().',COUNT(idf_project_id) as project_count', 'select' => $this->getSelect().',COUNT(idf_project_id) as project_count',
'group' => 'idf_tag_id', 'group' => $cols,
'props' => array('project_count' => 'project_count'), 'props' => array('project_count' => 'project_count'),
), ),
); );
@ -146,7 +148,7 @@ class IDF_Tag extends Pluf_Model
$class = trim($class); $class = trim($class);
$name = trim($name); $name = trim($name);
$gtag = new IDF_Tag(); $gtag = new IDF_Tag();
$sql = new Pluf_SQL('class=%s AND lcname=%s AND project=0', $sql = new Pluf_SQL('class=%s AND lcname=%s AND project IS NULL',
array($class, mb_strtolower($name))); array($class, mb_strtolower($name)));
$tags = $gtag->getList(array('filter' => $sql->gen())); $tags = $gtag->getList(array('filter' => $sql->gen()));
if ($tags->count() < 1) { if ($tags->count() < 1) {
@ -154,6 +156,7 @@ class IDF_Tag extends Pluf_Model
$tag = new IDF_Tag(); $tag = new IDF_Tag();
$tag->name = $name; $tag->name = $name;
$tag->class = $class; $tag->class = $class;
$tag->project = null;
$tag->create(); $tag->create();
return $tag; return $tag;
} }

View File

@ -83,7 +83,7 @@ class IDF_Template_MarkdownForge extends Pluf_Template_Tag
$name = $class; $name = $class;
$class = IDF_TAG_DEFAULT_CLASS; $class = IDF_TAG_DEFAULT_CLASS;
} }
$sql = new Pluf_SQL('class=%s AND lcname=%s AND project=0', $sql = new Pluf_SQL('class=%s AND lcname=%s AND project IS NULL',
array(strtolower($class), mb_strtolower($name))); array(strtolower($class), mb_strtolower($name)));
$tag = Pluf::factory('IDF_Tag')->getOne(array('filter' => $sql->gen())); $tag = Pluf::factory('IDF_Tag')->getOne(array('filter' => $sql->gen()));
} }

View File

@ -382,14 +382,14 @@ class IDF_Views
{ {
$db =& Pluf::db(); $db =& Pluf::db();
$false = Pluf_DB_BooleanToDb(false, $db); $false = Pluf_DB_BooleanToDb(false, $db);
$sql = new Pluf_SQL(1); $sql = new Pluf_SQL('1=1');
if ($tag !== false) { if ($tag !== false) {
$sql->SAnd(new Pluf_SQL('idf_tag_id=%s', $tag->id)); $sql->SAnd(new Pluf_SQL('idf_tag_id=%s', $tag->id));
} }
if ($user->isAnonymous()) if ($user->isAnonymous())
{ {
$authSql = new Pluf_SQL('private=%s', $false); $authSql = new Pluf_SQL($db->qn('private').'='.$false);
$sql->SAnd($authSql); $sql->SAnd($authSql);
} else } else
if (!$user->administrator) { if (!$user->administrator) {
@ -403,7 +403,7 @@ class IDF_Views
$permSql = new Pluf_SQL("model_class='IDF_Project' AND owner_class='Pluf_User' AND owner_id=%s AND negative=".$false, $user->id); $permSql = 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' => $permSql->gen())); $rows = Pluf::factory('Pluf_RowPermission')->getList(array('filter' => $permSql->gen()));
$authSql = new Pluf_SQL('private=%s', $false); $authSql = new Pluf_SQL($db->qn('private').'='.$false);
if ($rows->count() > 0) { if ($rows->count() > 0) {
$ids = array(); $ids = array();
foreach ($rows as $row) { foreach ($rows as $row) {

View File

@ -645,7 +645,7 @@ class IDF_Views_Issue
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Issue::view', $url = Pluf_HTTP_URL_urlForView('IDF_Views_Issue::view',
array($prj->shortname, $issue->id)); array($prj->shortname, $issue->id));
$title = Pluf_Template::markSafe(sprintf(__('Issue <a href="%1$s">%2$d</a>: %3$s'), $url, $issue->id, $issue->summary)); $title = Pluf_Template::markSafe(sprintf(__('Issue <a href="%1$s">%2$d</a>: %3$s'), $url, $issue->id, Pluf_esc($issue->summary)));
$form = false; // The form is available only if logged in. $form = false; // The form is available only if logged in.
$starred = false; $starred = false;
$closed = in_array($issue->status, $prj->getTagIdsByStatus('closed')); $closed = in_array($issue->status, $prj->getTagIdsByStatus('closed'));

View File

@ -137,7 +137,7 @@ class IDF_Views_Review
$prj->inOr404($review); $prj->inOr404($review);
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Review::view', $url = Pluf_HTTP_URL_urlForView('IDF_Views_Review::view',
array($prj->shortname, $review->id)); array($prj->shortname, $review->id));
$title = Pluf_Template::markSafe(sprintf(__('Review <a href="%1$s">%2$d</a>: %3$s'), $url, $review->id, $review->summary)); $title = Pluf_Template::markSafe(sprintf(__('Review <a href="%1$s">%2$d</a>: %3$s'), $url, $review->id, Pluf_esc($review->summary)));
$patches = $review->get_patches_list(); $patches = $review->get_patches_list();
$patch = $patches[0]; $patch = $patches[0];

View File

@ -2116,10 +2116,10 @@ msgstr ""
"Grunde genommen eine normale\n" "Grunde genommen eine normale\n"
"ZIP-Datei ist, die weitere Meta-Informationen enthält. Diese " "ZIP-Datei ist, die weitere Meta-Informationen enthält. Diese "
"Meta-Informationen werden in einer speziellen\n" "Meta-Informationen werden in einer speziellen\n"
"Manifest-Datei aufgehoben, die getrennt von den anderen Dateien des Archivs " "Manifest-Datei beschrieben, die getrennt von den anderen Dateien des Archivs "
"behandelt wird.</p>\n" "behandelt wird.</p>\n"
"<p>Sobald das Archiv hochgeladen wurde, liest InDefero die Meta-Informatine " "<p>Sobald das Archiv hochgeladen wurde, liest InDefero die "
"aus, entpackt die anderen Dateien\n" "Meta-Informationen aus, entpackt die anderen Dateien\n"
"vom Archiv und erzeugt für jede von ihnen individuelle Downloads.</p>" "vom Archiv und erzeugt für jede von ihnen individuelle Downloads.</p>"
#: IDF/gettexttemplates/idf/faq.html.php:36 #: IDF/gettexttemplates/idf/faq.html.php:36
@ -2278,8 +2278,8 @@ msgstr ""
"<p>Zusätzlich sind die folgenden Makros verfügbar:<br />\n" "<p>Zusätzlich sind die folgenden Makros verfügbar:<br />\n"
"<ul>\n" "<ul>\n"
"<li><code>&#x7b;projectlist, label=..., order=(name|activity), " "<li><code>&#x7b;projectlist, label=..., order=(name|activity), "
"limit=...}</code> -Zeigt eine Projektliste an, die optional nach " "limit=...}</code> -Zeigt eine Projektliste an, die optional nach Marke "
"Markegefiltert und nach Name oder Aktivität sortiert und / oder auf eine " "gefiltert und nach Name oder Aktivität sortiert und / oder auf eine "
"bestimmte Anzahl von Projekten beschränkt werden kann.</li>\n" "bestimmte Anzahl von Projekten beschränkt werden kann.</li>\n"
"</ul>\n" "</ul>\n"
"</p>\n" "</p>\n"

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
<?php <?php
return array( return array(
'version' => '1.3-dev', 'version' => '1.4-dev',
'revision' => '$Format:%H$', 'revision' => '$Format:%H$',
); );