summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog1
-rw-r--r--app/Core/Base.php1
-rw-r--r--app/Core/User/Avatar/AvatarManager.php62
-rw-r--r--app/Core/User/Avatar/AvatarProviderInterface.php30
-rw-r--r--app/Helper/UserHelper.php17
-rw-r--r--app/ServiceProvider/AvatarProvider.php31
-rw-r--r--app/Template/comment/show.php4
-rw-r--r--app/Template/event/comment_create.php2
-rw-r--r--app/Template/event/comment_update.php2
-rw-r--r--app/Template/event/events.php11
-rw-r--r--app/Template/event/subtask_create.php2
-rw-r--r--app/Template/event/subtask_update.php2
-rw-r--r--app/Template/event/task_assignee_change.php2
-rw-r--r--app/Template/event/task_close.php2
-rw-r--r--app/Template/event/task_create.php2
-rw-r--r--app/Template/event/task_file_create.php2
-rw-r--r--app/Template/event/task_move_column.php2
-rw-r--r--app/Template/event/task_move_position.php2
-rw-r--r--app/Template/event/task_move_swimlane.php2
-rw-r--r--app/Template/event/task_open.php2
-rw-r--r--app/Template/event/task_update.php2
-rw-r--r--app/User/Avatar/GravatarProvider.php35
-rw-r--r--app/common.php1
-rw-r--r--doc/plugin-avatar-provider.markdown32
-rw-r--r--doc/plugins.markdown7
25 files changed, 216 insertions, 42 deletions
diff --git a/ChangeLog b/ChangeLog
index 79c389a9..ef24f486 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,7 @@ Version 1.0.27 (unreleased)
Improvements:
+* Added pluggable Avatar providers
* Improve task summary sections
* Put back the action sidebar in task view
* Added support for multiple placeholders for LDAP_USER_FILTER
diff --git a/app/Core/Base.php b/app/Core/Base.php
index e53f299a..f87f271a 100644
--- a/app/Core/Base.php
+++ b/app/Core/Base.php
@@ -41,6 +41,7 @@ use Pimple\Container;
* @property \Kanboard\Core\Session\FlashMessage $flash
* @property \Kanboard\Core\Session\SessionManager $sessionManager
* @property \Kanboard\Core\Session\SessionStorage $sessionStorage
+ * @property \Kanboard\Core\User\Avatar\AvatarManager $avatarManager
* @property \Kanboard\Core\User\GroupSync $groupSync
* @property \Kanboard\Core\User\UserProfile $userProfile
* @property \Kanboard\Core\User\UserSync $userSync
diff --git a/app/Core/User/Avatar/AvatarManager.php b/app/Core/User/Avatar/AvatarManager.php
new file mode 100644
index 00000000..4b0c5298
--- /dev/null
+++ b/app/Core/User/Avatar/AvatarManager.php
@@ -0,0 +1,62 @@
+<?php
+
+namespace Kanboard\Core\User\Avatar;
+
+/**
+ * Avatar Manager
+ *
+ * @package user
+ * @author Frederic Guillot
+ */
+class AvatarManager
+{
+ /**
+ * Providers
+ *
+ * @access private
+ * @var AvatarProviderInterface[]
+ */
+ private $providers = array();
+
+ /**
+ * Register a new Avatar provider
+ *
+ * @access public
+ * @param AvatarProviderInterface $provider
+ * @return $this
+ */
+ public function register(AvatarProviderInterface $provider)
+ {
+ $this->providers[] = $provider;
+ return $this;
+ }
+
+ /**
+ * Render avatar html element
+ *
+ * @access public
+ * @param string $user_id
+ * @param string $username
+ * @param string $name
+ * @param string $email
+ * @param int $size
+ * @return string
+ */
+ public function render($user_id, $username, $name, $email, $size)
+ {
+ $user = array(
+ 'id' => $user_id,
+ 'username' => $username,
+ 'name' => $name,
+ 'email' => $email,
+ );
+
+ foreach ($this->providers as $provider) {
+ if ($provider->isActive($user)) {
+ return $provider->render($user, $size);
+ }
+ }
+
+ return '';
+ }
+}
diff --git a/app/Core/User/Avatar/AvatarProviderInterface.php b/app/Core/User/Avatar/AvatarProviderInterface.php
new file mode 100644
index 00000000..e0375d26
--- /dev/null
+++ b/app/Core/User/Avatar/AvatarProviderInterface.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace Kanboard\Core\User\Avatar;
+
+/**
+ * Avatar Provider Interface
+ *
+ * @package user
+ * @author Frederic Guillot
+ */
+interface AvatarProviderInterface
+{
+ /**
+ * Render avatar html
+ *
+ * @access public
+ * @param array $user
+ * @param int $size
+ */
+ public function render(array $user, $size);
+
+ /**
+ * Determine if the provider is active
+ *
+ * @access public
+ * @param array $user
+ * @return boolean
+ */
+ public function isActive(array $user);
+}
diff --git a/app/Helper/UserHelper.php b/app/Helper/UserHelper.php
index cbdb4af8..24ac591f 100644
--- a/app/Helper/UserHelper.php
+++ b/app/Helper/UserHelper.php
@@ -160,19 +160,18 @@ class UserHelper extends Base
}
/**
- * Display gravatar image
+ * Display avatar
*
* @access public
- * @param string $email
- * @param string $alt
+ * @param string $user_id
+ * @param string $username
+ * @param string $name
+ * @param string $email
* @return string
*/
- public function avatar($email, $alt = '')
+ public function avatar($user_id, $username, $name, $email)
{
- if (! empty($email) && $this->config->get('integration_gravatar') == 1) {
- return '<img class="avatar" src="https://www.gravatar.com/avatar/'.md5(strtolower($email)).'?s=25" alt="'.$this->helper->text->e($alt).'" title="'.$this->helper->text->e($alt).'">';
- }
-
- return '';
+ $html = $this->avatarManager->render($user_id, $username, $name, $email, 25);
+ return '<div class="avatar">'.$html.'</div>';
}
}
diff --git a/app/ServiceProvider/AvatarProvider.php b/app/ServiceProvider/AvatarProvider.php
new file mode 100644
index 00000000..2bbc9c03
--- /dev/null
+++ b/app/ServiceProvider/AvatarProvider.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace Kanboard\ServiceProvider;
+
+use Pimple\Container;
+use Pimple\ServiceProviderInterface;
+use Kanboard\Core\User\Avatar\AvatarManager;
+use Kanboard\User\Avatar\GravatarProvider;
+
+/**
+ * Avatar Provider
+ *
+ * @package serviceProvider
+ * @author Frederic Guillot
+ */
+class AvatarProvider implements ServiceProviderInterface
+{
+ /**
+ * Register providers
+ *
+ * @access public
+ * @param \Pimple\Container $container
+ * @return \Pimple\Container
+ */
+ public function register(Container $container)
+ {
+ $container['avatarManager'] = new AvatarManager;
+ $container['avatarManager']->register(new GravatarProvider($container));
+ return $container;
+ }
+}
diff --git a/app/Template/comment/show.php b/app/Template/comment/show.php
index 873e1470..c5963666 100644
--- a/app/Template/comment/show.php
+++ b/app/Template/comment/show.php
@@ -1,9 +1,7 @@
<div class="comment <?= isset($preview) ? 'comment-preview' : '' ?>" id="comment-<?= $comment['id'] ?>">
<p class="comment-title">
- <?php if (! empty($comment['email'])): ?>
- <?= $this->user->avatar($comment['email'], $comment['name'] ?: $comment['username']) ?>
- <?php endif ?>
+ <?= $this->user->avatar($comment['user_id'], $comment['username'], $comment['name'], $comment['email']) ?>
<?php if (! empty($comment['username'])): ?>
<span class="comment-username"><?= $this->text->e($comment['name'] ?: $comment['username']) ?></span> @
diff --git a/app/Template/event/comment_create.php b/app/Template/event/comment_create.php
index 063736b3..43c521cf 100644
--- a/app/Template/event/comment_create.php
+++ b/app/Template/event/comment_create.php
@@ -1,5 +1,3 @@
-<?= $this->user->avatar($email, $author) ?>
-
<p class="activity-title">
<?= e('%s commented the task %s',
$this->text->e($author),
diff --git a/app/Template/event/comment_update.php b/app/Template/event/comment_update.php
index 93f24d8a..80a33031 100644
--- a/app/Template/event/comment_update.php
+++ b/app/Template/event/comment_update.php
@@ -1,5 +1,3 @@
-<?= $this->user->avatar($email, $author) ?>
-
<p class="activity-title">
<?= e('%s updated a comment on the task %s',
$this->text->e($author),
diff --git a/app/Template/event/events.php b/app/Template/event/events.php
index bbb01be4..097da318 100644
--- a/app/Template/event/events.php
+++ b/app/Template/event/events.php
@@ -16,7 +16,16 @@
<?php endif ?>
&nbsp;<?= $this->dt->datetime($event['date_creation']) ?>
</p>
- <div class="activity-content"><?= $event['event_content'] ?></div>
+ <div class="activity-content">
+ <?= $this->user->avatar(
+ $event['creator_id'],
+ $event['author_username'],
+ $event['author_name'],
+ $event['email']
+ ) ?>
+
+ <?= $event['event_content'] ?>
+ </div>
</div>
<?php endforeach ?>
diff --git a/app/Template/event/subtask_create.php b/app/Template/event/subtask_create.php
index 532783d5..ae6ddd44 100644
--- a/app/Template/event/subtask_create.php
+++ b/app/Template/event/subtask_create.php
@@ -1,5 +1,3 @@
-<?= $this->user->avatar($email, $author) ?>
-
<p class="activity-title">
<?= e('%s created a subtask for the task %s',
$this->text->e($author),
diff --git a/app/Template/event/subtask_update.php b/app/Template/event/subtask_update.php
index e9ff6ac6..1d560fb0 100644
--- a/app/Template/event/subtask_update.php
+++ b/app/Template/event/subtask_update.php
@@ -1,5 +1,3 @@
-<?= $this->user->avatar($email, $author) ?>
-
<p class="activity-title">
<?= e('%s updated a subtask for the task %s',
$this->text->e($author),
diff --git a/app/Template/event/task_assignee_change.php b/app/Template/event/task_assignee_change.php
index 580176c7..6964a50e 100644
--- a/app/Template/event/task_assignee_change.php
+++ b/app/Template/event/task_assignee_change.php
@@ -1,5 +1,3 @@
-<?= $this->user->avatar($email, $author) ?>
-
<p class="activity-title">
<?php $assignee = $task['assignee_name'] ?: $task['assignee_username'] ?>
diff --git a/app/Template/event/task_close.php b/app/Template/event/task_close.php
index 361458d3..2ba77156 100644
--- a/app/Template/event/task_close.php
+++ b/app/Template/event/task_close.php
@@ -1,5 +1,3 @@
-<?= $this->user->avatar($email, $author) ?>
-
<p class="activity-title">
<?= e('%s closed the task %s',
$this->text->e($author),
diff --git a/app/Template/event/task_create.php b/app/Template/event/task_create.php
index 655bf8f3..21facc9e 100644
--- a/app/Template/event/task_create.php
+++ b/app/Template/event/task_create.php
@@ -1,5 +1,3 @@
-<?= $this->user->avatar($email, $author) ?>
-
<p class="activity-title">
<?= e('%s created the task %s',
$this->text->e($author),
diff --git a/app/Template/event/task_file_create.php b/app/Template/event/task_file_create.php
index 61bf3d61..837f5dc0 100644
--- a/app/Template/event/task_file_create.php
+++ b/app/Template/event/task_file_create.php
@@ -1,5 +1,3 @@
-<?= $this->user->avatar($email, $author) ?>
-
<p class="activity-title">
<?= e('%s attached a new file to the task %s',
$this->text->e($author),
diff --git a/app/Template/event/task_move_column.php b/app/Template/event/task_move_column.php
index 904c956c..b9ae65cc 100644
--- a/app/Template/event/task_move_column.php
+++ b/app/Template/event/task_move_column.php
@@ -1,5 +1,3 @@
-<?= $this->user->avatar($email, $author) ?>
-
<p class="activity-title">
<?= e('%s moved the task %s to the column "%s"',
$this->text->e($author),
diff --git a/app/Template/event/task_move_position.php b/app/Template/event/task_move_position.php
index 6580bb79..dbe73f4b 100644
--- a/app/Template/event/task_move_position.php
+++ b/app/Template/event/task_move_position.php
@@ -1,5 +1,3 @@
-<?= $this->user->avatar($email, $author) ?>
-
<p class="activity-title">
<?= e('%s moved the task %s to the position #%d in the column "%s"',
$this->text->e($author),
diff --git a/app/Template/event/task_move_swimlane.php b/app/Template/event/task_move_swimlane.php
index 9ffa554c..b0635a06 100644
--- a/app/Template/event/task_move_swimlane.php
+++ b/app/Template/event/task_move_swimlane.php
@@ -1,5 +1,3 @@
-<?= $this->user->avatar($email, $author) ?>
-
<p class="activity-title">
<?php if ($task['swimlane_id'] == 0): ?>
<?= e('%s moved the task %s to the first swimlane',
diff --git a/app/Template/event/task_open.php b/app/Template/event/task_open.php
index 9db2e3c9..ce92bb18 100644
--- a/app/Template/event/task_open.php
+++ b/app/Template/event/task_open.php
@@ -1,5 +1,3 @@
-<?= $this->user->avatar($email, $author) ?>
-
<p class="activity-title">
<?= e('%s opened the task %s',
$this->text->e($author),
diff --git a/app/Template/event/task_update.php b/app/Template/event/task_update.php
index 72d70495..83f1661b 100644
--- a/app/Template/event/task_update.php
+++ b/app/Template/event/task_update.php
@@ -1,5 +1,3 @@
-<?= $this->user->avatar($email, $author) ?>
-
<p class="activity-title">
<?= e('%s updated the task %s',
$this->text->e($author),
diff --git a/app/User/Avatar/GravatarProvider.php b/app/User/Avatar/GravatarProvider.php
new file mode 100644
index 00000000..10ab4390
--- /dev/null
+++ b/app/User/Avatar/GravatarProvider.php
@@ -0,0 +1,35 @@
+<?php
+
+namespace Kanboard\User\Avatar;
+
+use Kanboard\Core\Base;
+use Kanboard\Core\User\Avatar\AvatarProviderInterface;
+
+class GravatarProvider extends Base implements AvatarProviderInterface
+{
+ /**
+ * Render avatar html
+ *
+ * @access public
+ * @param array $user
+ * @param int $size
+ */
+ public function render(array $user, $size)
+ {
+ $url = sprintf('https://www.gravatar.com/avatar/%s?s=%d', md5(strtolower($user['email'])), $size);
+ $title = $this->helper->text->e($user['name'] ?: $user['username']);
+ return '<img src="'.$url.'" alt="'.$title.'" title="'.$title.'">';
+ }
+
+ /**
+ * Determine if the provider is active
+ *
+ * @access public
+ * @param array $user
+ * @return boolean
+ */
+ public function isActive(array $user)
+ {
+ return !empty($user['email']) && $this->config->get('integration_gravatar') == 1;
+ }
+}
diff --git a/app/common.php b/app/common.php
index 71f80c75..7dbd7587 100644
--- a/app/common.php
+++ b/app/common.php
@@ -38,4 +38,5 @@ $container->register(new Kanboard\ServiceProvider\GroupProvider);
$container->register(new Kanboard\ServiceProvider\RouteProvider);
$container->register(new Kanboard\ServiceProvider\ActionProvider);
$container->register(new Kanboard\ServiceProvider\ExternalLinkProvider);
+$container->register(new Kanboard\ServiceProvider\AvatarProvider);
$container->register(new Kanboard\ServiceProvider\PluginProvider);
diff --git a/doc/plugin-avatar-provider.markdown b/doc/plugin-avatar-provider.markdown
new file mode 100644
index 00000000..62941e5c
--- /dev/null
+++ b/doc/plugin-avatar-provider.markdown
@@ -0,0 +1,32 @@
+Adding a new Avatar Provider
+=============================
+
+Registration
+------------
+
+```php
+$this->avatarManager->register(new CustomAvatarProvider());
+```
+
+Interface
+---------
+
+The provider must implements the interface `Kanboard\Core\User\Avatar\AvatarProviderInterface`:
+
+
+| Method | Description |
+|-------------------------------|---------------------------------------------------------------|
+| `render(array $user, $size)` | Render HTML |
+| `isActive(array $user)` | Returns a boolean if the provider is able to render something |
+
+
+The `$user` argument is a dictionary that contains these keys:
+
+```php
+[
+ 'id' => 123,
+ 'username' => 'admin',
+ 'name' => 'Administrator',
+ 'email' => 'me@localhost',
+]
+```
diff --git a/doc/plugins.markdown b/doc/plugins.markdown
index e38c887f..475bc249 100644
--- a/doc/plugins.markdown
+++ b/doc/plugins.markdown
@@ -20,9 +20,10 @@ Plugin creators should specify explicitly the compatible versions of Kanboard. I
- [Attach metadata to users, tasks and projects](plugin-metadata.markdown)
- [Authentication architecture](plugin-authentication-architecture.markdown)
- [Authentication plugin registration](plugin-authentication.markdown)
-- [Authorization Architecture](plugin-authorization-architecture.markdown)
-- [Custom Group Providers](plugin-group-provider.markdown)
-- [External Link Providers](plugin-external-link.markdown)
+- [Authorization architecture](plugin-authorization-architecture.markdown)
+- [Custom group providers](plugin-group-provider.markdown)
+- [External link providers](plugin-external-link.markdown)
+- [Add avatar providers](plugin-avatar-provider.markdown)
- [LDAP client](plugin-ldap-client.markdown)
Examples of plugins