summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog1
-rw-r--r--app/Api/Procedure/ProjectProcedure.php7
-rw-r--r--app/Helper/AppHelper.php5
-rw-r--r--app/Locale/bs_BA/translations.php2
-rw-r--r--app/Locale/cs_CZ/translations.php2
-rw-r--r--app/Locale/da_DK/translations.php2
-rw-r--r--app/Locale/de_DE/translations.php2
-rw-r--r--app/Locale/el_GR/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.php4
-rw-r--r--app/Locale/hu_HU/translations.php2
-rw-r--r--app/Locale/id_ID/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/ko_KR/translations.php2
-rw-r--r--app/Locale/my_MY/translations.php2
-rw-r--r--app/Locale/nb_NO/translations.php2
-rw-r--r--app/Locale/nl_NL/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/pt_PT/translations.php2
-rw-r--r--app/Locale/ru_RU/translations.php2
-rw-r--r--app/Locale/sr_Latn_RS/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/tr_TR/translations.php2
-rw-r--r--app/Locale/zh_CN/translations.php2
-rw-r--r--app/Model/ProjectModel.php16
-rw-r--r--app/Schema/Mysql.php7
-rw-r--r--app/Schema/Postgres.php7
-rw-r--r--app/Schema/Sqlite.php7
-rw-r--r--app/Template/project_edit/show.php20
-rw-r--r--app/Validator/ProjectValidator.php2
-rw-r--r--doc/en_US/api-project-procedures.markdown50
-rw-r--r--tests/units/Model/ProjectModelTest.php33
36 files changed, 198 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index f2c1a80b..9b36d5f9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,7 @@ Version 1.0.39 (unreleased)
Improvements:
+* Add email address field for projects
* Improve forget password behaviour (notify the user that an email has been sent or not)
* Do not display current project in board selector
* Do not set default task assignee for team projects
diff --git a/app/Api/Procedure/ProjectProcedure.php b/app/Api/Procedure/ProjectProcedure.php
index a580c8d9..e8a34cd3 100644
--- a/app/Api/Procedure/ProjectProcedure.php
+++ b/app/Api/Procedure/ProjectProcedure.php
@@ -32,6 +32,13 @@ class ProjectProcedure extends BaseProcedure
return $this->formatProject($project);
}
+ public function getProjectByEmail($email)
+ {
+ $project = $this->formatProject($this->projectModel->getByEmail($email));
+ ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getProjectByEmail', $project['id']);
+ return $this->formatProject($project);
+ }
+
public function getAllProjects()
{
return $this->formatProjects($this->projectModel->getAll());
diff --git a/app/Helper/AppHelper.php b/app/Helper/AppHelper.php
index 3b48d7d3..3cefd1c5 100644
--- a/app/Helper/AppHelper.php
+++ b/app/Helper/AppHelper.php
@@ -12,6 +12,11 @@ use Kanboard\Core\Base;
*/
class AppHelper extends Base
{
+ public function isAjax()
+ {
+ return $this->request->isAjax();
+ }
+
/**
* Render Javascript component
*
diff --git a/app/Locale/bs_BA/translations.php b/app/Locale/bs_BA/translations.php
index 3174d450..9dfe2a3e 100644
--- a/app/Locale/bs_BA/translations.php
+++ b/app/Locale/bs_BA/translations.php
@@ -1311,4 +1311,6 @@ return array(
// 'Your profile must have a valid email address.' => '',
// 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
// 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
);
diff --git a/app/Locale/cs_CZ/translations.php b/app/Locale/cs_CZ/translations.php
index e152db9f..8ab5aa7f 100644
--- a/app/Locale/cs_CZ/translations.php
+++ b/app/Locale/cs_CZ/translations.php
@@ -1311,4 +1311,6 @@ return array(
// 'Your profile must have a valid email address.' => '',
// 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
// 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
);
diff --git a/app/Locale/da_DK/translations.php b/app/Locale/da_DK/translations.php
index a38a20d7..eeb02e1d 100644
--- a/app/Locale/da_DK/translations.php
+++ b/app/Locale/da_DK/translations.php
@@ -1311,4 +1311,6 @@ return array(
// 'Your profile must have a valid email address.' => '',
// 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
// 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
);
diff --git a/app/Locale/de_DE/translations.php b/app/Locale/de_DE/translations.php
index 13cdf6bf..9d1ff3bf 100644
--- a/app/Locale/de_DE/translations.php
+++ b/app/Locale/de_DE/translations.php
@@ -1311,4 +1311,6 @@ return array(
// 'Your profile must have a valid email address.' => '',
// 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
// 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
);
diff --git a/app/Locale/el_GR/translations.php b/app/Locale/el_GR/translations.php
index c2760407..a4750705 100644
--- a/app/Locale/el_GR/translations.php
+++ b/app/Locale/el_GR/translations.php
@@ -1311,4 +1311,6 @@ return array(
// 'Your profile must have a valid email address.' => '',
// 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
// 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
);
diff --git a/app/Locale/es_ES/translations.php b/app/Locale/es_ES/translations.php
index 3fa4c3a8..f84f1db1 100644
--- a/app/Locale/es_ES/translations.php
+++ b/app/Locale/es_ES/translations.php
@@ -1311,4 +1311,6 @@ return array(
// 'Your profile must have a valid email address.' => '',
// 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
// 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
);
diff --git a/app/Locale/fi_FI/translations.php b/app/Locale/fi_FI/translations.php
index f37abc55..40fddda4 100644
--- a/app/Locale/fi_FI/translations.php
+++ b/app/Locale/fi_FI/translations.php
@@ -1311,4 +1311,6 @@ return array(
// 'Your profile must have a valid email address.' => '',
// 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
// 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
);
diff --git a/app/Locale/fr_FR/translations.php b/app/Locale/fr_FR/translations.php
index ce2e8a46..54df0379 100644
--- a/app/Locale/fr_FR/translations.php
+++ b/app/Locale/fr_FR/translations.php
@@ -961,7 +961,7 @@ return array(
'Do you really want to close all tasks of this column?' => 'Voulez-vous vraiment fermer toutes les tâches de cette colonne ?',
'%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '%d tâche(s) dans la colonne « %s » et la swimlane « %s » seront fermées.',
'Close all tasks of this column' => 'Fermer toutes les tâches de cette colonne',
- 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => 'Aucun plugin n\'a enregistré une méthode de notification de projet. Vous pouvez toujours configurer les notifications individuelles dans votre profil d\'utilisateur.',
+ 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => 'Aucun plugin n\'a enregistré une méthode de notification de projet. Vous pouvez toujours configurer les notifications individuelles dans votre profil utilisateur.',
'My dashboard' => 'Mon tableau de bord',
'My profile' => 'Mon profil',
'Project owner: ' => 'Responsable du projet : ',
@@ -1311,4 +1311,6 @@ return array(
'Your profile must have a valid email address.' => 'Votre profil doit avoir une adresse e-mail valide.',
'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => 'Malheureusement, nous ne pouvons pas réinitialiser votre mot de passe. Avez-vous saisi un nom d\'utilisateur valide ? Avez-vous une adresse e-mail dans votre profil ?',
'TRL - Turkish Lira' => 'TRL - Livre turque',
+ 'The project email is optional and could be used by several plugins.' => 'L\'adresse email d\'un projet est optionnel et pourrait être utilisé par plusieurs extensions.',
+ 'The email project must be unique across all projects' => 'L\'adresse email d\'un projet doit être unique pour tous les projets',
);
diff --git a/app/Locale/hu_HU/translations.php b/app/Locale/hu_HU/translations.php
index 57bea247..2ad209a7 100644
--- a/app/Locale/hu_HU/translations.php
+++ b/app/Locale/hu_HU/translations.php
@@ -1311,4 +1311,6 @@ return array(
// 'Your profile must have a valid email address.' => '',
// 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
// 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
);
diff --git a/app/Locale/id_ID/translations.php b/app/Locale/id_ID/translations.php
index 4c2bab4f..938c6bd7 100644
--- a/app/Locale/id_ID/translations.php
+++ b/app/Locale/id_ID/translations.php
@@ -1311,4 +1311,6 @@ return array(
// 'Your profile must have a valid email address.' => '',
// 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
// 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
);
diff --git a/app/Locale/it_IT/translations.php b/app/Locale/it_IT/translations.php
index 8a73ceeb..6d4ceaf9 100644
--- a/app/Locale/it_IT/translations.php
+++ b/app/Locale/it_IT/translations.php
@@ -1311,4 +1311,6 @@ return array(
// 'Your profile must have a valid email address.' => '',
// 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
// 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
);
diff --git a/app/Locale/ja_JP/translations.php b/app/Locale/ja_JP/translations.php
index 8ce0c9fa..1c69d809 100644
--- a/app/Locale/ja_JP/translations.php
+++ b/app/Locale/ja_JP/translations.php
@@ -1311,4 +1311,6 @@ return array(
// 'Your profile must have a valid email address.' => '',
// 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
// 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
);
diff --git a/app/Locale/ko_KR/translations.php b/app/Locale/ko_KR/translations.php
index b3fe859e..1bf45633 100644
--- a/app/Locale/ko_KR/translations.php
+++ b/app/Locale/ko_KR/translations.php
@@ -1311,4 +1311,6 @@ return array(
// 'Your profile must have a valid email address.' => '',
// 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
// 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
);
diff --git a/app/Locale/my_MY/translations.php b/app/Locale/my_MY/translations.php
index 0d694782..588829d2 100644
--- a/app/Locale/my_MY/translations.php
+++ b/app/Locale/my_MY/translations.php
@@ -1311,4 +1311,6 @@ return array(
// 'Your profile must have a valid email address.' => '',
// 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
// 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
);
diff --git a/app/Locale/nb_NO/translations.php b/app/Locale/nb_NO/translations.php
index 7f563358..04d7c718 100644
--- a/app/Locale/nb_NO/translations.php
+++ b/app/Locale/nb_NO/translations.php
@@ -1311,4 +1311,6 @@ return array(
// 'Your profile must have a valid email address.' => '',
// 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
// 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
);
diff --git a/app/Locale/nl_NL/translations.php b/app/Locale/nl_NL/translations.php
index 37427071..3bc9e51d 100644
--- a/app/Locale/nl_NL/translations.php
+++ b/app/Locale/nl_NL/translations.php
@@ -1311,4 +1311,6 @@ return array(
// 'Your profile must have a valid email address.' => '',
// 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
// 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
);
diff --git a/app/Locale/pl_PL/translations.php b/app/Locale/pl_PL/translations.php
index a3b0018d..fdca3f07 100644
--- a/app/Locale/pl_PL/translations.php
+++ b/app/Locale/pl_PL/translations.php
@@ -1311,4 +1311,6 @@ return array(
// 'Your profile must have a valid email address.' => '',
// 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
// 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
);
diff --git a/app/Locale/pt_BR/translations.php b/app/Locale/pt_BR/translations.php
index 0de6ab2b..e709bb4a 100644
--- a/app/Locale/pt_BR/translations.php
+++ b/app/Locale/pt_BR/translations.php
@@ -1311,4 +1311,6 @@ return array(
// 'Your profile must have a valid email address.' => '',
// 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
// 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
);
diff --git a/app/Locale/pt_PT/translations.php b/app/Locale/pt_PT/translations.php
index 6bf04605..b70d97d9 100644
--- a/app/Locale/pt_PT/translations.php
+++ b/app/Locale/pt_PT/translations.php
@@ -1311,4 +1311,6 @@ return array(
'Your profile must have a valid email address.' => 'O seu perfil deve ter um endereço de email válido.',
'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => 'Infelizmente, não conseguimos redefinir a sua password. Colocou um utilizador válido? Tem um endereço de email definido no seu perfil?',
'TRL - Turkish Lira' => 'TRL - Lira Turca',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
);
diff --git a/app/Locale/ru_RU/translations.php b/app/Locale/ru_RU/translations.php
index d9b9d4d2..680340b1 100644
--- a/app/Locale/ru_RU/translations.php
+++ b/app/Locale/ru_RU/translations.php
@@ -1311,4 +1311,6 @@ return array(
// 'Your profile must have a valid email address.' => '',
// 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
// 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
);
diff --git a/app/Locale/sr_Latn_RS/translations.php b/app/Locale/sr_Latn_RS/translations.php
index 2f22774e..75678bca 100644
--- a/app/Locale/sr_Latn_RS/translations.php
+++ b/app/Locale/sr_Latn_RS/translations.php
@@ -1311,4 +1311,6 @@ return array(
// 'Your profile must have a valid email address.' => '',
// 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
// 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
);
diff --git a/app/Locale/sv_SE/translations.php b/app/Locale/sv_SE/translations.php
index 17e60c03..3f901a09 100644
--- a/app/Locale/sv_SE/translations.php
+++ b/app/Locale/sv_SE/translations.php
@@ -1311,4 +1311,6 @@ return array(
// 'Your profile must have a valid email address.' => '',
// 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
// 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
);
diff --git a/app/Locale/th_TH/translations.php b/app/Locale/th_TH/translations.php
index f8ecd0d2..26497b0a 100644
--- a/app/Locale/th_TH/translations.php
+++ b/app/Locale/th_TH/translations.php
@@ -1311,4 +1311,6 @@ return array(
// 'Your profile must have a valid email address.' => '',
// 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
// 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
);
diff --git a/app/Locale/tr_TR/translations.php b/app/Locale/tr_TR/translations.php
index 7c8a7453..c3947fed 100644
--- a/app/Locale/tr_TR/translations.php
+++ b/app/Locale/tr_TR/translations.php
@@ -1311,4 +1311,6 @@ return array(
// 'Your profile must have a valid email address.' => '',
// 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
// 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
);
diff --git a/app/Locale/zh_CN/translations.php b/app/Locale/zh_CN/translations.php
index 76c51a62..5f45188b 100644
--- a/app/Locale/zh_CN/translations.php
+++ b/app/Locale/zh_CN/translations.php
@@ -1311,4 +1311,6 @@ return array(
// 'Your profile must have a valid email address.' => '',
// 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
// 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
);
diff --git a/app/Model/ProjectModel.php b/app/Model/ProjectModel.php
index aba5eee2..080217cb 100644
--- a/app/Model/ProjectModel.php
+++ b/app/Model/ProjectModel.php
@@ -106,6 +106,22 @@ class ProjectModel extends Base
}
/**
+ * Get a project by the email address
+ *
+ * @access public
+ * @param string $email
+ * @return array|boolean
+ */
+ public function getByEmail($email)
+ {
+ if (empty($email)) {
+ return false;
+ }
+
+ return $this->db->table(self::TABLE)->eq('email', $email)->findOne();
+ }
+
+ /**
* Fetch project data by using the token
*
* @access public
diff --git a/app/Schema/Mysql.php b/app/Schema/Mysql.php
index 7771440e..ca9f45ad 100644
--- a/app/Schema/Mysql.php
+++ b/app/Schema/Mysql.php
@@ -6,7 +6,12 @@ use PDO;
use Kanboard\Core\Security\Token;
use Kanboard\Core\Security\Role;
-const VERSION = 120;
+const VERSION = 121;
+
+function version_121(PDO $pdo)
+{
+ $pdo->exec('ALTER TABLE projects ADD COLUMN email VARCHAR(255)');
+}
function version_120(PDO $pdo)
{
diff --git a/app/Schema/Postgres.php b/app/Schema/Postgres.php
index 8054340c..cbea908f 100644
--- a/app/Schema/Postgres.php
+++ b/app/Schema/Postgres.php
@@ -6,7 +6,12 @@ use PDO;
use Kanboard\Core\Security\Token;
use Kanboard\Core\Security\Role;
-const VERSION = 99;
+const VERSION = 100;
+
+function version_100(PDO $pdo)
+{
+ $pdo->exec('ALTER TABLE "projects" ADD COLUMN email VARCHAR(255)');
+}
function version_99(PDO $pdo)
{
diff --git a/app/Schema/Sqlite.php b/app/Schema/Sqlite.php
index 87630b1a..a68ed418 100644
--- a/app/Schema/Sqlite.php
+++ b/app/Schema/Sqlite.php
@@ -6,7 +6,12 @@ use Kanboard\Core\Security\Token;
use Kanboard\Core\Security\Role;
use PDO;
-const VERSION = 110;
+const VERSION = 111;
+
+function version_111(PDO $pdo)
+{
+ $pdo->exec('ALTER TABLE "projects" ADD COLUMN email TEXT');
+}
function version_110(PDO $pdo)
{
diff --git a/app/Template/project_edit/show.php b/app/Template/project_edit/show.php
index 46cdb8fa..074f1d37 100644
--- a/app/Template/project_edit/show.php
+++ b/app/Template/project_edit/show.php
@@ -1,6 +1,12 @@
-<div class="page-header">
- <h2><?= $this->text->e($project['name']) ?> &gt; <?= t('Edit project') ?></h2>
-</div>
+<?php if ($this->app->isAjax()): ?>
+ <div class="page-header">
+ <h2><?= $this->text->e($project['name']) ?> &gt; <?= t('Edit project') ?></h2>
+ </div>
+<?php else: ?>
+ <div class="page-header">
+ <h2><?= t('Edit project') ?></h2>
+ </div>
+<?php endif ?>
<form method="post" action="<?= $this->url->href('ProjectEditController', 'update', array('project_id' => $project['id'], 'redirect' => 'edit')) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('id', $values) ?>
@@ -11,12 +17,16 @@
<?= $this->form->label(t('Name'), 'name') ?>
<?= $this->form->text('name', $values, $errors, array('required', 'maxlength="50"', 'autofocus', 'tabindex="1"')) ?>
+ <?= $this->form->label(t('Email'), 'email') ?>
+ <?= $this->form->email('email', $values, $errors, array('maxlength="255"', 'tabindex="2"')) ?>
+ <p class="form-help"><?= t('The project email is optional and could be used by several plugins.') ?></p>
+
<?= $this->form->label(t('Identifier'), 'identifier') ?>
- <?= $this->form->text('identifier', $values, $errors, array('maxlength="50"', 'tabindex="2"')) ?>
+ <?= $this->form->text('identifier', $values, $errors, array('maxlength="50"', 'tabindex="3"')) ?>
<p class="form-help"><?= t('The project identifier is optional and must be alphanumeric, example: MYPROJECT.') ?></p>
<?= $this->form->label(t('Description'), 'description') ?>
- <?= $this->form->textEditor('description', $values, $errors, array('tabindex' => 3)) ?>
+ <?= $this->form->textEditor('description', $values, $errors, array('tabindex' => 4)) ?>
</fieldset>
<fieldset>
diff --git a/app/Validator/ProjectValidator.php b/app/Validator/ProjectValidator.php
index 5b10026c..8d8053a3 100644
--- a/app/Validator/ProjectValidator.php
+++ b/app/Validator/ProjectValidator.php
@@ -34,6 +34,8 @@ class ProjectValidator extends BaseValidator
new Validators\MaxLength('end_date', t('The maximum length is %d characters', 10), 10),
new Validators\AlphaNumeric('identifier', t('This value must be alphanumeric')) ,
new Validators\Unique('identifier', t('The identifier must be unique'), $this->db->getConnection(), ProjectModel::TABLE),
+ new Validators\Email('email', t('Email address invalid')) ,
+ new Validators\Unique('email', t('The email project must be unique across all projects'), $this->db->getConnection(), ProjectModel::TABLE),
);
}
diff --git a/doc/en_US/api-project-procedures.markdown b/doc/en_US/api-project-procedures.markdown
index 09000e68..831c4b60 100644
--- a/doc/en_US/api-project-procedures.markdown
+++ b/doc/en_US/api-project-procedures.markdown
@@ -182,6 +182,56 @@ Response example:
}
```
+## getProjectByEmail
+
+- Purpose: **Get project information**
+- Parameters:
+ - **email** (string, required)
+- Result on success: **project properties**
+- Result on failure: **null**
+
+Request example:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "method": "getProjectByEmail",
+ "id": 1620253806,
+ "params": {
+ "email": "my_project@my_domain.tld"
+ }
+}
+```
+
+Response example:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "id": 1620253806,
+ "result": {
+ "id": "1",
+ "name": "Test",
+ "is_active": "1",
+ "token": "",
+ "last_modified": "1436119135",
+ "is_public": "0",
+ "is_private": "0",
+ "is_everybody_allowed": "0",
+ "default_swimlane": "Default swimlane",
+ "show_default_swimlane": "1",
+ "description": "test",
+ "identifier": "",
+ "email": "my_project@my_domain.tld",
+ "url": {
+ "board": "http:\/\/127.0.0.1:8000\/?controller=board&action=show&project_id=1",
+ "calendar": "http:\/\/127.0.0.1:8000\/?controller=calendar&action=show&project_id=1",
+ "list": "http:\/\/127.0.0.1:8000\/?controller=listing&action=show&project_id=1"
+ }
+ }
+}
+```
+
## getAllProjects
- Purpose: **Get all available projects**
diff --git a/tests/units/Model/ProjectModelTest.php b/tests/units/Model/ProjectModelTest.php
index cd86b654..1f65cad7 100644
--- a/tests/units/Model/ProjectModelTest.php
+++ b/tests/units/Model/ProjectModelTest.php
@@ -298,6 +298,39 @@ class ProjectModelTest extends Base
$this->assertFalse($project);
}
+ public function testEmail()
+ {
+ $projectModel = new ProjectModel($this->container);
+
+ // Creation
+ $this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest1', 'email' => 'test1@localhost')));
+ $this->assertEquals(2, $projectModel->create(array('name' => 'UnitTest2')));
+
+ $project = $projectModel->getById(1);
+ $this->assertNotEmpty($project);
+ $this->assertEquals('test1@localhost', $project['email']);
+
+ $project = $projectModel->getById(2);
+ $this->assertNotEmpty($project);
+ $this->assertEquals('', $project['email']);
+
+ // Update
+ $this->assertTrue($projectModel->update(array('id' => '1', 'email' => 'test1@here')));
+
+ $project = $projectModel->getById(1);
+ $this->assertNotEmpty($project);
+ $this->assertEquals('test1@here', $project['email']);
+
+ $project = $projectModel->getByEmail('test1@here');
+ $this->assertEquals(1, $project['id']);
+
+ $project = $projectModel->getByEmail('test1@localhost');
+ $this->assertEmpty($project);
+
+ $project = $projectModel->getByEmail('');
+ $this->assertFalse($project);
+ }
+
public function testThatProjectCreatorAreAlsoOwner()
{
$projectModel = new ProjectModel($this->container);