Skip to content
This repository was archived by the owner on Jun 30, 2023. It is now read-only.

Commit 56a19c7

Browse files
Merge branch '1-project-invitation-to-new-user' into 'master'
Resolve "Project invitation to new User" See merge request ipunkt/officetools/kanboard/projectinvitation!1
2 parents cd083c9 + 684a55e commit 56a19c7

File tree

11 files changed

+318
-1
lines changed

11 files changed

+318
-1
lines changed

Diff for: Controller/ProjectInviteController.php

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
namespace Kanboard\Plugin\ProjectInvitation\Controller;
4+
5+
use Kanboard\Controller\BaseController;
6+
7+
/**
8+
* Class ProjectInviteController
9+
* @package Kanboard\Plugin\ProjectInvitation\Controller
10+
*/
11+
class ProjectInviteController extends BaseController
12+
{
13+
public function inviteUser()
14+
{
15+
$values = $this->request->getValues();
16+
$user = $this->userModel->getByEmail($values['email']);
17+
$url = 'project/' . $values['project_id'] . '/permissions';
18+
19+
if (! filter_var($values['email'], FILTER_VALIDATE_EMAIL)) {
20+
$this->flash->failure('Please enter a valid email.');
21+
return $this->response->redirect($url);
22+
}
23+
24+
$emails_number = substr_count($values['email'], '@');
25+
26+
if (!($emails_number > 1)) {
27+
if ($user['email'] !== $values['email']) {
28+
$this->inviteModel->createInvites(array($values['email']), $values['project_id']);
29+
$this->flash->success(t('Invitation to user has been sent successfully.'));
30+
} else {
31+
$this->flash->failure(t('User is already registered.'));
32+
}
33+
} else {
34+
$this->flash->failure(t('You can add only one email per one invitation.'));
35+
}
36+
37+
return $this->response->redirect($url);
38+
}
39+
}

Diff for: Data/config.php

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
// Mail transport available: "smtp", "sendmail", "mail" (PHP mail function), "postmark", "mailgun", "sendgrid"
3+
define('MAIL_TRANSPORT', 'smtp');
4+
5+
// SMTP configuration to use when the "smtp" transport is chosen
6+
define('MAIL_SMTP_HOSTNAME', 'mailhog');
7+
define('MAIL_SMTP_PORT', 1025);
8+
define('MAIL_SMTP_USERNAME', '');
9+
define('MAIL_SMTP_PASSWORD', '');
10+
define('MAIL_SMTP_ENCRYPTION', null); // Valid values are null (not a string "null"), "ssl" or "tls"

Diff for: LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2019 ipunkt Business Solutions
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Diff for: Locale/de_DE/translations.php

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
return array(
3+
'Plugin is used to invite new users to actual Project by typing user\'s email.' => 'Das Plugin wird verwendet, um neue Benutzer zum eigentlichen Projekt einzuladen, indem Sie die E-Mail-Adresse des Benutzers eingeben.',
4+
'Enter one email address per invite.' => 'Geben Sie nur eine E-Mail-Adresse pro Einladung ein.',
5+
'Enter user email...' => 'Geben Sie die Benutzer-E-Mail-Adresse ein',
6+
'Invite User' => 'Benutzer einladen',
7+
'Invite' => 'Einladen',
8+
'Invitation to user has been sent successfully.' => 'Einladung an Benutzer wurde erfolgreich gesendet',
9+
'User is already registered.' => 'Benutzer ist bereits registriert bzw. eingeladen',
10+
'You can add only one email per one invitation.' => 'Sie können nur eine E-Mail pro Einladung hinzufügen.',
11+
'Please enter a valid email address.' => 'Bitte geben Sie eine gültige E-Mail-Adresse ein',
12+
);

Diff for: Locale/ru_RU/translations.php

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
return array(
3+
'Plugin is used to invite new users to actual Project by typing user\'s email.' => 'Плагин используется для приглаешения нового пользователя в проект путём отсылки эл. почты.',
4+
'Enter one email address per invite.' => 'Введите один адрес эл. почты для одного приглашения.',
5+
'Enter user email...' => 'Введите эл. почту...',
6+
'Invite User' => 'Пригласить пользователя',
7+
'Invite' => 'Пригласить',
8+
'Invitation to user has been sent successfully.' => 'Приглашение пользователю успешно выслано.',
9+
'User is already registered.' => 'Пользователь уже зарегистрирован.',
10+
'You can add only one email per one invitation.' => 'Вы можете обавить только одного адресата.',
11+
'Please enter a valid email address.' => 'Пожалуйста, введите действительный адрес электронной почты.',
12+
);

Diff for: Plugin.php

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
namespace Kanboard\Plugin\ProjectInvitation;
4+
5+
use Kanboard\Core\Plugin\Base;
6+
use Kanboard\Core\Translator;
7+
8+
class Plugin extends Base
9+
{
10+
public function initialize()
11+
{
12+
13+
if (APP_VERSION < 'v1.2.11') {
14+
$this->template->setTemplateOverride('project_permission/users', 'ProjectInvitation:users-override');
15+
} else {
16+
$this->template->hook->attachCallable('template:project-permission:after-adduser',
17+
'ProjectInvitation:users',
18+
function ($project, $values, $errors) {
19+
$project_id = $this->request->getIntegerParam('project_id', $project['project_id']);
20+
return array(
21+
'project_id' => $project_id,
22+
'values' => $values,
23+
'errors' => $errors
24+
);
25+
});
26+
}
27+
}
28+
29+
public function getClasses()
30+
{
31+
return array(
32+
'Plugin\ProjectInvitation\Controller' => array(
33+
'ProjectInviteController',
34+
)
35+
);
36+
}
37+
38+
public function onStartup()
39+
{
40+
Translator::load($this->languageModel->getCurrentLanguage(), __DIR__ . '/Locale');
41+
}
42+
43+
public function getPluginName()
44+
{
45+
return 'ProjectInvitation';
46+
}
47+
48+
public function getPluginDescription()
49+
{
50+
return t("Plugin is used to invite new users to actual Project by typing user's email. Input for invitation is located in `Project Settings->Permissions`.");
51+
}
52+
53+
public function getPluginAuthor()
54+
{
55+
return 'Andrei Volgin / Hussein Khalil, ipunkt Business Solutions';
56+
}
57+
58+
public function getPluginVersion()
59+
{
60+
return '1.0.0';
61+
}
62+
63+
public function getPluginHomepage()
64+
{
65+
return 'https://www.ipunkt.biz/unternehmen/opensource';
66+
}
67+
}

Diff for: README.md

100644100755
+3-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
1-
# ProjectInvitation
1+
# Project invite a new User
22

3+
Plugin is used to invite new users to actual Project by typing user's email.
4+
Input for invitation is located in `Project Settings->Permissions`.

Diff for: Template/users-override.php

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php if (empty($users)): ?>
2+
<div class="alert"><?= t('No user have been allowed specifically.') ?></div>
3+
<?php else: ?>
4+
<table class="table-scrolling">
5+
<tr>
6+
<th class="column-50"><?= t('User') ?></th>
7+
<th><?= t('Role') ?></th>
8+
<?php if ($project['is_private'] == 0): ?>
9+
<th class="column-15"><?= t('Actions') ?></th>
10+
<?php endif ?>
11+
</tr>
12+
<?php foreach ($users as $user): ?>
13+
<tr>
14+
<td><?= $this->text->e($user['name'] ?: $user['username']) ?></td>
15+
<td>
16+
<?= $this->app->component('project-select-role', array(
17+
'roles' => $roles,
18+
'role' => $user['role'],
19+
'id' => $user['id'],
20+
'url' => $this->url->to('ProjectPermissionController', 'changeUserRole',
21+
array('project_id' => $project['id'])),
22+
)) ?>
23+
</td>
24+
<td>
25+
<?php if (!$this->user->isCurrentUser($user['id'])): ?>
26+
<?= $this->url->icon('trash-o', t('Remove'), 'ProjectPermissionController', 'removeUser',
27+
array('project_id' => $project['id'], 'user_id' => $user['id']), true) ?>
28+
<?php endif ?>
29+
</td>
30+
</tr>
31+
<?php endforeach ?>
32+
</table>
33+
<?php endif ?>
34+
35+
<?php if ($project['is_private'] == 0): ?>
36+
<div class="panel">
37+
<form method="post" action="<?= $this->url->href('ProjectPermissionController', 'addUser',
38+
array('project_id' => $project['id'])) ?>" autocomplete="off" class="form-inline">
39+
<?= $this->form->csrf() ?>
40+
<?= $this->form->hidden('project_id', array('project_id' => $project['id'])) ?>
41+
<?= $this->form->hidden('user_id', $values) ?>
42+
<?= $this->form->hidden('username', $values) ?>
43+
<?= $this->form->hidden('external_id', $values) ?>
44+
<?= $this->form->hidden('external_id_column', $values) ?>
45+
46+
<?= $this->form->label(t('Name'), 'name') ?>
47+
<?= $this->form->text('name', $values, $errors, array(
48+
'required',
49+
'placeholder="' . t('Enter user name...') . '"',
50+
'title="' . t('Enter user name...') . '"',
51+
'data-dst-field="user_id"',
52+
'data-dst-extra-fields="external_id,external_id_column,username"',
53+
'data-search-url="' . $this->url->href('UserAjaxController', 'autocomplete') . '"',
54+
),
55+
'autocomplete') ?>
56+
57+
<?= $this->form->select('role', $roles, $values, $errors) ?>
58+
59+
<button type="submit" class="btn btn-blue"><?= t('Add') ?></button>
60+
</form>
61+
</div>
62+
<!--User Invitation -->
63+
<div class="panel">
64+
<form method="post"
65+
action="<?= $this->url->href('ProjectInviteController', 'inviteUser',
66+
array('plugin' => 'ProjectInvitation', 'project_id' => $project['id'])) ?>"
67+
autocomplete="off" class="form-inline">
68+
<?= $this->form->csrf() ?>
69+
<?= $this->form->hidden('project_id', array('project_id' => $project['id'])) ?>
70+
<?= $this->form->label(t('Invite User'), 'invite_user') ?>
71+
<?= $this->form->text('email', $values, $errors, array(
72+
'required',
73+
'placeholder="' . t('Enter user email...') . '"',
74+
'title="' . t('Enter user email...') . '"'
75+
)) ?>
76+
<button type="submit" class="btn btn-blue"><?= t('Invite') ?></button>
77+
</form>
78+
<p class="form-help"><?= t('Enter one email address per invite.') ?></p>
79+
</div>
80+
<?php endif ?>

Diff for: Template/users.php

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!--User Invitation -->
2+
<div class="panel">
3+
<form method="post"
4+
action="<?= $this->url->href('ProjectInviteController', 'inviteUser',
5+
array('plugin' => 'ProjectInvitation', 'project_id' => $project_id)) ?>"
6+
autocomplete="off" class="form-inline">
7+
<?= $this->form->csrf() ?>
8+
<?= $this->form->hidden('project_id', array('project_id' => $project_id)) ?>
9+
<?= $this->form->label(t('Invite User'), 'invite_user') ?>
10+
<?= $this->form->email('email', $values, $errors, array(
11+
'required',
12+
'placeholder="' . t('Enter user email...') . '"',
13+
'title="' . t('Enter user email...') . '"'
14+
)) ?>
15+
<button type="submit" class="btn btn-blue"><?= t('Invite') ?></button>
16+
</form>
17+
<p class="form-help"><?= t('Enter one email address per invite.') ?></p>
18+
</div>

Diff for: docker-compose.yml

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
version: '2'
2+
services:
3+
kanboard:
4+
image: kanboard/kanboard:latest
5+
ports:
6+
- "80:80"
7+
volumes:
8+
- .:/var/www/app/plugins/ProjectInvitation
9+
- ./docker/conf.d/local.ini:/etc/php7/conf.d/local.ini
10+
- ./Data/config.php:/var/www/app/data/config.php
11+
environment:
12+
DATABASE_URL: mysql://kb:kb-secret@db/kanboard
13+
mailhog:
14+
image: mailhog/mailhog:latest
15+
ports:
16+
- 1025:1025
17+
- 8025:8025
18+
pma:
19+
image: phpmyadmin/phpmyadmin
20+
ports:
21+
- "8000:80"
22+
environment:
23+
PMA_HOST: db
24+
PMA_USER: kb
25+
PMA_PASSWORD: kb-secret
26+
db:
27+
image: mariadb:latest
28+
command: --default-authentication-plugin=mysql_native_password
29+
environment:
30+
MYSQL_ROOT_PASSWORD: secret
31+
MYSQL_DATABASE: kanboard
32+
MYSQL_USER: kb
33+
MYSQL_PASSWORD: kb-secret
34+
rights:
35+
image: busybox
36+
command: sh -c 'while true ; do chown -R $${USER_ID}.$${GROUP_ID} /target ; sleep 2s ; done'
37+
volumes:
38+
- .:/target
39+
environment:
40+
- USER_ID=10015
41+
- GROUP_ID=10003

Diff for: docker/conf.d/local.ini

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
expose_php = Off
2+
error_reporting = E_ALL
3+
display_errors = Off
4+
log_errors = On
5+
error_log = /dev/stderr
6+
date.timezone = UTC
7+
allow_url_fopen = On
8+
post_max_size = 32M
9+
upload_max_filesize = 32M
10+
opcache.max_accelerated_files = 7963
11+
opcache.validate_timestamps = On
12+
opcache.save_comments = 0
13+
opcache.load_comments = 0
14+
opcache.fast_shutdown = 1
15+
opcache.enable_file_override = On

0 commit comments

Comments
 (0)