Compare commits
39 Commits
v1.3
...
release-1.
Author | SHA1 | Date | |
---|---|---|---|
|
6f4af6b68d | ||
|
ebb8d46420 | ||
|
6c5406dd99 | ||
|
4aa4100532 | ||
|
d90c1a2c23 | ||
|
22c1f92b2b | ||
|
d17098e703 | ||
|
64c6674762 | ||
|
839444cc8a | ||
|
831439120c | ||
|
6bb886b92a | ||
|
dd3474c06c | ||
|
bcd515eed5 | ||
|
0826dab575 | ||
|
1c037f81a0 | ||
|
71c41fe940 | ||
|
8ad0707509 | ||
|
a2d5b14a2c | ||
|
16de6a0d77 | ||
|
03404adf64 | ||
|
dd2fa6f902 | ||
|
b6acf4c0e2 | ||
|
8db3c45763 | ||
|
e8882292b5 | ||
|
bca3eb332e | ||
|
307c35ff42 | ||
|
786e9f81c0 | ||
|
8cd19c0f53 | ||
|
d5394265ba | ||
|
0919cb83d8 | ||
|
b7ad4bf47a | ||
|
75f62663a9 | ||
|
169fbe6216 | ||
|
84d80af1ce | ||
|
d1542c9c00 | ||
|
4da01b2732 | ||
|
b44ad48fd5 | ||
|
3ae92627bc | ||
|
d46df5c129 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -5,6 +5,7 @@
|
|||||||
.settings
|
.settings
|
||||||
.tx/config
|
.tx/config
|
||||||
attachments
|
attachments
|
||||||
|
backups
|
||||||
indefero-*.zip
|
indefero-*.zip
|
||||||
src/IDF/conf/idf.php
|
src/IDF/conf/idf.php
|
||||||
src/IDF/conf/idf.test.php
|
src/IDF/conf/idf.test.php
|
||||||
|
2
AUTHORS
2
AUTHORS
@@ -7,6 +7,7 @@ Much appreciated contributors (in alphabetical order):
|
|||||||
Andrew Nguyen <andrew-git-indefero@na-consulting.net>
|
Andrew Nguyen <andrew-git-indefero@na-consulting.net>
|
||||||
Baptiste Durand-Bret <bathizte@ozazar.org>
|
Baptiste Durand-Bret <bathizte@ozazar.org>
|
||||||
Baptiste Michaud <bactisme@gmail.com> - Subversion sync
|
Baptiste Michaud <bactisme@gmail.com> - Subversion sync
|
||||||
|
Benjamin Danon <benjamin@sphax3d.org> - French translation
|
||||||
Benjamin Jorand <benjamin.jorand@gmail.com> - Mercurial support
|
Benjamin Jorand <benjamin.jorand@gmail.com> - Mercurial support
|
||||||
Brenda Wallace <shiny@cpan.org>
|
Brenda Wallace <shiny@cpan.org>
|
||||||
Brian Armstrong <brianar>
|
Brian Armstrong <brianar>
|
||||||
@@ -22,6 +23,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 <jonathan.aillet@gmail.com> - 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>
|
||||||
|
23
Makefile
23
Makefile
@@ -37,10 +37,11 @@ help:
|
|||||||
@printf "\tpo-push - Send the all PO files to the transifex server.\n"
|
@printf "\tpo-push - Send the all PO files to the transifex server.\n"
|
||||||
@printf "\tpo-pull - Get all PO files from the transifex server.\n"
|
@printf "\tpo-pull - Get all PO files from the transifex server.\n"
|
||||||
@printf "\tpo-stats - Show translation statistics of all PO files.\n"
|
@printf "\tpo-stats - Show translation statistics of all PO files.\n"
|
||||||
@printf "\nMisc Rules :\n";
|
@printf "\nRules for managing the database :\n";
|
||||||
@printf "\tdb-install - Install the database schema.\n"
|
@printf "\tdb-install - Install the database schema.\n"
|
||||||
@printf "\tdb-update - Update the database schema.\n"
|
@printf "\tdb-update - Update the database schema.\n"
|
||||||
|
@printf "\tdb-backup-foo - Create a named backup 'foo' with data from the current database.\n"
|
||||||
|
@printf "\tdb-restore-foo - Restore schema and the data from a named backup 'foo' to an empty database.\n"
|
||||||
|
|
||||||
#
|
#
|
||||||
# Internationalization rule, POT & PO file manipulation
|
# Internationalization rule, POT & PO file manipulation
|
||||||
@@ -139,8 +140,8 @@ po-stats:
|
|||||||
# make develop_zipfile
|
# make develop_zipfile
|
||||||
#
|
#
|
||||||
%-zipfile:
|
%-zipfile:
|
||||||
@git archive --format=zip --prefix="indefero/" $(@:-zipfile=) \
|
@git archive --format=zip --prefix="indefero/" $* \
|
||||||
> indefero-$(@:-zipfile=)-`git log $(@:-zipfile=) -n 1 \
|
> indefero-$*-`git log $* -n 1 \
|
||||||
--pretty=format:%h`.zip
|
--pretty=format:%h`.zip
|
||||||
|
|
||||||
db-install:
|
db-install:
|
||||||
@@ -148,3 +149,13 @@ db-install:
|
|||||||
|
|
||||||
db-update:
|
db-update:
|
||||||
@cd src && php "$(PLUF_PATH)/migrate.php" --conf=IDF/conf/idf.php -a -d
|
@cd src && php "$(PLUF_PATH)/migrate.php" --conf=IDF/conf/idf.php -a -d
|
||||||
|
|
||||||
|
db-backup-%:
|
||||||
|
@[ -e backups ] || mkdir backups
|
||||||
|
@cd src && php "$(PLUF_PATH)/migrate.php" --conf=IDF/conf/idf.php -a -b ../backups $*
|
||||||
|
@echo Files for named backup $* have been saved into backups/ directory.
|
||||||
|
|
||||||
|
db-restore-%:
|
||||||
|
@cd src && php "$(PLUF_PATH)/migrate.php" --conf=IDF/conf/idf.php -a -r ../backups $*
|
||||||
|
@echo Files for named backup $* have been restored from the backups/ directory.
|
||||||
|
|
||||||
|
70
NEWS.mdtext
70
NEWS.mdtext
@@ -1,4 +1,70 @@
|
|||||||
# InDefero 1.3 - Sun Apr 15 21:10 2011 UTC
|
# InDefero 1.3.4 - xxx xxx xx xx:xx:xx UTC 201X
|
||||||
|
|
||||||
|
## Bugfixes
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
# InDefero 1.3.3 - Sun Nov 18 22:54:00 UTC 2012
|
||||||
|
|
||||||
|
**ATTENTION**: InDefero needs Pluf [a45dc195](http://projects.ceondo.com/p/pluf/source/commit/a45dc195)
|
||||||
|
or newer to run properly!
|
||||||
|
|
||||||
|
## Bugfixes
|
||||||
|
|
||||||
|
- A long standing bug in the Mercurial plugin that lead to corruption
|
||||||
|
of boolean configuration values in the `hgrc` of the served repository
|
||||||
|
has been fixed (issue 523).
|
||||||
|
|
||||||
|
- If an anonymous or authenticated user had no access to any project in a
|
||||||
|
forge, all projects were listed for him (but still no one was actually
|
||||||
|
accessible). This has been fixed.
|
||||||
|
|
||||||
|
- Fixed a problem where the SyncGit plugin doesn't properly updates the
|
||||||
|
authorized_keys file when the public key data contained slashes (thanks
|
||||||
|
to Simon Gareste for the fix!)
|
||||||
|
|
||||||
|
- Under PostgreSQL indefero could not be set up because of a circular
|
||||||
|
foreign key dependency. This has been fixed (issue 800).
|
||||||
|
|
||||||
|
- Under PostgreSQL new projects could not be created due to a failing
|
||||||
|
foreign key relation. Adding project tags was not possible for a similar
|
||||||
|
reason. This has been fixed (issue 800, continued).
|
||||||
|
|
||||||
|
- If a project was created based on the settings of an existing project,
|
||||||
|
not all settings, like for example the new notification settings, have
|
||||||
|
been copied. This has been changed insofar that now all properties except
|
||||||
|
the project's URL, logo and individual SCM settings are copied by default.
|
||||||
|
|
||||||
|
- Wiki pages couldn't be properly saved with E_NOTICE enabled because
|
||||||
|
of a syntax error (fixes issue 808).
|
||||||
|
|
||||||
|
- Indefero now shows detected copies in git changesets.
|
||||||
|
|
||||||
|
- A user is no longer redirected to the Help page if he enters 'H' in the
|
||||||
|
password text field on the login page (fixes issue 821).
|
||||||
|
|
||||||
|
# InDefero 1.3.2 - Wed May 09 20:05 2012 UTC
|
||||||
|
|
||||||
|
## Bugfixes
|
||||||
|
|
||||||
|
- Fix two bugs in the project list view if no project
|
||||||
|
is visible to the user or available in the forge (issue 805)
|
||||||
|
|
||||||
|
# InDefero 1.3.1 - Sun May 06 20:32 2012 UTC
|
||||||
|
|
||||||
|
## Bugfixes
|
||||||
|
|
||||||
|
- Compatiblity fixes for PostgreSQL (issue 800)
|
||||||
|
- Fix TOC generation in wiki (issue 803)
|
||||||
|
- Make the display of large files and diffs faster (issue 804)
|
||||||
|
- Make the project list faster and its tag list more accurate by not
|
||||||
|
counting projects that are invisible to the current user
|
||||||
|
|
||||||
|
## 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
|
This new major release of Indefero is possible thanks to the sponsor of
|
||||||
[Scilab Enterprises](http://www.scilab-enterprises.com/).
|
[Scilab Enterprises](http://www.scilab-enterprises.com/).
|
||||||
@@ -34,7 +100,7 @@ or newer to properly run this version of Indefero!
|
|||||||
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, 480, and 791)
|
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
|
||||||
fine-tuned via `activity_section_weights` and `activity_lookback` in
|
fine-tuned via `activity_section_weights` and `activity_lookback` in
|
||||||
`idf.php` and the result is visible as green bar in the project list view.
|
`idf.php` and the result is visible as green bar in the project list view.
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
$xmlfile = dirname(__FILE__) .'/test/report.xml';
|
$xmlfile = dirname(__FILE__) .'/test/report.xml';
|
||||||
passthru('phpunit --coverage-clover='.$xmlfile);
|
passthru('phpunit --coverage-clover='.escapeshellarg($xmlfile));
|
||||||
$xml = simplexml_load_string(file_get_contents($xmlfile));
|
$xml = simplexml_load_string(file_get_contents($xmlfile));
|
||||||
unlink($xmlfile);
|
unlink($xmlfile);
|
||||||
printf(
|
printf(
|
||||||
|
@@ -44,10 +44,15 @@ class IDF_ActivityTaxonomy
|
|||||||
{
|
{
|
||||||
public static function recalculateTaxnomies(DateTime $date)
|
public static function recalculateTaxnomies(DateTime $date)
|
||||||
{
|
{
|
||||||
|
$sectionWeights = Pluf::f('activity_section_weights', null);
|
||||||
|
$lookback = Pluf::f('activity_lookback', null);
|
||||||
|
if ($sectionWeights === null || $lookback === null) {
|
||||||
|
throw new LogicException('activity configuration is missing in idf.php');
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// query and normalize the section weights
|
// query and normalize the section weights
|
||||||
//
|
//
|
||||||
$sectionWeights = Pluf::f('activity_section_weights', array());
|
|
||||||
$allWeights = array_sum($sectionWeights);
|
$allWeights = array_sum($sectionWeights);
|
||||||
if ($allWeights == 0) {
|
if ($allWeights == 0) {
|
||||||
throw new LogicException('the sum of all "activity_section_weights" must not be 0');
|
throw new LogicException('the sum of all "activity_section_weights" must not be 0');
|
||||||
@@ -59,7 +64,6 @@ class IDF_ActivityTaxonomy
|
|||||||
//
|
//
|
||||||
// determine the date boundaries
|
// determine the date boundaries
|
||||||
//
|
//
|
||||||
$lookback = Pluf::f('activity_lookback', 0);
|
|
||||||
if ($lookback < 1) {
|
if ($lookback < 1) {
|
||||||
throw new LogicException('lookback must be greater or equal to 1');
|
throw new LogicException('lookback must be greater or equal to 1');
|
||||||
}
|
}
|
||||||
@@ -141,7 +145,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));
|
||||||
|
|
||||||
|
@@ -84,7 +84,7 @@ class IDF_Conf extends Pluf_Model
|
|||||||
|
|
||||||
function initCache()
|
function initCache()
|
||||||
{
|
{
|
||||||
$this->datacache = new ArrayObject();
|
$this->datacache = array();
|
||||||
$sql = new Pluf_SQL('project=%s', $this->_project->id);
|
$sql = new Pluf_SQL('project=%s', $this->_project->id);
|
||||||
foreach ($this->getList(array('filter' => $sql->gen())) as $val) {
|
foreach ($this->getList(array('filter' => $sql->gen())) as $val) {
|
||||||
$this->datacache[$val->vkey] = $val->vdesc;
|
$this->datacache[$val->vkey] = $val->vdesc;
|
||||||
@@ -129,4 +129,12 @@ class IDF_Conf extends Pluf_Model
|
|||||||
$this->initCache();
|
$this->initCache();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getKeys()
|
||||||
|
{
|
||||||
|
if ($this->datacache === null) {
|
||||||
|
$this->initCache();
|
||||||
|
}
|
||||||
|
return array_keys($this->datacache);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -147,7 +147,7 @@ class IDF_FileUtil
|
|||||||
* Splits a string into separate lines while retaining the individual
|
* Splits a string into separate lines while retaining the individual
|
||||||
* line ending character for every line.
|
* line ending character for every line.
|
||||||
*
|
*
|
||||||
* OS9 line endings are not supported.
|
* OS 9 line endings are not supported.
|
||||||
*
|
*
|
||||||
* @param string content
|
* @param string content
|
||||||
* @param boolean if true, skip completely empty lines
|
* @param boolean if true, skip completely empty lines
|
||||||
@@ -155,19 +155,16 @@ class IDF_FileUtil
|
|||||||
*/
|
*/
|
||||||
public static function splitIntoLines($content, $skipEmpty = false)
|
public static function splitIntoLines($content, $skipEmpty = false)
|
||||||
{
|
{
|
||||||
$flags = PREG_SPLIT_OFFSET_CAPTURE;
|
$last_off = 0;
|
||||||
if ($skipEmpty) $flags |= PREG_SPLIT_NO_EMPTY;
|
|
||||||
$splitted = preg_split("/\r\n|\n/", $content, -1, $flags);
|
|
||||||
|
|
||||||
$last_off = -1;
|
|
||||||
$lines = array();
|
$lines = array();
|
||||||
while (($split = array_shift($splitted)) !== null) {
|
while (preg_match("/\r\n|\n/", $content, $m, PREG_OFFSET_CAPTURE, $last_off)) {
|
||||||
if ($last_off != -1) {
|
$next_off = strlen($m[0][0]) + $m[0][1];
|
||||||
$lines[] .= substr($content, $last_off, $split[1] - $last_off);
|
$line = substr($content, $last_off, $next_off - $last_off);
|
||||||
}
|
$last_off = $next_off;
|
||||||
$last_off = $split[1];
|
if ($line !== $m[0][0] || !$skipEmpty) $lines[] = $line;
|
||||||
}
|
}
|
||||||
$lines[] = substr($content, $last_off);
|
$line = substr($content, $last_off);
|
||||||
|
if ($line !== false && strlen($line) > 0) $lines[] = $line;
|
||||||
return $lines;
|
return $lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -52,31 +52,6 @@ class IDF_Forge
|
|||||||
$this->conf->setVal('project_labels', $labels);
|
$this->conf->setVal('project_labels', $labels);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getProjectLabelsWithCounts() {
|
|
||||||
$sql = new Pluf_SQL('project=0');
|
|
||||||
$tagList = Pluf::factory('IDF_Tag')->getList(array(
|
|
||||||
'filter' => $sql->gen(),
|
|
||||||
'view' => 'join_projects',
|
|
||||||
'order' => 'class ASC, lcname ASC'
|
|
||||||
));
|
|
||||||
|
|
||||||
$maxProjectCount = 0;
|
|
||||||
foreach ($tagList as $tag) {
|
|
||||||
$maxProjectCount = max($maxProjectCount, $tag->project_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
$tags = array();
|
|
||||||
foreach ($tagList as $tag) {
|
|
||||||
// group by class
|
|
||||||
if (!array_key_exists($tag->class, $tags)) {
|
|
||||||
$tags[$tag->class] = array();
|
|
||||||
}
|
|
||||||
$tag->rel_project_count = $tag->project_count / (double) $maxProjectCount;
|
|
||||||
$tags[$tag->class][] = $tag;
|
|
||||||
}
|
|
||||||
return $tags;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setCustomForgePageEnabled($enabled) {
|
public function setCustomForgePageEnabled($enabled) {
|
||||||
$this->conf->setVal('custom_forge_page_enabled', $enabled);
|
$this->conf->setVal('custom_forge_page_enabled', $enabled);
|
||||||
}
|
}
|
||||||
|
@@ -360,45 +360,35 @@ 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',
|
|
||||||
'svn_password', 'mtn_master_branch', 'external_project_url');
|
|
||||||
foreach ($keys as $key) {
|
|
||||||
$this->cleaned_data[$key] = (!empty($this->cleaned_data[$key])) ?
|
|
||||||
$this->cleaned_data[$key] : '';
|
|
||||||
$conf->setVal($key, $this->cleaned_data[$key]);
|
|
||||||
}
|
|
||||||
if ($this->cleaned_data['template'] != '--') {
|
if ($this->cleaned_data['template'] != '--') {
|
||||||
$tmplconf = new IDF_Conf();
|
$tmplconf = new IDF_Conf();
|
||||||
$tmplconf->setProject($tmpl);
|
$tmplconf->setProject($tmpl);
|
||||||
// We need to get all the configuration variables we want from
|
|
||||||
// the old project and put them into the new project.
|
$allKeys = $tmplconf->getKeys();
|
||||||
$props = array(
|
$scm = $this->cleaned_data['scm'];
|
||||||
'labels_download_predefined' => IDF_Form_UploadConf::init_predefined,
|
$ignoreKeys = array('scm', 'external_project_url', 'logo');
|
||||||
'labels_download_one_max' => IDF_Form_UploadConf::init_one_max,
|
|
||||||
'labels_wiki_predefined' => IDF_Form_WikiConf::init_predefined,
|
// copy over all existing variables, except scm-related data and
|
||||||
'labels_wiki_one_max' => IDF_Form_WikiConf::init_one_max,
|
// the project url / logo
|
||||||
'labels_issue_template' => IDF_Form_IssueTrackingConf::init_template,
|
foreach ($allKeys as $key) {
|
||||||
'labels_issue_open' => IDF_Form_IssueTrackingConf::init_open,
|
if (in_array($key, $ignoreKeys) || strpos($key, $scm.'_') === 0) {
|
||||||
'labels_issue_closed' => IDF_Form_IssueTrackingConf::init_closed,
|
continue;
|
||||||
'labels_issue_predefined' => IDF_Form_IssueTrackingConf::init_predefined,
|
}
|
||||||
'labels_issue_one_max' => IDF_Form_IssueTrackingConf::init_one_max,
|
$conf->setVal($key, $tmplconf->getVal($key));
|
||||||
'issue_relations' => IDF_Form_IssueTrackingConf::init_relations,
|
|
||||||
'webhook_url' => '',
|
|
||||||
'downloads_access_rights' => 'all',
|
|
||||||
'review_access_rights' => 'all',
|
|
||||||
'wiki_access_rights' => 'all',
|
|
||||||
'source_access_rights' => 'all',
|
|
||||||
'issues_access_rights' => 'all',
|
|
||||||
'downloads_notification_email' => '',
|
|
||||||
'review_notification_email' => '',
|
|
||||||
'wiki_notification_email' => '',
|
|
||||||
'source_notification_email' => '',
|
|
||||||
'issues_notification_email' => '',
|
|
||||||
);
|
|
||||||
foreach ($props as $prop => $def) {
|
|
||||||
$conf->setVal($prop, $tmplconf->getVal($prop, $def));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$keys = array(
|
||||||
|
'scm', 'svn_remote_url', 'svn_username',
|
||||||
|
'svn_password', 'mtn_master_branch',
|
||||||
|
'external_project_url'
|
||||||
|
);
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
$this->cleaned_data[$key] = !empty($this->cleaned_data[$key]) ?
|
||||||
|
$this->cleaned_data[$key] : '';
|
||||||
|
$conf->setVal($key, $this->cleaned_data[$key]);
|
||||||
|
}
|
||||||
$project->created();
|
$project->created();
|
||||||
|
|
||||||
if ($this->cleaned_data['template'] == '--') {
|
if ($this->cleaned_data['template'] == '--') {
|
||||||
|
47
src/IDF/Migrations/25NullableProjectInTag.php
Normal file
47
src/IDF/Migrations/25NullableProjectInTag.php
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<?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)
|
||||||
|
{
|
||||||
|
$engine = Pluf::f('db_engine');
|
||||||
|
$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');
|
||||||
|
}
|
||||||
|
}
|
46
src/IDF/Migrations/26NullableActivityInProject.php
Normal file
46
src/IDF/Migrations/26NullableActivityInProject.php
Normal 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-2012 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_26NullableActivityInProject_up($params=null)
|
||||||
|
{
|
||||||
|
$engine = Pluf::f('db_engine');
|
||||||
|
$db = Pluf::db();
|
||||||
|
if ($engine === 'PostgreSQL') {
|
||||||
|
$db->execute('ALTER TABLE '.$db->pfx.'idf_projects ALTER COLUMN current_activity DROP NOT NULL');
|
||||||
|
} else if ($engine === 'MySQL') {
|
||||||
|
$db->execute('ALTER TABLE '.$db->pfx.'idf_projects MODIFY current_activity MEDIUMINT NULL');
|
||||||
|
// this is only needed for non-transactional setups where MySQL set 0 as default value
|
||||||
|
$db->execute('UPDATE '.$db->pfx.'idf_projects SET current_activity=NULL WHERE current_activity=0');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function IDF_Migrations_26NullableActivityInProject_down($params=null)
|
||||||
|
{
|
||||||
|
$engine = Pluf::f('db_engine');
|
||||||
|
$db = Pluf::db();
|
||||||
|
if ($engine === 'PostgreSQL') {
|
||||||
|
$db->execute('ALTER TABLE '.$db->pfx.'idf_projects ALTER COLUMN current_activity SET NOT NULL');
|
||||||
|
} else if ($engine === 'MySQL') {
|
||||||
|
$db->execute('ALTER TABLE '.$db->pfx.'idf_projects MODIFY current_activity MEDIUMINT NOT NULL');
|
||||||
|
}
|
||||||
|
}
|
@@ -119,5 +119,9 @@ function IDF_Migrations_Backup_restore($folder, $name)
|
|||||||
foreach ($full_data as $model => $data) {
|
foreach ($full_data as $model => $data) {
|
||||||
Pluf_Test_Fixture::load($data, false);
|
Pluf_Test_Fixture::load($data, false);
|
||||||
}
|
}
|
||||||
|
foreach ($models as $model) {
|
||||||
|
$schema->model = new $model();
|
||||||
|
$schema->createConstraints();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -62,6 +62,10 @@ function IDF_Migrations_Install_setup($params=null)
|
|||||||
$schema->model = new $model();
|
$schema->model = new $model();
|
||||||
$schema->createTables();
|
$schema->createTables();
|
||||||
}
|
}
|
||||||
|
foreach ($models as $model) {
|
||||||
|
$schema->model = new $model();
|
||||||
|
$schema->createConstraints();
|
||||||
|
}
|
||||||
// Install the permissions
|
// Install the permissions
|
||||||
$perm = new Pluf_Permission();
|
$perm = new Pluf_Permission();
|
||||||
$perm->name = 'Project membership';
|
$perm->name = 'Project membership';
|
||||||
@@ -120,6 +124,10 @@ function IDF_Migrations_Install_teardown($params=null)
|
|||||||
);
|
);
|
||||||
$db = Pluf::db();
|
$db = Pluf::db();
|
||||||
$schema = new Pluf_DB_Schema($db);
|
$schema = new Pluf_DB_Schema($db);
|
||||||
|
foreach ($models as $model) {
|
||||||
|
$schema->model = new $model();
|
||||||
|
$schema->dropConstraints();
|
||||||
|
}
|
||||||
foreach ($models as $model) {
|
foreach ($models as $model) {
|
||||||
$schema->model = new $model();
|
$schema->model = new $model();
|
||||||
$schema->dropTables();
|
$schema->dropTables();
|
||||||
|
@@ -64,7 +64,7 @@ class IDF_Plugin_SyncGit_Cron
|
|||||||
// We update only the part of the file between IDF_START / IDF_END comment
|
// We update only the part of the file between IDF_START / IDF_END comment
|
||||||
$original_keys = file_get_contents($authorized_keys);
|
$original_keys = file_get_contents($authorized_keys);
|
||||||
if (strstr($original_keys, "# indefero start") && strstr($original_keys, "# indefero end")) {
|
if (strstr($original_keys, "# indefero start") && strstr($original_keys, "# indefero end")) {
|
||||||
$out = preg_replace('/(#\sindefero\sstart).+(#\sindefero\send\s\s?)/isU',
|
$out = preg_replace('%(#\sindefero\sstart).+(#\sindefero\send\s\s?)%isU',
|
||||||
$out, $original_keys);
|
$out, $original_keys);
|
||||||
} else {
|
} else {
|
||||||
$out .= $original_keys;
|
$out .= $original_keys;
|
||||||
|
@@ -178,7 +178,10 @@ class IDF_Plugin_SyncMercurial
|
|||||||
|
|
||||||
// Generate hgrc content
|
// Generate hgrc content
|
||||||
if (is_file($hgrc_file)) {
|
if (is_file($hgrc_file)) {
|
||||||
$tmp_content = parse_ini_file($hgrc_file, true);
|
$tmp_content = @parse_ini_file($hgrc_file, true, INI_SCANNER_RAW);
|
||||||
|
if ($tmp_content === false) {
|
||||||
|
throw new Exception('could not parse "'.$hgrc_file.'" because of syntax problems');
|
||||||
|
}
|
||||||
$tmp_content['web']['allow_push'] = $allow_push;
|
$tmp_content['web']['allow_push'] = $allow_push;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@@ -105,6 +105,8 @@ class IDF_Project extends Pluf_Model
|
|||||||
'type' => 'Pluf_DB_Field_Foreignkey',
|
'type' => 'Pluf_DB_Field_Foreignkey',
|
||||||
'model' => 'IDF_ProjectActivity',
|
'model' => 'IDF_ProjectActivity',
|
||||||
'blank' => true,
|
'blank' => true,
|
||||||
|
'is_null' => true,
|
||||||
|
'default' => null,
|
||||||
'verbose' => __('current project activity'),
|
'verbose' => __('current project activity'),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -115,8 +117,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'
|
||||||
|
@@ -52,11 +52,11 @@ class IDF_Scm_Git extends IDF_Scm
|
|||||||
* A doc/Guide utilisateur/images/ftp-nautilus.png
|
* A doc/Guide utilisateur/images/ftp-nautilus.png
|
||||||
* M doc/Guide utilisateur/textes/log_boot_PEGASE.txt
|
* M doc/Guide utilisateur/textes/log_boot_PEGASE.txt
|
||||||
*
|
*
|
||||||
* Status letters mean : Added (A), Deleted (D), Modified (M), Renamed (R)
|
* Status letters mean : Added (A), Copied (C), Deleted (D), Modified (M), Renamed (R)
|
||||||
*/
|
*/
|
||||||
public function getChanges($commit)
|
public function getChanges($commit)
|
||||||
{
|
{
|
||||||
$cmd = sprintf('GIT_DIR=%s '.Pluf::f('git_path', 'git').' show %s --name-status --pretty="format:" --diff-filter="[A|D|M|R]" -M',
|
$cmd = sprintf('GIT_DIR=%s '.Pluf::f('git_path', 'git').' show %s --name-status --pretty="format:" --diff-filter="[A|C|D|M|R]" -C -C',
|
||||||
escapeshellarg($this->repo),
|
escapeshellarg($this->repo),
|
||||||
escapeshellarg($commit));
|
escapeshellarg($commit));
|
||||||
$out = array();
|
$out = array();
|
||||||
@@ -89,6 +89,9 @@ class IDF_Scm_Git extends IDF_Scm
|
|||||||
} else if ($action == 'R') {
|
} else if ($action == 'R') {
|
||||||
$matches = preg_split("/\t/", $line);
|
$matches = preg_split("/\t/", $line);
|
||||||
$return->renames[$matches[1]] = $matches[2];
|
$return->renames[$matches[1]] = $matches[2];
|
||||||
|
} else if ($action == 'C') {
|
||||||
|
$matches = preg_split("/\t/", $line);
|
||||||
|
$return->copies[$matches[1]] = $matches[2];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -48,7 +48,9 @@ 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,
|
||||||
|
'default' => null,
|
||||||
'verbose' => __('project'),
|
'verbose' => __('project'),
|
||||||
),
|
),
|
||||||
'class' =>
|
'class' =>
|
||||||
@@ -76,13 +78,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 +149,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 +157,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;
|
||||||
}
|
}
|
||||||
|
@@ -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()));
|
||||||
}
|
}
|
||||||
|
@@ -85,7 +85,7 @@ class IDF_Views
|
|||||||
|
|
||||||
$projects = self::getProjects($request->user, $tag, $order);
|
$projects = self::getProjects($request->user, $tag, $order);
|
||||||
$stats = self::getProjectsStatistics($projects);
|
$stats = self::getProjectsStatistics($projects);
|
||||||
$projectLabels = IDF_Forge::instance()->getProjectLabelsWithCounts();
|
$projectLabels = self::getProjectLabelsWithCounts($request->user);
|
||||||
|
|
||||||
return Pluf_Shortcuts_RenderToResponse('idf/listProjects.html',
|
return Pluf_Shortcuts_RenderToResponse('idf/listProjects.html',
|
||||||
array('page_title' => __('Projects'),
|
array('page_title' => __('Projects'),
|
||||||
@@ -371,6 +371,62 @@ class IDF_Views
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of ids of projects that are visible for the given user
|
||||||
|
*
|
||||||
|
* @param Pluf_User $user
|
||||||
|
*/
|
||||||
|
private static function getUserVisibleProjectIds($user)
|
||||||
|
{
|
||||||
|
$db =& Pluf::db();
|
||||||
|
// the administrator can see all projects
|
||||||
|
if ($user->administrator) {
|
||||||
|
$ids = array();
|
||||||
|
$sql_results = $db->select(
|
||||||
|
'SELECT id FROM '.Pluf::f('db_table_prefix', '').'idf_projects'
|
||||||
|
);
|
||||||
|
foreach ($sql_results as $id) {
|
||||||
|
$ids[] = $id['id'];
|
||||||
|
}
|
||||||
|
return $ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
// anonymous users can only see non-private projects
|
||||||
|
$false = Pluf_DB_BooleanToDb(false, $db);
|
||||||
|
$sql_results = $db->select(
|
||||||
|
'SELECT id FROM '.$db->pfx.'idf_projects '.
|
||||||
|
'WHERE '.$db->qn('private').'='.$false
|
||||||
|
);
|
||||||
|
|
||||||
|
$ids = array();
|
||||||
|
foreach ($sql_results as $id) {
|
||||||
|
$ids[] = $id['id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// registered users may additionally see private projects with which
|
||||||
|
// they're somehow affiliated
|
||||||
|
if (!$user->isAnonymous()) {
|
||||||
|
$perms = array(
|
||||||
|
Pluf_Permission::getFromString('IDF.project-member'),
|
||||||
|
Pluf_Permission::getFromString('IDF.project-owner'),
|
||||||
|
Pluf_Permission::getFromString('IDF.project-authorized-user')
|
||||||
|
);
|
||||||
|
$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()));
|
||||||
|
if ($rows->count() > 0) {
|
||||||
|
foreach ($rows as $row) {
|
||||||
|
if (in_array($row->model_id, $ids))
|
||||||
|
continue;
|
||||||
|
$ids[] = $row->model_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $ids;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of projects accessible for the user and optionally filtered by tag.
|
* Returns a list of projects accessible for the user and optionally filtered by tag.
|
||||||
*
|
*
|
||||||
@@ -381,39 +437,18 @@ class IDF_Views
|
|||||||
public static function getProjects($user, $tag = false, $order = 'name')
|
public static function getProjects($user, $tag = false, $order = 'name')
|
||||||
{
|
{
|
||||||
$db =& Pluf::db();
|
$db =& Pluf::db();
|
||||||
$false = Pluf_DB_BooleanToDb(false, $db);
|
$sql = new Pluf_SQL('1=1');
|
||||||
$sql = new Pluf_SQL(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())
|
$projectIds = self::getUserVisibleProjectIds($user);
|
||||||
{
|
if (count($projectIds) == 0) {
|
||||||
$authSql = new Pluf_SQL('private=%s', $false);
|
return new ArrayObject();
|
||||||
$sql->SAnd($authSql);
|
|
||||||
} else
|
|
||||||
if (!$user->administrator) {
|
|
||||||
// grab the list of projects where the user is admin,
|
|
||||||
// member or authorized
|
|
||||||
$perms = array(
|
|
||||||
Pluf_Permission::getFromString('IDF.project-member'),
|
|
||||||
Pluf_Permission::getFromString('IDF.project-owner'),
|
|
||||||
Pluf_Permission::getFromString('IDF.project-authorized-user')
|
|
||||||
);
|
|
||||||
$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()));
|
|
||||||
|
|
||||||
$authSql = new Pluf_SQL('private=%s', $false);
|
|
||||||
if ($rows->count() > 0) {
|
|
||||||
$ids = array();
|
|
||||||
foreach ($rows as $row) {
|
|
||||||
$ids[] = $row->model_id;
|
|
||||||
}
|
|
||||||
$authSql->SOr(new Pluf_SQL(sprintf($db->pfx.'idf_projects.id IN (%s)', implode(', ', $ids))));
|
|
||||||
}
|
|
||||||
$sql->SAnd($authSql);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$sql->SAnd(new Pluf_SQL(sprintf($db->pfx.'idf_projects.id IN (%s)', implode(', ', $projectIds))));
|
||||||
|
|
||||||
$orderTypes = array(
|
$orderTypes = array(
|
||||||
'name' => 'name ASC',
|
'name' => 'name ASC',
|
||||||
'activity' => 'value DESC, name ASC',
|
'activity' => 'value DESC, name ASC',
|
||||||
@@ -425,6 +460,48 @@ class IDF_Views
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of global tags each carrying the number of projects that have the
|
||||||
|
* particular tag set
|
||||||
|
*
|
||||||
|
* @param Pluf_User $user
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getProjectLabelsWithCounts($user) {
|
||||||
|
|
||||||
|
$sql = new Pluf_SQL('project IS NULL');
|
||||||
|
|
||||||
|
$projectIds = self::getUserVisibleProjectIds($user);
|
||||||
|
if (count($projectIds) == 0) {
|
||||||
|
return new ArrayObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql->SAnd(new Pluf_SQL(sprintf('idf_project_id IN (%s)', implode(', ', $projectIds))));
|
||||||
|
|
||||||
|
$tagList = Pluf::factory('IDF_Tag')->getList(array(
|
||||||
|
'filter' => $sql->gen(),
|
||||||
|
'view' => 'join_projects',
|
||||||
|
'order' => 'class ASC, lcname ASC'
|
||||||
|
));
|
||||||
|
|
||||||
|
$maxProjectCount = 0;
|
||||||
|
foreach ($tagList as $tag) {
|
||||||
|
$maxProjectCount = max($maxProjectCount, $tag->project_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
$tags = array();
|
||||||
|
foreach ($tagList as $tag) {
|
||||||
|
// group by class
|
||||||
|
if (!array_key_exists($tag->class, $tags)) {
|
||||||
|
$tags[$tag->class] = array();
|
||||||
|
}
|
||||||
|
$tag->rel_project_count = $tag->project_count / (double) $maxProjectCount;
|
||||||
|
$tags[$tag->class][] = $tag;
|
||||||
|
}
|
||||||
|
return $tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns statistics on a list of projects.
|
* Returns statistics on a list of projects.
|
||||||
*
|
*
|
||||||
@@ -433,27 +510,30 @@ class IDF_Views
|
|||||||
*/
|
*/
|
||||||
public static function getProjectsStatistics($projects)
|
public static function getProjectsStatistics($projects)
|
||||||
{
|
{
|
||||||
// Init the return var
|
$projectIds = array(0);
|
||||||
$forgestats = array('downloads' => 0,
|
foreach ($projects as $project) {
|
||||||
'reviews' => 0,
|
$projectIds[] = $project->id;
|
||||||
'issues' => 0,
|
|
||||||
'docpages' => 0,
|
|
||||||
'commits' => 0);
|
|
||||||
|
|
||||||
// Count for each projects
|
|
||||||
foreach ($projects as $p) {
|
|
||||||
$pstats = $p->getStats();
|
|
||||||
$forgestats['downloads'] += $pstats['downloads'];
|
|
||||||
$forgestats['reviews'] += $pstats['reviews'];
|
|
||||||
$forgestats['issues'] += $pstats['issues'];
|
|
||||||
$forgestats['docpages'] += $pstats['docpages'];
|
|
||||||
$forgestats['commits'] += $pstats['commits'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Count members
|
$forgestats = array();
|
||||||
$sql = new Pluf_SQL('first_name != %s', array('---'));
|
|
||||||
$forgestats['members'] = Pluf::factory('Pluf_User')
|
// count overall project stats
|
||||||
->getCount(array('filter' => $sql->gen()));
|
$forgestats['total'] = 0;
|
||||||
|
$what = array(
|
||||||
|
'downloads' => 'IDF_Upload',
|
||||||
|
'reviews' => 'IDF_Review',
|
||||||
|
'issues' => 'IDF_Issue',
|
||||||
|
'docpages' => 'IDF_Wiki_Page',
|
||||||
|
'commits' => 'IDF_Commit',
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($what as $key => $model) {
|
||||||
|
$count = Pluf::factory($model)->getCount(array(
|
||||||
|
'filter' => sprintf('project IN (%s)', implode(', ', $projectIds))
|
||||||
|
));
|
||||||
|
$forgestats[$key] = $count;
|
||||||
|
$forgestats['total'] += $count;
|
||||||
|
}
|
||||||
|
|
||||||
return $forgestats;
|
return $forgestats;
|
||||||
}
|
}
|
||||||
|
@@ -167,7 +167,7 @@ class IDF_Wiki_PageRevision extends Pluf_Model
|
|||||||
if (count($matches) > 1 && count($matches[1]) > 0) {
|
if (count($matches) > 1 && count($matches[1]) > 0) {
|
||||||
foreach ($matches[1] as $resourceName) {
|
foreach ($matches[1] as $resourceName) {
|
||||||
$sql = new Pluf_SQL('project=%s AND title=%s',
|
$sql = new Pluf_SQL('project=%s AND title=%s',
|
||||||
array($prj->id, $resourceName));
|
array($page->get_project()->id, $resourceName));
|
||||||
$resources = Pluf::factory('IDF_Wiki_Resource')->getList(array('filter'=>$sql->gen()));
|
$resources = Pluf::factory('IDF_Wiki_Resource')->getList(array('filter'=>$sql->gen()));
|
||||||
if ($resources->count() == 0)
|
if ($resources->count() == 0)
|
||||||
continue;
|
continue;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -48,7 +48,6 @@
|
|||||||
|
|
||||||
<strong>{trans 'Filtered project stats'}</strong>
|
<strong>{trans 'Filtered project stats'}</strong>
|
||||||
<dl class="statistics smaller">
|
<dl class="statistics smaller">
|
||||||
<dt>{trans 'Members:'}</dt><dd>{$stats.members}</dd>
|
|
||||||
<dt>{trans 'Issues:'}</dt><dd>{$stats.issues}</dd>
|
<dt>{trans 'Issues:'}</dt><dd>{$stats.issues}</dd>
|
||||||
<dt>{trans 'Commits:'}</dt><dd>{$stats.commits}</dd>
|
<dt>{trans 'Commits:'}</dt><dd>{$stats.commits}</dd>
|
||||||
<dt>{trans 'Documentations:'}</dt><dd>{$stats.docpages}</dd>
|
<dt>{trans 'Documentations:'}</dt><dd>{$stats.docpages}</dd>
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
return array(
|
return array(
|
||||||
'version' => '1.3-dev',
|
'version' => '1.3.4-dev',
|
||||||
'revision' => '$Format:%H$',
|
'revision' => '$Format:%H$',
|
||||||
);
|
);
|
||||||
|
@@ -80,7 +80,6 @@
|
|||||||
0 => '',
|
0 => '',
|
||||||
1 => 11,
|
1 => 11,
|
||||||
2 => '
|
2 => '
|
||||||
|
|
||||||
',
|
',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@@ -44,7 +44,7 @@
|
|||||||
|
|
||||||
handleObj.handler = function( event ) {
|
handleObj.handler = function( event ) {
|
||||||
// Don't fire in text-accepting inputs that we didn't directly bind to
|
// Don't fire in text-accepting inputs that we didn't directly bind to
|
||||||
if ( this !== event.target && (/textarea|select/i.test( event.target.nodeName ) ||
|
if ( this !== event.target && (/textarea|select|input/i.test( event.target.nodeName ) ||
|
||||||
event.target.type === "text" || $(event.target).prop('contenteditable') == 'true' )) {
|
event.target.type === "text" || $(event.target).prop('contenteditable') == 'true' )) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,12 @@
|
|||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$(":header", "#wiki-content").map(function(index) {
|
$(":header", "#wiki-content").map(function(index) {
|
||||||
this.id = "wikititle_" + index;
|
var $header = $(this);
|
||||||
$("<a href='#" + this.id + "'>" + jQuery.fn.text([this]) + "</a>")
|
var $toc = $('#wiki-toc-content');
|
||||||
.addClass("wiki-" + this.tagName.toLowerCase())
|
$header.attr('id', 'wikititle_' + index);
|
||||||
.appendTo('#wiki-toc-content');
|
$('<a />').attr('href', '#' + $header.attr('id'))
|
||||||
|
.text($header.text())
|
||||||
|
.addClass("wiki-" + $header[0].tagName.toLowerCase())
|
||||||
|
.appendTo($toc);
|
||||||
});
|
});
|
||||||
if ($('#wiki-toc-content *').size() < 2)
|
if ($('#wiki-toc-content *').size() < 2)
|
||||||
$('#wiki-toc').hide();
|
$('#wiki-toc').hide();
|
||||||
|
Reference in New Issue
Block a user