summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/Locale/da_DK/translations.php2
-rw-r--r--app/Locale/de_DE/translations.php2
-rw-r--r--app/Locale/es_ES/translations.php2
-rw-r--r--app/Locale/fi_FI/translations.php2
-rw-r--r--app/Locale/fr_FR/translations.php2
-rw-r--r--app/Locale/hu_HU/translations.php2
-rw-r--r--app/Locale/it_IT/translations.php2
-rw-r--r--app/Locale/ja_JP/translations.php2
-rw-r--r--app/Locale/pl_PL/translations.php2
-rw-r--r--app/Locale/pt_BR/translations.php2
-rw-r--r--app/Locale/ru_RU/translations.php2
-rw-r--r--app/Locale/sv_SE/translations.php2
-rw-r--r--app/Locale/th_TH/translations.php2
-rw-r--r--app/Locale/zh_CN/translations.php2
-rw-r--r--app/Model/Category.php25
-rw-r--r--app/Model/Project.php2
-rw-r--r--app/Schema/Mysql.php8
-rw-r--r--app/Schema/Postgres.php8
-rw-r--r--app/Schema/Sqlite.php8
-rw-r--r--app/Template/config/board.php4
-rw-r--r--tests/units/ConfigTest.php3
-rw-r--r--tests/units/ProjectTest.php60
22 files changed, 142 insertions, 4 deletions
diff --git a/app/Locale/da_DK/translations.php b/app/Locale/da_DK/translations.php
index 1636ccb2..b6227771 100644
--- a/app/Locale/da_DK/translations.php
+++ b/app/Locale/da_DK/translations.php
@@ -624,4 +624,6 @@ return array(
// 'Unable to remove this swimlane.' => '',
// 'Unable to update this swimlane.' => '',
// 'Your swimlane have been created successfully.' => '',
+ // 'Example: "Bug, Feature Request, Improvement"' => '',
+ // 'Default categories for new projects (Comma-separated)' => '',
);
diff --git a/app/Locale/de_DE/translations.php b/app/Locale/de_DE/translations.php
index 6e6301ec..f9d8e714 100644
--- a/app/Locale/de_DE/translations.php
+++ b/app/Locale/de_DE/translations.php
@@ -624,4 +624,6 @@ return array(
// 'Unable to remove this swimlane.' => '',
// 'Unable to update this swimlane.' => '',
// 'Your swimlane have been created successfully.' => '',
+ // 'Example: "Bug, Feature Request, Improvement"' => '',
+ // 'Default categories for new projects (Comma-separated)' => '',
);
diff --git a/app/Locale/es_ES/translations.php b/app/Locale/es_ES/translations.php
index 6e37eead..1f4a3d87 100644
--- a/app/Locale/es_ES/translations.php
+++ b/app/Locale/es_ES/translations.php
@@ -624,4 +624,6 @@ return array(
// 'Unable to remove this swimlane.' => '',
// 'Unable to update this swimlane.' => '',
// 'Your swimlane have been created successfully.' => '',
+ // 'Example: "Bug, Feature Request, Improvement"' => '',
+ // 'Default categories for new projects (Comma-separated)' => '',
);
diff --git a/app/Locale/fi_FI/translations.php b/app/Locale/fi_FI/translations.php
index 524bbee4..25cf67c3 100644
--- a/app/Locale/fi_FI/translations.php
+++ b/app/Locale/fi_FI/translations.php
@@ -624,4 +624,6 @@ return array(
// 'Unable to remove this swimlane.' => '',
// 'Unable to update this swimlane.' => '',
// 'Your swimlane have been created successfully.' => '',
+ // 'Example: "Bug, Feature Request, Improvement"' => '',
+ // 'Default categories for new projects (Comma-separated)' => '',
);
diff --git a/app/Locale/fr_FR/translations.php b/app/Locale/fr_FR/translations.php
index 9ae853bf..fb281f13 100644
--- a/app/Locale/fr_FR/translations.php
+++ b/app/Locale/fr_FR/translations.php
@@ -624,4 +624,6 @@ return array(
'Unable to remove this swimlane.' => 'Impossible de supprimer cette swimlane.',
'Unable to update this swimlane.' => 'Impossible de mettre à jour cette swimlane.',
'Your swimlane have been created successfully.' => 'Votre swimlane a été créée avec succès.',
+ 'Example: "Bug, Feature Request, Improvement"' => 'Exemple: « Incident, Demande de fonctionnalité, Amélioration »',
+ 'Default categories for new projects (Comma-separated)' => 'Catégories par défaut pour les nouveaux projets (séparé par des virgules)',
);
diff --git a/app/Locale/hu_HU/translations.php b/app/Locale/hu_HU/translations.php
index 352cd1ba..7188d197 100644
--- a/app/Locale/hu_HU/translations.php
+++ b/app/Locale/hu_HU/translations.php
@@ -624,4 +624,6 @@ return array(
// 'Unable to remove this swimlane.' => '',
// 'Unable to update this swimlane.' => '',
// 'Your swimlane have been created successfully.' => '',
+ // 'Example: "Bug, Feature Request, Improvement"' => '',
+ // 'Default categories for new projects (Comma-separated)' => '',
);
diff --git a/app/Locale/it_IT/translations.php b/app/Locale/it_IT/translations.php
index c07dd042..3117a068 100644
--- a/app/Locale/it_IT/translations.php
+++ b/app/Locale/it_IT/translations.php
@@ -624,4 +624,6 @@ return array(
// 'Unable to remove this swimlane.' => '',
// 'Unable to update this swimlane.' => '',
// 'Your swimlane have been created successfully.' => '',
+ // 'Example: "Bug, Feature Request, Improvement"' => '',
+ // 'Default categories for new projects (Comma-separated)' => '',
);
diff --git a/app/Locale/ja_JP/translations.php b/app/Locale/ja_JP/translations.php
index 3811243a..60ded536 100644
--- a/app/Locale/ja_JP/translations.php
+++ b/app/Locale/ja_JP/translations.php
@@ -624,4 +624,6 @@ return array(
// 'Unable to remove this swimlane.' => '',
// 'Unable to update this swimlane.' => '',
// 'Your swimlane have been created successfully.' => '',
+ // 'Example: "Bug, Feature Request, Improvement"' => '',
+ // 'Default categories for new projects (Comma-separated)' => '',
);
diff --git a/app/Locale/pl_PL/translations.php b/app/Locale/pl_PL/translations.php
index 2d1572a1..1c0492ed 100644
--- a/app/Locale/pl_PL/translations.php
+++ b/app/Locale/pl_PL/translations.php
@@ -624,4 +624,6 @@ return array(
// 'Unable to remove this swimlane.' => '',
// 'Unable to update this swimlane.' => '',
// 'Your swimlane have been created successfully.' => '',
+ // 'Example: "Bug, Feature Request, Improvement"' => '',
+ // 'Default categories for new projects (Comma-separated)' => '',
);
diff --git a/app/Locale/pt_BR/translations.php b/app/Locale/pt_BR/translations.php
index 5b9316b3..28858ec5 100644
--- a/app/Locale/pt_BR/translations.php
+++ b/app/Locale/pt_BR/translations.php
@@ -624,4 +624,6 @@ return array(
// 'Unable to remove this swimlane.' => '',
// 'Unable to update this swimlane.' => '',
// 'Your swimlane have been created successfully.' => '',
+ // 'Example: "Bug, Feature Request, Improvement"' => '',
+ // 'Default categories for new projects (Comma-separated)' => '',
);
diff --git a/app/Locale/ru_RU/translations.php b/app/Locale/ru_RU/translations.php
index 457c803d..5d58ca25 100644
--- a/app/Locale/ru_RU/translations.php
+++ b/app/Locale/ru_RU/translations.php
@@ -624,4 +624,6 @@ return array(
// 'Unable to remove this swimlane.' => '',
// 'Unable to update this swimlane.' => '',
// 'Your swimlane have been created successfully.' => '',
+ // 'Example: "Bug, Feature Request, Improvement"' => '',
+ // 'Default categories for new projects (Comma-separated)' => '',
);
diff --git a/app/Locale/sv_SE/translations.php b/app/Locale/sv_SE/translations.php
index 33e45341..cd0bb2bf 100644
--- a/app/Locale/sv_SE/translations.php
+++ b/app/Locale/sv_SE/translations.php
@@ -624,4 +624,6 @@ return array(
// 'Unable to remove this swimlane.' => '',
// 'Unable to update this swimlane.' => '',
// 'Your swimlane have been created successfully.' => '',
+ // 'Example: "Bug, Feature Request, Improvement"' => '',
+ // 'Default categories for new projects (Comma-separated)' => '',
);
diff --git a/app/Locale/th_TH/translations.php b/app/Locale/th_TH/translations.php
index 5f65f572..7331d877 100644
--- a/app/Locale/th_TH/translations.php
+++ b/app/Locale/th_TH/translations.php
@@ -624,4 +624,6 @@ return array(
// 'Unable to remove this swimlane.' => '',
// 'Unable to update this swimlane.' => '',
// 'Your swimlane have been created successfully.' => '',
+ // 'Example: "Bug, Feature Request, Improvement"' => '',
+ // 'Default categories for new projects (Comma-separated)' => '',
);
diff --git a/app/Locale/zh_CN/translations.php b/app/Locale/zh_CN/translations.php
index d610f8ee..455e37ed 100644
--- a/app/Locale/zh_CN/translations.php
+++ b/app/Locale/zh_CN/translations.php
@@ -624,4 +624,6 @@ return array(
'Unable to remove this swimlane.' => '无法删除此泳道',
'Unable to update this swimlane.' => '无法更新此泳道',
'Your swimlane have been created successfully.' => '已经成功创建泳道。',
+ // 'Example: "Bug, Feature Request, Improvement"' => '',
+ // 'Default categories for new projects (Comma-separated)' => '',
);
diff --git a/app/Model/Category.php b/app/Model/Category.php
index 54a0f552..cd60e7f7 100644
--- a/app/Model/Category.php
+++ b/app/Model/Category.php
@@ -118,7 +118,30 @@ class Category extends Base
}
/**
- * Create a category
+ * Create default cetegories during project creation (transaction already started in Project::create())
+ *
+ * @access public
+ * @param integer $project_id
+ */
+ public function createDefaultCategories($project_id)
+ {
+ $categories = explode(',', $this->config->get('project_categories'));
+
+ foreach ($categories as $category) {
+
+ $category = trim($category);
+
+ if (! empty($category)) {
+ $this->db->table(self::TABLE)->insert(array(
+ 'project_id' => $project_id,
+ 'name' => $category,
+ ));
+ }
+ }
+ }
+
+ /**
+ * Create a category (run inside a transaction)
*
* @access public
* @param array $values Form values
diff --git a/app/Model/Project.php b/app/Model/Project.php
index 9c0adee9..278fe6ab 100644
--- a/app/Model/Project.php
+++ b/app/Model/Project.php
@@ -298,6 +298,8 @@ class Project extends Base
$this->projectPermission->allowUser($project_id, $user_id);
}
+ $this->category->createDefaultCategories($project_id);
+
$this->db->closeTransaction();
return (int) $project_id;
diff --git a/app/Schema/Mysql.php b/app/Schema/Mysql.php
index 7fc8da6a..4d155f26 100644
--- a/app/Schema/Mysql.php
+++ b/app/Schema/Mysql.php
@@ -5,7 +5,13 @@ namespace Schema;
use PDO;
use Core\Security;
-const VERSION = 38;
+const VERSION = 39;
+
+function version_39($pdo)
+{
+ $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)');
+ $rq->execute(array('project_categories', ''));
+}
function version_38($pdo)
{
diff --git a/app/Schema/Postgres.php b/app/Schema/Postgres.php
index fd68d9c3..2d84a578 100644
--- a/app/Schema/Postgres.php
+++ b/app/Schema/Postgres.php
@@ -5,7 +5,13 @@ namespace Schema;
use PDO;
use Core\Security;
-const VERSION = 19;
+const VERSION = 20;
+
+function version_20($pdo)
+{
+ $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)');
+ $rq->execute(array('project_categories', ''));
+}
function version_19($pdo)
{
diff --git a/app/Schema/Sqlite.php b/app/Schema/Sqlite.php
index cd319241..39377a91 100644
--- a/app/Schema/Sqlite.php
+++ b/app/Schema/Sqlite.php
@@ -5,7 +5,13 @@ namespace Schema;
use Core\Security;
use PDO;
-const VERSION = 37;
+const VERSION = 38;
+
+function version_38($pdo)
+{
+ $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)');
+ $rq->execute(array('project_categories', ''));
+}
function version_37($pdo)
{
diff --git a/app/Template/config/board.php b/app/Template/config/board.php
index 3bd4ecbd..d7f8ee44 100644
--- a/app/Template/config/board.php
+++ b/app/Template/config/board.php
@@ -22,6 +22,10 @@
<?= $this->formText('board_columns', $values, $errors) ?><br/>
<p class="form-help"><?= t('Default values are "%s"', $default_columns) ?></p>
+ <?= $this->formLabel(t('Default categories for new projects (Comma-separated)'), 'project_categories') ?>
+ <?= $this->formText('project_categories', $values, $errors) ?><br/>
+ <p class="form-help"><?= t('Example: "Bug, Feature Request, Improvement"') ?></p>
+
<div class="form-actions">
<input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/>
</div>
diff --git a/tests/units/ConfigTest.php b/tests/units/ConfigTest.php
index 950d4a09..b630f284 100644
--- a/tests/units/ConfigTest.php
+++ b/tests/units/ConfigTest.php
@@ -51,5 +51,8 @@ class ConfigTest extends Base
$this->assertEquals('foo', $c->get('board_columns'));
$this->assertEquals('foo', $c->get('board_columns', 'test'));
$this->assertEquals('test', $c->get('empty_value', 'test'));
+
+ session_id('');
+ unset($this->container['session']);
}
}
diff --git a/tests/units/ProjectTest.php b/tests/units/ProjectTest.php
index 31481d96..38b742b3 100644
--- a/tests/units/ProjectTest.php
+++ b/tests/units/ProjectTest.php
@@ -10,6 +10,8 @@ use Model\Task;
use Model\TaskCreation;
use Model\Acl;
use Model\Board;
+use Model\Config;
+use Model\Category;
class ProjectTest extends Base
{
@@ -28,6 +30,64 @@ class ProjectTest extends Base
$this->assertEmpty($project['token']);
}
+ public function testCreationWithDefaultCategories()
+ {
+ $p = new Project($this->container);
+ $c = new Config($this->container);
+ $cat = new Category($this->container);
+
+ // Multiple categories correctly formatted
+
+ $this->assertTrue($c->save(array('project_categories' => 'Test1, Test2')));
+ $this->assertEquals(1, $p->create(array('name' => 'UnitTest1')));
+
+ $project = $p->getById(1);
+ $this->assertNotEmpty($project);
+
+ $categories = $cat->getAll(1);
+ $this->assertNotEmpty($categories);
+ $this->assertEquals(2, count($categories));
+ $this->assertEquals('Test1', $categories[0]['name']);
+ $this->assertEquals('Test2', $categories[1]['name']);
+
+ // Single category
+
+ $this->assertTrue($c->save(array('project_categories' => 'Test1')));
+ $this->assertEquals(2, $p->create(array('name' => 'UnitTest2')));
+
+ $project = $p->getById(2);
+ $this->assertNotEmpty($project);
+
+ $categories = $cat->getAll(2);
+ $this->assertNotEmpty($categories);
+ $this->assertEquals(1, count($categories));
+ $this->assertEquals('Test1', $categories[0]['name']);
+
+ // Multiple categories badly formatted
+
+ $this->assertTrue($c->save(array('project_categories' => 'ABC, , DEF 3, ')));
+ $this->assertEquals(3, $p->create(array('name' => 'UnitTest3')));
+
+ $project = $p->getById(3);
+ $this->assertNotEmpty($project);
+
+ $categories = $cat->getAll(3);
+ $this->assertNotEmpty($categories);
+ $this->assertEquals(2, count($categories));
+ $this->assertEquals('ABC', $categories[0]['name']);
+ $this->assertEquals('DEF 3', $categories[1]['name']);
+
+ // No default categories
+ $this->assertTrue($c->save(array('project_categories' => ' ')));
+ $this->assertEquals(4, $p->create(array('name' => 'UnitTest4')));
+
+ $project = $p->getById(4);
+ $this->assertNotEmpty($project);
+
+ $categories = $cat->getAll(4);
+ $this->assertEmpty($categories);
+ }
+
public function testUpdateLastModifiedDate()
{
$p = new Project($this->container);