mirror of
https://github.com/YunoHost-Apps/kanboard_ynh.git
synced 2024-09-03 19:36:17 +02:00
Update kanboard v1.0.11
This commit is contained in:
parent
1acd2f8689
commit
ce6c8e2aa9
938 changed files with 11336 additions and 119656 deletions
|
@ -2,9 +2,8 @@
|
|||
|
||||
namespace Action;
|
||||
|
||||
use Event\GenericEvent;
|
||||
use Pimple\Container;
|
||||
use Core\Listener;
|
||||
use Core\Tool;
|
||||
|
||||
/**
|
||||
* Base class for automatic actions
|
||||
|
@ -12,7 +11,7 @@ use Core\Tool;
|
|||
* @package action
|
||||
* @author Frederic Guillot
|
||||
*
|
||||
* @property \Model\Acl $acl
|
||||
* @property \Model\UserSession $userSession
|
||||
* @property \Model\Comment $comment
|
||||
* @property \Model\Task $task
|
||||
* @property \Model\TaskCreation $taskCreation
|
||||
|
@ -21,8 +20,16 @@ use Core\Tool;
|
|||
* @property \Model\TaskFinder $taskFinder
|
||||
* @property \Model\TaskStatus $taskStatus
|
||||
*/
|
||||
abstract class Base implements Listener
|
||||
abstract class Base
|
||||
{
|
||||
/**
|
||||
* Flag for called listener
|
||||
*
|
||||
* @access private
|
||||
* @var boolean
|
||||
*/
|
||||
private $called = false;
|
||||
|
||||
/**
|
||||
* Project id
|
||||
*
|
||||
|
@ -114,6 +121,7 @@ abstract class Base implements Listener
|
|||
$this->container = $container;
|
||||
$this->project_id = $project_id;
|
||||
$this->event_name = $event_name;
|
||||
$this->called = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -136,7 +144,7 @@ abstract class Base implements Listener
|
|||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
return Tool::loadModel($this->container, $name);
|
||||
return $this->container[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -183,7 +191,6 @@ abstract class Base implements Listener
|
|||
* Check if the event is compatible with the action
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasCompatibleEvent()
|
||||
|
@ -225,12 +232,20 @@ abstract class Base implements Listener
|
|||
* Execute the action
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
* @param \Event\GenericEvent $event Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function execute(array $data)
|
||||
public function execute(GenericEvent $event)
|
||||
{
|
||||
// Avoid infinite loop, a listener instance can be called only one time
|
||||
if ($this->called) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$data = $event->getAll();
|
||||
|
||||
if ($this->isExecutable($data)) {
|
||||
$this->called = true;
|
||||
return $this->doAction($data);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Action;
|
||||
|
||||
use Model\GithubWebhook;
|
||||
use Integration\GithubWebhook;
|
||||
|
||||
/**
|
||||
* Create automatically a comment from a webhook
|
||||
|
@ -16,7 +16,7 @@ class CommentCreation extends Base
|
|||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
* @return string[]
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
|
@ -29,7 +29,7 @@ class CommentCreation extends Base
|
|||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
* @return string[]
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
|
|
|
@ -67,7 +67,7 @@ class TaskAssignCategoryColor extends Base
|
|||
'category_id' => $this->getParam('category_id'),
|
||||
);
|
||||
|
||||
return $this->taskModification->update($values, false);
|
||||
return $this->taskModification->update($values);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Action;
|
||||
|
||||
use Model\GithubWebhook;
|
||||
use Integration\GithubWebhook;
|
||||
|
||||
/**
|
||||
* Set a category automatically according to a label
|
||||
|
@ -67,7 +67,7 @@ class TaskAssignCategoryLabel extends Base
|
|||
'category_id' => isset($data['category_id']) ? $data['category_id'] : $this->getParam('category_id'),
|
||||
);
|
||||
|
||||
return $this->taskModification->update($values, false);
|
||||
return $this->taskModification->update($values);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -67,7 +67,7 @@ class TaskAssignColorCategory extends Base
|
|||
'color_id' => $this->getParam('color_id'),
|
||||
);
|
||||
|
||||
return $this->taskModification->update($values, false);
|
||||
return $this->taskModification->update($values);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -68,7 +68,7 @@ class TaskAssignColorUser extends Base
|
|||
'color_id' => $this->getParam('color_id'),
|
||||
);
|
||||
|
||||
return $this->taskModification->update($values, false);
|
||||
return $this->taskModification->update($values);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -62,12 +62,16 @@ class TaskAssignCurrentUser extends Base
|
|||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
if (! $this->userSession->isLogged()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$values = array(
|
||||
'id' => $data['task_id'],
|
||||
'owner_id' => $this->acl->getUserId(),
|
||||
'owner_id' => $this->userSession->getId(),
|
||||
);
|
||||
|
||||
return $this->taskModification->update($values, false);
|
||||
return $this->taskModification->update($values);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -68,7 +68,7 @@ class TaskAssignSpecificUser extends Base
|
|||
'owner_id' => $this->getParam('user_id'),
|
||||
);
|
||||
|
||||
return $this->taskModification->update($values, false);
|
||||
return $this->taskModification->update($values);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Action;
|
||||
|
||||
use Model\GithubWebhook;
|
||||
use Integration\GithubWebhook;
|
||||
|
||||
/**
|
||||
* Assign a task to someone
|
||||
|
@ -64,7 +64,7 @@ class TaskAssignUser extends Base
|
|||
'owner_id' => $data['owner_id'],
|
||||
);
|
||||
|
||||
return $this->taskModification->update($values, false);
|
||||
return $this->taskModification->update($values);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
namespace Action;
|
||||
|
||||
use Model\GithubWebhook;
|
||||
use Integration\GitlabWebhook;
|
||||
use Integration\GithubWebhook;
|
||||
use Model\Task;
|
||||
|
||||
/**
|
||||
|
@ -25,6 +26,8 @@ class TaskClose extends Base
|
|||
Task::EVENT_MOVE_COLUMN,
|
||||
GithubWebhook::EVENT_COMMIT,
|
||||
GithubWebhook::EVENT_ISSUE_CLOSED,
|
||||
GitlabWebhook::EVENT_COMMIT,
|
||||
GitlabWebhook::EVENT_ISSUE_CLOSED,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -39,6 +42,8 @@ class TaskClose extends Base
|
|||
switch ($this->event_name) {
|
||||
case GithubWebhook::EVENT_COMMIT:
|
||||
case GithubWebhook::EVENT_ISSUE_CLOSED:
|
||||
case GitlabWebhook::EVENT_COMMIT:
|
||||
case GitlabWebhook::EVENT_ISSUE_CLOSED:
|
||||
return array();
|
||||
default:
|
||||
return array('column_id' => t('Column'));
|
||||
|
@ -56,6 +61,8 @@ class TaskClose extends Base
|
|||
switch ($this->event_name) {
|
||||
case GithubWebhook::EVENT_COMMIT:
|
||||
case GithubWebhook::EVENT_ISSUE_CLOSED:
|
||||
case GitlabWebhook::EVENT_COMMIT:
|
||||
case GitlabWebhook::EVENT_ISSUE_CLOSED:
|
||||
return array('task_id');
|
||||
default:
|
||||
return array('task_id', 'column_id');
|
||||
|
@ -86,6 +93,8 @@ class TaskClose extends Base
|
|||
switch ($this->event_name) {
|
||||
case GithubWebhook::EVENT_COMMIT:
|
||||
case GithubWebhook::EVENT_ISSUE_CLOSED:
|
||||
case GitlabWebhook::EVENT_COMMIT:
|
||||
case GitlabWebhook::EVENT_ISSUE_CLOSED:
|
||||
return true;
|
||||
default:
|
||||
return $data['column_id'] == $this->getParam('column_id');
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
namespace Action;
|
||||
|
||||
use Model\GithubWebhook;
|
||||
use Integration\GithubWebhook;
|
||||
use Integration\GitlabWebhook;
|
||||
|
||||
/**
|
||||
* Create automatically a task from a webhook
|
||||
|
@ -22,6 +23,7 @@ class TaskCreation extends Base
|
|||
{
|
||||
return array(
|
||||
GithubWebhook::EVENT_ISSUE_OPENED,
|
||||
GitlabWebhook::EVENT_ISSUE_OPENED,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -63,7 +65,7 @@ class TaskCreation extends Base
|
|||
'project_id' => $data['project_id'],
|
||||
'title' => $data['title'],
|
||||
'reference' => $data['reference'],
|
||||
'description' => $data['description'],
|
||||
'description' => isset($data['description']) ? $data['description'] : '',
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Action;
|
||||
|
||||
use Model\GithubWebhook;
|
||||
use Integration\GithubWebhook;
|
||||
|
||||
/**
|
||||
* Open automatically a task
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace Auth;
|
||||
|
||||
use Core\Tool;
|
||||
use Pimple\Container;
|
||||
|
||||
/**
|
||||
|
@ -14,6 +13,7 @@ use Pimple\Container;
|
|||
* @property \Model\Acl $acl
|
||||
* @property \Model\LastLogin $lastLogin
|
||||
* @property \Model\User $user
|
||||
* @property \Model\UserSession $userSession
|
||||
*/
|
||||
abstract class Base
|
||||
{
|
||||
|
@ -54,6 +54,6 @@ abstract class Base
|
|||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
return Tool::loadModel($this->container, $name);
|
||||
return $this->container[$name];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
namespace Auth;
|
||||
|
||||
use Model\User;
|
||||
use Core\Request;
|
||||
use Event\AuthEvent;
|
||||
|
||||
/**
|
||||
* Database authentication
|
||||
|
@ -33,18 +33,8 @@ class Database extends Base
|
|||
$user = $this->db->table(User::TABLE)->eq('username', $username)->eq('is_ldap_user', 0)->findOne();
|
||||
|
||||
if ($user && password_verify($password, $user['password'])) {
|
||||
|
||||
// Update user session
|
||||
$this->user->updateSession($user);
|
||||
|
||||
// Update login history
|
||||
$this->lastLogin->create(
|
||||
self::AUTH_NAME,
|
||||
$user['id'],
|
||||
Request::getIpAddress(),
|
||||
Request::getUserAgent()
|
||||
);
|
||||
|
||||
$this->userSession->refresh($user);
|
||||
$this->container['dispatcher']->dispatch('auth.success', new AuthEvent(self::AUTH_NAME, $user['id']));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Auth;
|
||||
|
||||
use Core\Request;
|
||||
use Event\AuthEvent;
|
||||
use OAuth\Common\Storage\Session;
|
||||
use OAuth\Common\Consumer\Credentials;
|
||||
use OAuth\Common\Http\Uri\UriFactory;
|
||||
|
@ -35,18 +35,8 @@ class GitHub extends Base
|
|||
$user = $this->user->getByGitHubId($github_id);
|
||||
|
||||
if ($user) {
|
||||
|
||||
// Create the user session
|
||||
$this->user->updateSession($user);
|
||||
|
||||
// Update login history
|
||||
$this->lastLogin->create(
|
||||
self::AUTH_NAME,
|
||||
$user['id'],
|
||||
Request::getIpAddress(),
|
||||
Request::getUserAgent()
|
||||
);
|
||||
|
||||
$this->userSession->refresh($user);
|
||||
$this->container['dispatcher']->dispatch('auth.success', new AuthEvent(self::AUTH_NAME, $user['id']));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Auth;
|
||||
|
||||
use Core\Request;
|
||||
use Event\AuthEvent;
|
||||
use OAuth\Common\Storage\Session;
|
||||
use OAuth\Common\Consumer\Credentials;
|
||||
use OAuth\Common\Http\Uri\UriFactory;
|
||||
|
@ -36,18 +36,8 @@ class Google extends Base
|
|||
$user = $this->user->getByGoogleId($google_id);
|
||||
|
||||
if ($user) {
|
||||
|
||||
// Create the user session
|
||||
$this->user->updateSession($user);
|
||||
|
||||
// Update login history
|
||||
$this->lastLogin->create(
|
||||
self::AUTH_NAME,
|
||||
$user['id'],
|
||||
Request::getIpAddress(),
|
||||
Request::getUserAgent()
|
||||
);
|
||||
|
||||
$this->userSession->refresh($user);
|
||||
$this->container['dispatcher']->dispatch('auth.success', new AuthEvent(self::AUTH_NAME, $user['id']));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Auth;
|
||||
|
||||
use Core\Request;
|
||||
use Event\AuthEvent;
|
||||
|
||||
/**
|
||||
* LDAP model
|
||||
|
@ -54,15 +54,8 @@ class Ldap extends Base
|
|||
}
|
||||
|
||||
// We open the session
|
||||
$this->user->updateSession($user);
|
||||
|
||||
// Update login history
|
||||
$this->lastLogin->create(
|
||||
self::AUTH_NAME,
|
||||
$user['id'],
|
||||
Request::getIpAddress(),
|
||||
Request::getUserAgent()
|
||||
);
|
||||
$this->userSession->refresh($user);
|
||||
$this->container['dispatcher']->dispatch('auth.success', new AuthEvent(self::AUTH_NAME, $user['id']));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
namespace Auth;
|
||||
|
||||
use Core\Request;
|
||||
use Event\AuthEvent;
|
||||
use Core\Security;
|
||||
|
||||
/**
|
||||
|
@ -100,15 +101,11 @@ class RememberMe extends Base
|
|||
);
|
||||
|
||||
// Create the session
|
||||
$this->user->updateSession($this->user->getById($record['user_id']));
|
||||
$this->acl->isRememberMe(true);
|
||||
$this->userSession->refresh($this->user->getById($record['user_id']));
|
||||
|
||||
// Update last login infos
|
||||
$this->lastLogin->create(
|
||||
self::AUTH_NAME,
|
||||
$this->acl->getUserId(),
|
||||
Request::getIpAddress(),
|
||||
Request::getUserAgent()
|
||||
$this->container['dispatcher']->dispatch(
|
||||
'auth.success',
|
||||
new AuthEvent(self::AUTH_NAME, $this->userSession->getId())
|
||||
);
|
||||
|
||||
return true;
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
|
||||
namespace Auth;
|
||||
|
||||
use Core\Request;
|
||||
use Core\Security;
|
||||
use Event\AuthEvent;
|
||||
|
||||
/**
|
||||
* ReverseProxy backend
|
||||
|
@ -38,16 +37,8 @@ class ReverseProxy extends Base
|
|||
$user = $this->user->getByUsername($login);
|
||||
}
|
||||
|
||||
// Create the user session
|
||||
$this->user->updateSession($user);
|
||||
|
||||
// Update login history
|
||||
$this->lastLogin->create(
|
||||
self::AUTH_NAME,
|
||||
$user['id'],
|
||||
Request::getIpAddress(),
|
||||
Request::getUserAgent()
|
||||
);
|
||||
$this->userSession->refresh($user);
|
||||
$this->container['dispatcher']->dispatch('auth.success', new AuthEvent(self::AUTH_NAME, $user['id']));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace Console;
|
||||
|
||||
use Core\Tool;
|
||||
use Pimple\Container;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
|
||||
|
@ -17,6 +16,7 @@ use Symfony\Component\Console\Command\Command;
|
|||
* @property \Model\ProjectPermission $projectPermission
|
||||
* @property \Model\ProjectAnalytic $projectAnalytic
|
||||
* @property \Model\ProjectDailySummary $projectDailySummary
|
||||
* @property \Model\SubtaskExport $subtaskExport
|
||||
* @property \Model\Task $task
|
||||
* @property \Model\TaskExport $taskExport
|
||||
* @property \Model\TaskFinder $taskFinder
|
||||
|
@ -52,6 +52,6 @@ abstract class Base extends Command
|
|||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
return Tool::loadModel($this->container, $name);
|
||||
return $this->container[$name];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,9 +3,7 @@
|
|||
namespace Console;
|
||||
|
||||
use Model\Project;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class ProjectDailySummaryCalculation extends Base
|
||||
|
|
|
@ -5,7 +5,6 @@ namespace Console;
|
|||
use Core\Tool;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class ProjectDailySummaryExport extends Base
|
||||
|
|
34
sources/app/Console/SubtaskExport.php
Normal file
34
sources/app/Console/SubtaskExport.php
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace Console;
|
||||
|
||||
use Core\Tool;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class SubtaskExport extends Base
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('export:subtasks')
|
||||
->setDescription('Subtasks CSV export')
|
||||
->addArgument('project_id', InputArgument::REQUIRED, 'Project id')
|
||||
->addArgument('start_date', InputArgument::REQUIRED, 'Start date (YYYY-MM-DD)')
|
||||
->addArgument('end_date', InputArgument::REQUIRED, 'End date (YYYY-MM-DD)');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$data = $this->subtaskExport->export(
|
||||
$input->getArgument('project_id'),
|
||||
$input->getArgument('start_date'),
|
||||
$input->getArgument('end_date')
|
||||
);
|
||||
|
||||
if (is_array($data)) {
|
||||
Tool::csv($data);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,7 +5,6 @@ namespace Console;
|
|||
use Core\Tool;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class TaskExport extends Base
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
namespace Console;
|
||||
|
||||
use Symfony\Component\Console\Helper\Table;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
|
|
@ -17,7 +17,7 @@ class Action extends Base
|
|||
*/
|
||||
public function index()
|
||||
{
|
||||
$project = $this->getProjectManagement();
|
||||
$project = $this->getProject();
|
||||
|
||||
$this->response->html($this->projectLayout('action/index', array(
|
||||
'values' => array('project_id' => $project['id']),
|
||||
|
@ -42,7 +42,7 @@ class Action extends Base
|
|||
*/
|
||||
public function event()
|
||||
{
|
||||
$project = $this->getProjectManagement();
|
||||
$project = $this->getProject();
|
||||
$values = $this->request->getValues();
|
||||
|
||||
if (empty($values['action_name']) || empty($values['project_id'])) {
|
||||
|
@ -64,7 +64,7 @@ class Action extends Base
|
|||
*/
|
||||
public function params()
|
||||
{
|
||||
$project = $this->getProjectManagement();
|
||||
$project = $this->getProject();
|
||||
$values = $this->request->getValues();
|
||||
|
||||
if (empty($values['action_name']) || empty($values['project_id']) || empty($values['event_name'])) {
|
||||
|
@ -101,7 +101,7 @@ class Action extends Base
|
|||
*/
|
||||
public function create()
|
||||
{
|
||||
$this->doCreation($this->getProjectManagement(), $this->request->getValues());
|
||||
$this->doCreation($this->getProject(), $this->request->getValues());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -135,7 +135,7 @@ class Action extends Base
|
|||
*/
|
||||
public function confirm()
|
||||
{
|
||||
$project = $this->getProjectManagement();
|
||||
$project = $this->getProject();
|
||||
|
||||
$this->response->html($this->projectLayout('action/remove', array(
|
||||
'action' => $this->action->getById($this->request->getIntegerParam('action_id')),
|
||||
|
@ -154,7 +154,7 @@ class Action extends Base
|
|||
public function remove()
|
||||
{
|
||||
$this->checkCSRFParam();
|
||||
$project = $this->getProjectManagement();
|
||||
$project = $this->getProject();
|
||||
$action = $this->action->getById($this->request->getIntegerParam('action_id'));
|
||||
|
||||
if ($action && $this->action->remove($action['id'])) {
|
||||
|
|
|
@ -20,8 +20,8 @@ class Analytic extends Base
|
|||
*/
|
||||
private function layout($template, array $params)
|
||||
{
|
||||
$params['board_selector'] = $this->projectPermission->getAllowedProjects($this->acl->getUserId());
|
||||
$params['analytic_content_for_layout'] = $this->template->load($template, $params);
|
||||
$params['board_selector'] = $this->projectPermission->getAllowedProjects($this->userSession->getId());
|
||||
$params['analytic_content_for_layout'] = $this->template->render($template, $params);
|
||||
|
||||
return $this->template->layout('analytic/layout', $params);
|
||||
}
|
||||
|
|
|
@ -2,9 +2,7 @@
|
|||
|
||||
namespace Controller;
|
||||
|
||||
use Model\Project as ProjectModel;
|
||||
use Model\SubTask as SubTaskModel;
|
||||
use Helper;
|
||||
|
||||
/**
|
||||
* Application controller
|
||||
|
@ -36,7 +34,7 @@ class App extends Base
|
|||
$direction = $this->request->getStringParam('direction');
|
||||
$order = $this->request->getStringParam('order');
|
||||
|
||||
$user_id = $this->acl->getUserId();
|
||||
$user_id = $this->userSession->getId();
|
||||
$projects = $this->projectPermission->getMemberProjects($user_id);
|
||||
$project_ids = array_keys($projects);
|
||||
|
||||
|
@ -57,6 +55,11 @@ class App extends Base
|
|||
* Get tasks pagination
|
||||
*
|
||||
* @access public
|
||||
* @param integer $user_id
|
||||
* @param string $paginate
|
||||
* @param integer $offset
|
||||
* @param string $order
|
||||
* @param string $direction
|
||||
*/
|
||||
private function getTaskPagination($user_id, $paginate, $offset, $order, $direction)
|
||||
{
|
||||
|
@ -94,6 +97,11 @@ class App extends Base
|
|||
* Get subtasks pagination
|
||||
*
|
||||
* @access public
|
||||
* @param integer $user_id
|
||||
* @param string $paginate
|
||||
* @param integer $offset
|
||||
* @param string $order
|
||||
* @param string $direction
|
||||
*/
|
||||
private function getSubtaskPagination($user_id, $paginate, $offset, $order, $direction)
|
||||
{
|
||||
|
@ -132,10 +140,15 @@ class App extends Base
|
|||
* Get projects pagination
|
||||
*
|
||||
* @access public
|
||||
* @param array $project_ids
|
||||
* @param string $paginate
|
||||
* @param integer $offset
|
||||
* @param string $order
|
||||
* @param string $direction
|
||||
*/
|
||||
private function getProjectPagination($project_ids, $paginate, $offset, $order, $direction)
|
||||
private function getProjectPagination(array $project_ids, $paginate, $offset, $order, $direction)
|
||||
{
|
||||
$limit = 5;
|
||||
$limit = 10;
|
||||
|
||||
if (! in_array($order, array('id', 'name'))) {
|
||||
$order = 'name';
|
||||
|
@ -178,8 +191,9 @@ class App extends Base
|
|||
$this->response->html('<p>'.t('Nothing to preview...').'</p>');
|
||||
}
|
||||
else {
|
||||
$this->response->html(Helper\markdown($payload['text']));
|
||||
$this->response->html(
|
||||
$this->template->markdown($payload['text'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,13 +3,13 @@
|
|||
namespace Controller;
|
||||
|
||||
use Pimple\Container;
|
||||
use Core\Tool;
|
||||
use Core\Security;
|
||||
use Core\Request;
|
||||
use Core\Response;
|
||||
use Core\Template;
|
||||
use Core\Session;
|
||||
use Model\LastLogin;
|
||||
use Symfony\Component\EventDispatcher\Event;
|
||||
|
||||
/**
|
||||
* Base controller
|
||||
|
@ -17,6 +17,8 @@ use Model\LastLogin;
|
|||
* @package controller
|
||||
* @author Frederic Guillot
|
||||
*
|
||||
* @property \Core\Session $session
|
||||
* @property \Core\Template $template
|
||||
* @property \Model\Acl $acl
|
||||
* @property \Model\Authentication $authentication
|
||||
* @property \Model\Action $action
|
||||
|
@ -49,6 +51,7 @@ use Model\LastLogin;
|
|||
* @property \Model\SubtaskHistory $subtaskHistory
|
||||
* @property \Model\TimeTracking $timeTracking
|
||||
* @property \Model\User $user
|
||||
* @property \Model\UserSession $userSession
|
||||
* @property \Model\Webhook $webhook
|
||||
*/
|
||||
abstract class Base
|
||||
|
@ -69,22 +72,6 @@ abstract class Base
|
|||
*/
|
||||
protected $response;
|
||||
|
||||
/**
|
||||
* Template instance
|
||||
*
|
||||
* @accesss protected
|
||||
* @var \Core\Template
|
||||
*/
|
||||
protected $template;
|
||||
|
||||
/**
|
||||
* Session instance
|
||||
*
|
||||
* @accesss public
|
||||
* @var \Core\Session
|
||||
*/
|
||||
protected $session;
|
||||
|
||||
/**
|
||||
* Container instance
|
||||
*
|
||||
|
@ -104,8 +91,6 @@ abstract class Base
|
|||
$this->container = $container;
|
||||
$this->request = new Request;
|
||||
$this->response = new Response;
|
||||
$this->session = new Session;
|
||||
$this->template = new Template;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -115,9 +100,15 @@ abstract class Base
|
|||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
// foreach ($this->container['db']->getLogMessages() as $message) {
|
||||
// $this->container['logger']->addDebug($message);
|
||||
// }
|
||||
if (DEBUG) {
|
||||
|
||||
foreach ($this->container['db']->getLogMessages() as $message) {
|
||||
$this->container['logger']->debug($message);
|
||||
}
|
||||
|
||||
$this->container['logger']->debug('SQL_QUERIES={nb}', array('nb' => $this->container['db']->nb_queries));
|
||||
$this->container['logger']->debug('RENDERING={time}', array('time' => microtime(true) - $_SERVER['REQUEST_TIME_FLOAT']));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -129,19 +120,16 @@ abstract class Base
|
|||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
return Tool::loadModel($this->container, $name);
|
||||
return $this->container[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Method executed before each action
|
||||
* Send HTTP headers
|
||||
*
|
||||
* @access public
|
||||
* @access private
|
||||
*/
|
||||
public function beforeAction($controller, $action)
|
||||
private function sendHeaders($action)
|
||||
{
|
||||
// Start the session
|
||||
$this->session->open(BASE_URL_DIRECTORY);
|
||||
|
||||
// HTTP secure headers
|
||||
$this->response->csp(array('style-src' => "'self' 'unsafe-inline'"));
|
||||
$this->response->nosniff();
|
||||
|
@ -155,12 +143,33 @@ abstract class Base
|
|||
if (ENABLE_HSTS) {
|
||||
$this->response->hsts();
|
||||
}
|
||||
}
|
||||
|
||||
$this->config->setupTranslations();
|
||||
$this->config->setupTimezone();
|
||||
/**
|
||||
* Method executed before each action
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function beforeAction($controller, $action)
|
||||
{
|
||||
// Start the session
|
||||
$this->session->open(BASE_URL_DIRECTORY);
|
||||
$this->sendHeaders($action);
|
||||
$this->container['dispatcher']->dispatch('session.bootstrap', new Event);
|
||||
|
||||
// Authentication
|
||||
if (! $this->authentication->isAuthenticated($controller, $action)) {
|
||||
if (! $this->acl->isPublicAction($controller, $action)) {
|
||||
$this->handleAuthenticatedUser($controller, $action);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check page access and authentication
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function handleAuthenticatedUser($controller, $action)
|
||||
{
|
||||
if (! $this->authentication->isAuthenticated()) {
|
||||
|
||||
if ($this->request->isAjax()) {
|
||||
$this->response->text('Not Authorized', 401);
|
||||
|
@ -169,33 +178,8 @@ abstract class Base
|
|||
$this->response->redirect('?controller=user&action=login&redirect_query='.urlencode($this->request->getQueryString()));
|
||||
}
|
||||
|
||||
// Check if the user is allowed to see this page
|
||||
if (! $this->acl->isPageAccessAllowed($controller, $action)) {
|
||||
$this->response->redirect('?controller=user&action=forbidden');
|
||||
}
|
||||
|
||||
// Attach events
|
||||
$this->attachEvents();
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach events
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
private function attachEvents()
|
||||
{
|
||||
$models = array(
|
||||
'projectActivity', // Order is important
|
||||
'projectDailySummary',
|
||||
'action',
|
||||
'project',
|
||||
'webhook',
|
||||
'notification',
|
||||
);
|
||||
|
||||
foreach ($models as $model) {
|
||||
$this->$model->attachEvents();
|
||||
if (! $this->acl->isAllowed($controller, $action, $this->request->getIntegerParam('project_id', 0))) {
|
||||
$this->forbidden();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -239,19 +223,6 @@ abstract class Base
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current user have access to the given project
|
||||
*
|
||||
* @access protected
|
||||
* @param integer $project_id Project id
|
||||
*/
|
||||
protected function checkProjectPermissions($project_id)
|
||||
{
|
||||
if ($this->acl->isRegularUser() && ! $this->projectPermission->isUserAllowed($project_id, $this->acl->getUserId())) {
|
||||
$this->forbidden();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirection when there is no project in the database
|
||||
*
|
||||
|
@ -273,14 +244,10 @@ abstract class Base
|
|||
*/
|
||||
protected function taskLayout($template, array $params)
|
||||
{
|
||||
if (isset($params['task']) && $this->taskPermission->canRemoveTask($params['task']) === false) {
|
||||
$params['hide_remove_menu'] = true;
|
||||
}
|
||||
|
||||
$content = $this->template->load($template, $params);
|
||||
$content = $this->template->render($template, $params);
|
||||
$params['task_content_for_layout'] = $content;
|
||||
$params['title'] = $params['task']['project_name'].' > '.$params['task']['title'];
|
||||
$params['board_selector'] = $this->projectPermission->getAllowedProjects($this->acl->getUserId());
|
||||
$params['board_selector'] = $this->projectPermission->getAllowedProjects($this->userSession->getId());
|
||||
|
||||
return $this->template->layout('task/layout', $params);
|
||||
}
|
||||
|
@ -295,10 +262,10 @@ abstract class Base
|
|||
*/
|
||||
protected function projectLayout($template, array $params)
|
||||
{
|
||||
$content = $this->template->load($template, $params);
|
||||
$content = $this->template->render($template, $params);
|
||||
$params['project_content_for_layout'] = $content;
|
||||
$params['title'] = $params['project']['name'] === $params['title'] ? $params['title'] : $params['project']['name'].' > '.$params['title'];
|
||||
$params['board_selector'] = $this->projectPermission->getAllowedProjects($this->acl->getUserId());
|
||||
$params['board_selector'] = $this->projectPermission->getAllowedProjects($this->userSession->getId());
|
||||
|
||||
return $this->template->layout('project/layout', $params);
|
||||
}
|
||||
|
@ -313,12 +280,10 @@ abstract class Base
|
|||
{
|
||||
$task = $this->taskFinder->getDetails($this->request->getIntegerParam('task_id'));
|
||||
|
||||
if (! $task) {
|
||||
if (! $task || $task['project_id'] != $this->request->getIntegerParam('project_id')) {
|
||||
$this->notfound();
|
||||
}
|
||||
|
||||
$this->checkProjectPermissions($task['project_id']);
|
||||
|
||||
return $task;
|
||||
}
|
||||
|
||||
|
@ -339,29 +304,6 @@ abstract class Base
|
|||
$this->response->redirect('?controller=project');
|
||||
}
|
||||
|
||||
$this->checkProjectPermissions($project['id']);
|
||||
|
||||
return $project;
|
||||
}
|
||||
|
||||
/**
|
||||
* Common method to get a project with administration rights
|
||||
*
|
||||
* @access protected
|
||||
* @return array
|
||||
*/
|
||||
protected function getProjectManagement()
|
||||
{
|
||||
$project = $this->project->getById($this->request->getIntegerParam('project_id'));
|
||||
|
||||
if (! $project) {
|
||||
$this->notfound();
|
||||
}
|
||||
|
||||
if ($this->acl->isRegularUser() && ! $this->projectPermission->adminAllowed($project['id'], $this->acl->getUserId())) {
|
||||
$this->forbidden();
|
||||
}
|
||||
|
||||
return $project;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
|
||||
namespace Controller;
|
||||
|
||||
use Model\Project as ProjectModel;
|
||||
use Model\User as UserModel;
|
||||
use Core\Security;
|
||||
|
||||
/**
|
||||
* Board controller
|
||||
*
|
||||
|
@ -22,7 +18,7 @@ class Board extends Base
|
|||
public function moveColumn()
|
||||
{
|
||||
$this->checkCSRFParam();
|
||||
$project = $this->getProjectManagement();
|
||||
$project = $this->getProject();
|
||||
$column_id = $this->request->getIntegerParam('column_id');
|
||||
$direction = $this->request->getStringParam('direction');
|
||||
|
||||
|
@ -43,7 +39,7 @@ class Board extends Base
|
|||
$task = $this->getTask();
|
||||
$project = $this->project->getById($task['project_id']);
|
||||
|
||||
$this->response->html($this->template->load('board/assignee', array(
|
||||
$this->response->html($this->template->render('board/assignee', array(
|
||||
'values' => $task,
|
||||
'users_list' => $this->projectPermission->getMemberList($project['id']),
|
||||
'project' => $project,
|
||||
|
@ -58,7 +54,6 @@ class Board extends Base
|
|||
public function updateAssignee()
|
||||
{
|
||||
$values = $this->request->getValues();
|
||||
$this->checkProjectPermissions($values['project_id']);
|
||||
|
||||
list($valid,) = $this->taskValidator->validateAssigneeModification($values);
|
||||
|
||||
|
@ -82,7 +77,7 @@ class Board extends Base
|
|||
$task = $this->getTask();
|
||||
$project = $this->project->getById($task['project_id']);
|
||||
|
||||
$this->response->html($this->template->load('board/category', array(
|
||||
$this->response->html($this->template->render('board/category', array(
|
||||
'values' => $task,
|
||||
'categories_list' => $this->category->getList($project['id']),
|
||||
'project' => $project,
|
||||
|
@ -97,7 +92,6 @@ class Board extends Base
|
|||
public function updateCategory()
|
||||
{
|
||||
$values = $this->request->getValues();
|
||||
$this->checkProjectPermissions($values['project_id']);
|
||||
|
||||
list($valid,) = $this->taskValidator->validateCategoryModification($values);
|
||||
|
||||
|
@ -130,12 +124,14 @@ class Board extends Base
|
|||
// Display the board with a specific layout
|
||||
$this->response->html($this->template->layout('board/public', array(
|
||||
'project' => $project,
|
||||
'columns' => $this->board->get($project['id']),
|
||||
'swimlanes' => $this->board->getBoard($project['id']),
|
||||
'categories' => $this->category->getList($project['id'], false),
|
||||
'title' => $project['name'],
|
||||
'no_layout' => true,
|
||||
'not_editable' => true,
|
||||
'board_public_refresh_interval' => $this->config->get('board_public_refresh_interval'),
|
||||
'board_private_refresh_interval' => $this->config->get('board_private_refresh_interval'),
|
||||
'board_highlight_period' => $this->config->get('board_highlight_period'),
|
||||
)));
|
||||
}
|
||||
|
||||
|
@ -146,16 +142,16 @@ class Board extends Base
|
|||
*/
|
||||
public function index()
|
||||
{
|
||||
$last_seen_project_id = $this->user->getLastSeenProjectId();
|
||||
$favorite_project_id = $this->user->getFavoriteProjectId();
|
||||
$last_seen_project_id = $this->userSession->getLastSeenProjectId();
|
||||
$favorite_project_id = $this->userSession->getFavoriteProjectId();
|
||||
$project_id = $last_seen_project_id ?: $favorite_project_id;
|
||||
|
||||
if (! $project_id) {
|
||||
$projects = $this->projectPermission->getAllowedProjects($this->acl->getUserId());
|
||||
$projects = $this->projectPermission->getAllowedProjects($this->userSession->getId());
|
||||
|
||||
if (empty($projects)) {
|
||||
|
||||
if ($this->acl->isAdminUser()) {
|
||||
if ($this->userSession->isAdmin()) {
|
||||
$this->redirectNoProject();
|
||||
}
|
||||
|
||||
|
@ -177,18 +173,18 @@ class Board extends Base
|
|||
public function show($project_id = 0)
|
||||
{
|
||||
$project = $this->getProject($project_id);
|
||||
$projects = $this->projectPermission->getAllowedProjects($this->acl->getUserId());
|
||||
$projects = $this->projectPermission->getAllowedProjects($this->userSession->getId());
|
||||
|
||||
$board_selector = $projects;
|
||||
unset($board_selector[$project['id']]);
|
||||
|
||||
$this->user->storeLastSeenProjectId($project['id']);
|
||||
$this->userSession->storeLastSeenProjectId($project['id']);
|
||||
|
||||
$this->response->html($this->template->layout('board/index', array(
|
||||
'users' => $this->projectPermission->getMemberList($project['id'], true, true),
|
||||
'projects' => $projects,
|
||||
'project' => $project,
|
||||
'board' => $this->board->get($project['id']),
|
||||
'swimlanes' => $this->board->getBoard($project['id']),
|
||||
'categories' => $this->category->getList($project['id'], true, true),
|
||||
'title' => $project['name'],
|
||||
'board_selector' => $board_selector,
|
||||
|
@ -202,11 +198,10 @@ class Board extends Base
|
|||
*
|
||||
* @access public
|
||||
*/
|
||||
public function edit()
|
||||
public function edit(array $values = array(), array $errors = array())
|
||||
{
|
||||
$project = $this->getProjectManagement();
|
||||
$project = $this->getProject();
|
||||
$columns = $this->board->getColumns($project['id']);
|
||||
$values = array();
|
||||
|
||||
foreach ($columns as $column) {
|
||||
$values['title['.$column['id'].']'] = $column['title'];
|
||||
|
@ -214,7 +209,7 @@ class Board extends Base
|
|||
}
|
||||
|
||||
$this->response->html($this->projectLayout('board/edit', array(
|
||||
'errors' => array(),
|
||||
'errors' => $errors,
|
||||
'values' => $values + array('project_id' => $project['id']),
|
||||
'columns' => $columns,
|
||||
'project' => $project,
|
||||
|
@ -229,7 +224,7 @@ class Board extends Base
|
|||
*/
|
||||
public function update()
|
||||
{
|
||||
$project = $this->getProjectManagement();
|
||||
$project = $this->getProject();
|
||||
$columns = $this->board->getColumns($project['id']);
|
||||
$data = $this->request->getValues();
|
||||
$values = $columns_list = array();
|
||||
|
@ -253,13 +248,7 @@ class Board extends Base
|
|||
}
|
||||
}
|
||||
|
||||
$this->response->html($this->projectLayout('board/edit', array(
|
||||
'errors' => $errors,
|
||||
'values' => $values + array('project_id' => $project['id']),
|
||||
'columns' => $columns,
|
||||
'project' => $project,
|
||||
'title' => t('Edit board')
|
||||
)));
|
||||
$this->edit($values, $errors);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -269,7 +258,7 @@ class Board extends Base
|
|||
*/
|
||||
public function add()
|
||||
{
|
||||
$project = $this->getProjectManagement();
|
||||
$project = $this->getProject();
|
||||
$columns = $this->board->getColumnsList($project['id']);
|
||||
$data = $this->request->getValues();
|
||||
$values = array();
|
||||
|
@ -291,13 +280,7 @@ class Board extends Base
|
|||
}
|
||||
}
|
||||
|
||||
$this->response->html($this->projectLayout('board/edit', array(
|
||||
'errors' => $errors,
|
||||
'values' => $values + $data,
|
||||
'columns' => $columns,
|
||||
'project' => $project,
|
||||
'title' => t('Edit board')
|
||||
)));
|
||||
$this->edit($values, $errors);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -307,7 +290,7 @@ class Board extends Base
|
|||
*/
|
||||
public function remove()
|
||||
{
|
||||
$project = $this->getProjectManagement();
|
||||
$project = $this->getProject();
|
||||
|
||||
if ($this->request->getStringParam('remove') === 'yes') {
|
||||
|
||||
|
@ -339,35 +322,38 @@ class Board extends Base
|
|||
{
|
||||
$project_id = $this->request->getIntegerParam('project_id');
|
||||
|
||||
if ($project_id > 0 && $this->request->isAjax()) {
|
||||
|
||||
if (! $this->projectPermission->isUserAllowed($project_id, $this->acl->getUserId())) {
|
||||
$this->response->text('Forbidden', 403);
|
||||
}
|
||||
|
||||
$values = $this->request->getJson();
|
||||
|
||||
if ($this->taskPosition->movePosition($project_id, $values['task_id'], $values['column_id'], $values['position'])) {
|
||||
|
||||
$this->response->html(
|
||||
$this->template->load('board/show', array(
|
||||
'project' => $this->project->getById($project_id),
|
||||
'board' => $this->board->get($project_id),
|
||||
'categories' => $this->category->getList($project_id, false),
|
||||
'board_private_refresh_interval' => $this->config->get('board_private_refresh_interval'),
|
||||
'board_highlight_period' => $this->config->get('board_highlight_period'),
|
||||
)),
|
||||
201
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
||||
$this->response->status(400);
|
||||
}
|
||||
if (! $project_id || ! $this->request->isAjax()) {
|
||||
return $this->response->status(403);
|
||||
}
|
||||
else {
|
||||
$this->response->status(403);
|
||||
|
||||
if (! $this->projectPermission->isUserAllowed($project_id, $this->userSession->getId())) {
|
||||
$this->response->text('Forbidden', 403);
|
||||
}
|
||||
|
||||
$values = $this->request->getJson();
|
||||
|
||||
$result =$this->taskPosition->movePosition(
|
||||
$project_id,
|
||||
$values['task_id'],
|
||||
$values['column_id'],
|
||||
$values['position'],
|
||||
$values['swimlane_id']
|
||||
);
|
||||
|
||||
if (! $result) {
|
||||
return $this->response->status(400);
|
||||
}
|
||||
|
||||
$this->response->html(
|
||||
$this->template->render('board/show', array(
|
||||
'project' => $this->project->getById($project_id),
|
||||
'swimlanes' => $this->board->getBoard($project_id),
|
||||
'categories' => $this->category->getList($project_id, false),
|
||||
'board_private_refresh_interval' => $this->config->get('board_private_refresh_interval'),
|
||||
'board_highlight_period' => $this->config->get('board_highlight_period'),
|
||||
)),
|
||||
201
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -377,33 +363,30 @@ class Board extends Base
|
|||
*/
|
||||
public function check()
|
||||
{
|
||||
if ($this->request->isAjax()) {
|
||||
|
||||
$project_id = $this->request->getIntegerParam('project_id');
|
||||
$timestamp = $this->request->getIntegerParam('timestamp');
|
||||
|
||||
if ($project_id > 0 && ! $this->projectPermission->isUserAllowed($project_id, $this->acl->getUserId())) {
|
||||
$this->response->text('Forbidden', 403);
|
||||
}
|
||||
|
||||
if ($this->project->isModifiedSince($project_id, $timestamp)) {
|
||||
$this->response->html(
|
||||
$this->template->load('board/show', array(
|
||||
'project' => $this->project->getById($project_id),
|
||||
'board' => $this->board->get($project_id),
|
||||
'categories' => $this->category->getList($project_id, false),
|
||||
'board_private_refresh_interval' => $this->config->get('board_private_refresh_interval'),
|
||||
'board_highlight_period' => $this->config->get('board_highlight_period'),
|
||||
))
|
||||
);
|
||||
}
|
||||
else {
|
||||
$this->response->status(304);
|
||||
}
|
||||
if (! $this->request->isAjax()) {
|
||||
return $this->response->status(403);
|
||||
}
|
||||
else {
|
||||
$this->response->status(403);
|
||||
|
||||
$project_id = $this->request->getIntegerParam('project_id');
|
||||
$timestamp = $this->request->getIntegerParam('timestamp');
|
||||
|
||||
if (! $this->projectPermission->isUserAllowed($project_id, $this->userSession->getId())) {
|
||||
$this->response->text('Forbidden', 403);
|
||||
}
|
||||
|
||||
if (! $this->project->isModifiedSince($project_id, $timestamp)) {
|
||||
return $this->response->status(304);
|
||||
}
|
||||
|
||||
$this->response->html(
|
||||
$this->template->render('board/show', array(
|
||||
'project' => $this->project->getById($project_id),
|
||||
'swimlanes' => $this->board->getBoard($project_id),
|
||||
'categories' => $this->category->getList($project_id, false),
|
||||
'board_private_refresh_interval' => $this->config->get('board_private_refresh_interval'),
|
||||
'board_highlight_period' => $this->config->get('board_highlight_period'),
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -414,8 +397,9 @@ class Board extends Base
|
|||
public function subtasks()
|
||||
{
|
||||
$task = $this->getTask();
|
||||
$this->response->html($this->template->load('board/subtasks', array(
|
||||
'subtasks' => $this->subTask->getAll($task['id'])
|
||||
$this->response->html($this->template->render('board/subtasks', array(
|
||||
'subtasks' => $this->subTask->getAll($task['id']),
|
||||
'task' => $task,
|
||||
)));
|
||||
}
|
||||
|
||||
|
@ -429,8 +413,9 @@ class Board extends Base
|
|||
$task = $this->getTask();
|
||||
$this->subTask->toggleStatus($this->request->getIntegerParam('subtask_id'));
|
||||
|
||||
$this->response->html($this->template->load('board/subtasks', array(
|
||||
'subtasks' => $this->subTask->getAll($task['id'])
|
||||
$this->response->html($this->template->render('board/subtasks', array(
|
||||
'subtasks' => $this->subTask->getAll($task['id']),
|
||||
'task' => $task,
|
||||
)));
|
||||
}
|
||||
|
||||
|
@ -443,8 +428,9 @@ class Board extends Base
|
|||
{
|
||||
$task = $this->getTask();
|
||||
|
||||
$this->response->html($this->template->load('board/files', array(
|
||||
'files' => $this->file->getAll($task['id'])
|
||||
$this->response->html($this->template->render('board/files', array(
|
||||
'files' => $this->file->getAll($task['id']),
|
||||
'task' => $task,
|
||||
)));
|
||||
}
|
||||
|
||||
|
@ -457,7 +443,7 @@ class Board extends Base
|
|||
{
|
||||
$task = $this->getTask();
|
||||
|
||||
$this->response->html($this->template->load('board/comments', array(
|
||||
$this->response->html($this->template->render('board/comments', array(
|
||||
'comments' => $this->comment->getAll($task['id'])
|
||||
)));
|
||||
}
|
||||
|
@ -471,7 +457,7 @@ class Board extends Base
|
|||
{
|
||||
$task = $this->getTask();
|
||||
|
||||
$this->response->html($this->template->load('board/description', array(
|
||||
$this->response->html($this->template->render('board/description', array(
|
||||
'task' => $task
|
||||
)));
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ class Category extends Base
|
|||
* Get the category (common method between actions)
|
||||
*
|
||||
* @access private
|
||||
* @param $project_id
|
||||
* @param integer $project_id
|
||||
* @return array
|
||||
*/
|
||||
private function getCategory($project_id)
|
||||
|
@ -36,7 +36,7 @@ class Category extends Base
|
|||
*/
|
||||
public function index(array $values = array(), array $errors = array())
|
||||
{
|
||||
$project = $this->getProjectManagement();
|
||||
$project = $this->getProject();
|
||||
|
||||
$this->response->html($this->projectLayout('category/index', array(
|
||||
'categories' => $this->category->getList($project['id'], false),
|
||||
|
@ -48,13 +48,13 @@ class Category extends Base
|
|||
}
|
||||
|
||||
/**
|
||||
* Validate and save a new project
|
||||
* Validate and save a new category
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
$project = $this->getProjectManagement();
|
||||
$project = $this->getProject();
|
||||
|
||||
$values = $this->request->getValues();
|
||||
list($valid, $errors) = $this->category->validateCreation($values);
|
||||
|
@ -80,7 +80,7 @@ class Category extends Base
|
|||
*/
|
||||
public function edit(array $values = array(), array $errors = array())
|
||||
{
|
||||
$project = $this->getProjectManagement();
|
||||
$project = $this->getProject();
|
||||
$category = $this->getCategory($project['id']);
|
||||
|
||||
$this->response->html($this->projectLayout('category/edit', array(
|
||||
|
@ -98,7 +98,7 @@ class Category extends Base
|
|||
*/
|
||||
public function update()
|
||||
{
|
||||
$project = $this->getProjectManagement();
|
||||
$project = $this->getProject();
|
||||
|
||||
$values = $this->request->getValues();
|
||||
list($valid, $errors) = $this->category->validateModification($values);
|
||||
|
@ -124,7 +124,7 @@ class Category extends Base
|
|||
*/
|
||||
public function confirm()
|
||||
{
|
||||
$project = $this->getProjectManagement();
|
||||
$project = $this->getProject();
|
||||
$category = $this->getCategory($project['id']);
|
||||
|
||||
$this->response->html($this->projectLayout('category/remove', array(
|
||||
|
@ -142,7 +142,7 @@ class Category extends Base
|
|||
public function remove()
|
||||
{
|
||||
$this->checkCSRFParam();
|
||||
$project = $this->getProjectManagement();
|
||||
$project = $this->getProject();
|
||||
$category = $this->getCategory($project['id']);
|
||||
|
||||
if ($this->category->remove($category['id'])) {
|
||||
|
|
|
@ -24,7 +24,7 @@ class Comment extends Base
|
|||
$this->notfound();
|
||||
}
|
||||
|
||||
if (! $this->acl->isAdminUser() && $comment['user_id'] != $this->acl->getUserId()) {
|
||||
if (! $this->userSession->isAdmin() && $comment['user_id'] != $this->userSession->getId()) {
|
||||
$this->response->html($this->template->layout('comment/forbidden', array(
|
||||
'title' => t('Access Forbidden')
|
||||
)));
|
||||
|
@ -44,7 +44,7 @@ class Comment extends Base
|
|||
|
||||
if (empty($values)) {
|
||||
$values = array(
|
||||
'user_id' => $this->acl->getUserId(),
|
||||
'user_id' => $this->userSession->getId(),
|
||||
'task_id' => $task['id'],
|
||||
);
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ class Comment extends Base
|
|||
$this->session->flashError(t('Unable to create your comment.'));
|
||||
}
|
||||
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'#comments');
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id'].'#comments');
|
||||
}
|
||||
|
||||
$this->create($values, $errors);
|
||||
|
@ -125,7 +125,7 @@ class Comment extends Base
|
|||
$this->session->flashError(t('Unable to update your comment.'));
|
||||
}
|
||||
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'#comment-'.$comment['id']);
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id'].'#comment-'.$comment['id']);
|
||||
}
|
||||
|
||||
$this->edit($values, $errors);
|
||||
|
@ -166,6 +166,6 @@ class Comment extends Base
|
|||
$this->session->flashError(t('Unable to remove this comment.'));
|
||||
}
|
||||
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'#comments');
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id'].'#comments');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,10 +20,10 @@ class Config extends Base
|
|||
*/
|
||||
private function layout($template, array $params)
|
||||
{
|
||||
$params['board_selector'] = $this->projectPermission->getAllowedProjects($this->acl->getUserId());
|
||||
$params['board_selector'] = $this->projectPermission->getAllowedProjects($this->userSession->getId());
|
||||
$params['values'] = $this->config->getAll();
|
||||
$params['errors'] = array();
|
||||
$params['config_content_for_layout'] = $this->template->load($template, $params);
|
||||
$params['config_content_for_layout'] = $this->template->render($template, $params);
|
||||
|
||||
return $this->template->layout('config/layout', $params);
|
||||
}
|
||||
|
|
75
sources/app/Controller/Export.php
Normal file
75
sources/app/Controller/Export.php
Normal file
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
namespace Controller;
|
||||
|
||||
/**
|
||||
* Export controller
|
||||
*
|
||||
* @package controller
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class Export extends Base
|
||||
{
|
||||
/**
|
||||
* Common export method
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
private function common($model, $method, $filename, $action, $page_title)
|
||||
{
|
||||
$project = $this->getProject();
|
||||
$from = $this->request->getStringParam('from');
|
||||
$to = $this->request->getStringParam('to');
|
||||
|
||||
if ($from && $to) {
|
||||
$data = $this->$model->$method($project['id'], $from, $to);
|
||||
$this->response->forceDownload($filename.'.csv');
|
||||
$this->response->csv($data);
|
||||
}
|
||||
|
||||
$this->response->html($this->projectLayout('export/'.$action, array(
|
||||
'values' => array(
|
||||
'controller' => 'export',
|
||||
'action' => $action,
|
||||
'project_id' => $project['id'],
|
||||
'from' => $from,
|
||||
'to' => $to,
|
||||
),
|
||||
'errors' => array(),
|
||||
'date_format' => $this->config->get('application_date_format'),
|
||||
'date_formats' => $this->dateParser->getAvailableFormats(),
|
||||
'project' => $project,
|
||||
'title' => $page_title,
|
||||
)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Task export
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function tasks()
|
||||
{
|
||||
$this->common('taskExport', 'export', t('Tasks'), 'tasks', t('Tasks Export'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtask export
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function subtasks()
|
||||
{
|
||||
$this->common('subtaskExport', 'export', t('Subtasks'), 'subtasks', t('Subtasks Export'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Daily project summary export
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function summary()
|
||||
{
|
||||
$this->common('projectDailySummary', 'getAggregatedMetrics', t('Summary'), 'summary', t('Daily project summary export'));
|
||||
}
|
||||
}
|
|
@ -37,11 +37,11 @@ class File extends Base
|
|||
$task = $this->getTask();
|
||||
|
||||
if ($this->file->upload($task['project_id'], $task['id'], 'files') === true) {
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'#attachments');
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id'].'#attachments');
|
||||
}
|
||||
else {
|
||||
$this->session->flashError(t('Unable to upload the file.'));
|
||||
$this->response->redirect('?controller=file&action=create&task_id='.$task['id']);
|
||||
$this->response->redirect('?controller=file&action=create&task_id='.$task['id'].'&project_id='.$task['project_id']);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ class File extends Base
|
|||
$this->response->binary(file_get_contents($filename));
|
||||
}
|
||||
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id']);
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -75,8 +75,9 @@ class File extends Base
|
|||
$file = $this->file->getById($this->request->getIntegerParam('file_id'));
|
||||
|
||||
if ($file['task_id'] == $task['id']) {
|
||||
$this->response->html($this->template->load('file/open', array(
|
||||
'file' => $file
|
||||
$this->response->html($this->template->render('file/open', array(
|
||||
'file' => $file,
|
||||
'task' => $task,
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
@ -119,7 +120,7 @@ class File extends Base
|
|||
$this->session->flashError(t('Unable to remove this file.'));
|
||||
}
|
||||
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id']);
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
namespace Controller;
|
||||
|
||||
use Model\Task as TaskModel;
|
||||
|
||||
/**
|
||||
* Project controller
|
||||
*
|
||||
|
@ -19,7 +17,7 @@ class Project extends Base
|
|||
*/
|
||||
public function index()
|
||||
{
|
||||
$projects = $this->project->getAll($this->acl->isRegularUser());
|
||||
$projects = $this->project->getAll(! $this->userSession->isAdmin());
|
||||
$nb_projects = count($projects);
|
||||
$active_projects = array();
|
||||
$inactive_projects = array();
|
||||
|
@ -34,7 +32,7 @@ class Project extends Base
|
|||
}
|
||||
|
||||
$this->response->html($this->template->layout('project/index', array(
|
||||
'board_selector' => $this->projectPermission->getAllowedProjects($this->acl->getUserId()),
|
||||
'board_selector' => $this->projectPermission->getAllowedProjects($this->userSession->getId()),
|
||||
'active_projects' => $active_projects,
|
||||
'inactive_projects' => $inactive_projects,
|
||||
'nb_projects' => $nb_projects,
|
||||
|
@ -54,77 +52,10 @@ class Project extends Base
|
|||
$this->response->html($this->projectLayout('project/show', array(
|
||||
'project' => $project,
|
||||
'stats' => $this->project->getStats($project['id']),
|
||||
'webhook_token' => $this->config->get('webhook_token'),
|
||||
'title' => $project['name'],
|
||||
)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Task export
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function exportTasks()
|
||||
{
|
||||
$project = $this->getProjectManagement();
|
||||
$from = $this->request->getStringParam('from');
|
||||
$to = $this->request->getStringParam('to');
|
||||
|
||||
if ($from && $to) {
|
||||
$data = $this->taskExport->export($project['id'], $from, $to);
|
||||
$this->response->forceDownload('Tasks_'.date('Y_m_d_H_i').'.csv');
|
||||
$this->response->csv($data);
|
||||
}
|
||||
|
||||
$this->response->html($this->projectLayout('project/export_tasks', array(
|
||||
'values' => array(
|
||||
'controller' => 'project',
|
||||
'action' => 'exportTasks',
|
||||
'project_id' => $project['id'],
|
||||
'from' => $from,
|
||||
'to' => $to,
|
||||
),
|
||||
'errors' => array(),
|
||||
'date_format' => $this->config->get('application_date_format'),
|
||||
'date_formats' => $this->dateParser->getAvailableFormats(),
|
||||
'project' => $project,
|
||||
'title' => t('Tasks Export')
|
||||
)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Daily project summary export
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function exportDailyProjectSummary()
|
||||
{
|
||||
$project = $this->getProjectManagement();
|
||||
$from = $this->request->getStringParam('from');
|
||||
$to = $this->request->getStringParam('to');
|
||||
|
||||
if ($from && $to) {
|
||||
$data = $this->projectDailySummary->getAggregatedMetrics($project['id'], $from, $to);
|
||||
$this->response->forceDownload('Daily_Summary_'.date('Y_m_d_H_i').'.csv');
|
||||
$this->response->csv($data);
|
||||
}
|
||||
|
||||
$this->response->html($this->projectLayout('project/export_daily_summary', array(
|
||||
'values' => array(
|
||||
'controller' => 'project',
|
||||
'action' => 'exportDailyProjectSummary',
|
||||
'project_id' => $project['id'],
|
||||
'from' => $from,
|
||||
'to' => $to,
|
||||
),
|
||||
'errors' => array(),
|
||||
'date_format' => $this->config->get('application_date_format'),
|
||||
'date_formats' => $this->dateParser->getAvailableFormats(),
|
||||
'project' => $project,
|
||||
'title' => t('Daily project summary export')
|
||||
)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Public access management
|
||||
*
|
||||
|
@ -132,7 +63,7 @@ class Project extends Base
|
|||
*/
|
||||
public function share()
|
||||
{
|
||||
$project = $this->getProjectManagement();
|
||||
$project = $this->getProject();
|
||||
$switch = $this->request->getStringParam('switch');
|
||||
|
||||
if ($switch === 'enable' || $switch === 'disable') {
|
||||
|
@ -154,6 +85,22 @@ class Project extends Base
|
|||
)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Integrations page
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function integration()
|
||||
{
|
||||
$project = $this->getProject();
|
||||
|
||||
$this->response->html($this->projectLayout('project/integrations', array(
|
||||
'project' => $project,
|
||||
'title' => t('Integrations'),
|
||||
'webhook_token' => $this->config->get('webhook_token'),
|
||||
)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a form to edit a project
|
||||
*
|
||||
|
@ -161,7 +108,7 @@ class Project extends Base
|
|||
*/
|
||||
public function edit(array $values = array(), array $errors = array())
|
||||
{
|
||||
$project = $this->getProjectManagement();
|
||||
$project = $this->getProject();
|
||||
|
||||
$this->response->html($this->projectLayout('project/edit', array(
|
||||
'values' => empty($values) ? $project : $values,
|
||||
|
@ -178,7 +125,7 @@ class Project extends Base
|
|||
*/
|
||||
public function update()
|
||||
{
|
||||
$project = $this->getProjectManagement();
|
||||
$project = $this->getProject();
|
||||
$values = $this->request->getValues();
|
||||
list($valid, $errors) = $this->project->validateModification($values);
|
||||
|
||||
|
@ -203,7 +150,7 @@ class Project extends Base
|
|||
*/
|
||||
public function users()
|
||||
{
|
||||
$project = $this->getProjectManagement();
|
||||
$project = $this->getProject();
|
||||
|
||||
$this->response->html($this->projectLayout('project/users', array(
|
||||
'project' => $project,
|
||||
|
@ -219,7 +166,7 @@ class Project extends Base
|
|||
*/
|
||||
public function allowEverybody()
|
||||
{
|
||||
$project = $this->getProjectManagement();
|
||||
$project = $this->getProject();
|
||||
$values = $this->request->getValues() + array('is_everybody_allowed' => 0);
|
||||
list($valid,) = $this->projectPermission->validateProjectModification($values);
|
||||
|
||||
|
@ -248,7 +195,37 @@ class Project extends Base
|
|||
|
||||
if ($valid) {
|
||||
|
||||
if ($this->projectPermission->allowUser($values['project_id'], $values['user_id'])) {
|
||||
if ($this->projectPermission->addMember($values['project_id'], $values['user_id'])) {
|
||||
$this->session->flash(t('Project updated successfully.'));
|
||||
}
|
||||
else {
|
||||
$this->session->flashError(t('Unable to update this project.'));
|
||||
}
|
||||
}
|
||||
|
||||
$this->response->redirect('?controller=project&action=users&project_id='.$values['project_id']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the role of a project member
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function role()
|
||||
{
|
||||
$this->checkCSRFParam();
|
||||
|
||||
$values = array(
|
||||
'project_id' => $this->request->getIntegerParam('project_id'),
|
||||
'user_id' => $this->request->getIntegerParam('user_id'),
|
||||
'is_owner' => $this->request->getIntegerParam('is_owner'),
|
||||
);
|
||||
|
||||
list($valid,) = $this->projectPermission->validateUserModification($values);
|
||||
|
||||
if ($valid) {
|
||||
|
||||
if ($this->projectPermission->changeRole($values['project_id'], $values['user_id'], $values['is_owner'])) {
|
||||
$this->session->flash(t('Project updated successfully.'));
|
||||
}
|
||||
else {
|
||||
|
@ -277,7 +254,7 @@ class Project extends Base
|
|||
|
||||
if ($valid) {
|
||||
|
||||
if ($this->projectPermission->revokeUser($values['project_id'], $values['user_id'])) {
|
||||
if ($this->projectPermission->revokeMember($values['project_id'], $values['user_id'])) {
|
||||
$this->session->flash(t('Project updated successfully.'));
|
||||
}
|
||||
else {
|
||||
|
@ -295,7 +272,7 @@ class Project extends Base
|
|||
*/
|
||||
public function remove()
|
||||
{
|
||||
$project = $this->getProjectManagement();
|
||||
$project = $this->getProject();
|
||||
|
||||
if ($this->request->getStringParam('remove') === 'yes') {
|
||||
|
||||
|
@ -324,7 +301,7 @@ class Project extends Base
|
|||
*/
|
||||
public function duplicate()
|
||||
{
|
||||
$project = $this->getProjectManagement();
|
||||
$project = $this->getProject();
|
||||
|
||||
if ($this->request->getStringParam('duplicate') === 'yes') {
|
||||
|
||||
|
@ -352,7 +329,7 @@ class Project extends Base
|
|||
*/
|
||||
public function disable()
|
||||
{
|
||||
$project = $this->getProjectManagement();
|
||||
$project = $this->getProject();
|
||||
|
||||
if ($this->request->getStringParam('disable') === 'yes') {
|
||||
|
||||
|
@ -380,7 +357,7 @@ class Project extends Base
|
|||
*/
|
||||
public function enable()
|
||||
{
|
||||
$project = $this->getProjectManagement();
|
||||
$project = $this->getProject();
|
||||
|
||||
if ($this->request->getStringParam('enable') === 'yes') {
|
||||
|
||||
|
@ -416,7 +393,7 @@ class Project extends Base
|
|||
$this->forbidden(true);
|
||||
}
|
||||
|
||||
$this->response->xml($this->template->load('project/feed', array(
|
||||
$this->response->xml($this->template->render('project/feed', array(
|
||||
'events' => $this->projectActivity->getProject($project['id']),
|
||||
'project' => $project,
|
||||
)));
|
||||
|
@ -432,7 +409,7 @@ class Project extends Base
|
|||
$project = $this->getProject();
|
||||
|
||||
$this->response->html($this->template->layout('project/activity', array(
|
||||
'board_selector' => $this->projectPermission->getAllowedProjects($this->acl->getUserId()),
|
||||
'board_selector' => $this->projectPermission->getAllowedProjects($this->userSession->getId()),
|
||||
'events' => $this->projectActivity->getProject($project['id']),
|
||||
'project' => $project,
|
||||
'title' => t('%s\'s activity', $project['name'])
|
||||
|
@ -461,7 +438,7 @@ class Project extends Base
|
|||
}
|
||||
|
||||
$this->response->html($this->template->layout('project/search', array(
|
||||
'board_selector' => $this->projectPermission->getAllowedProjects($this->acl->getUserId()),
|
||||
'board_selector' => $this->projectPermission->getAllowedProjects($this->userSession->getId()),
|
||||
'tasks' => $tasks,
|
||||
'nb_tasks' => $nb_tasks,
|
||||
'pagination' => array(
|
||||
|
@ -504,7 +481,7 @@ class Project extends Base
|
|||
$nb_tasks = $this->taskPaginator->countClosedTasks($project['id']);
|
||||
|
||||
$this->response->html($this->template->layout('project/tasks', array(
|
||||
'board_selector' => $this->projectPermission->getAllowedProjects($this->acl->getUserId()),
|
||||
'board_selector' => $this->projectPermission->getAllowedProjects($this->userSession->getId()),
|
||||
'pagination' => array(
|
||||
'controller' => 'project',
|
||||
'action' => 'tasks',
|
||||
|
@ -531,10 +508,10 @@ class Project extends Base
|
|||
*/
|
||||
public function create(array $values = array(), array $errors = array())
|
||||
{
|
||||
$is_private = $this->request->getIntegerParam('private', $this->acl->isRegularUser());
|
||||
$is_private = $this->request->getIntegerParam('private', $this->userSession->isAdmin() ? 0 : 1);
|
||||
|
||||
$this->response->html($this->template->layout('project/new', array(
|
||||
'board_selector' => $this->projectPermission->getAllowedProjects($this->acl->getUserId()),
|
||||
'board_selector' => $this->projectPermission->getAllowedProjects($this->userSession->getId()),
|
||||
'values' => empty($values) ? array('is_private' => $is_private) : $values,
|
||||
'errors' => $errors,
|
||||
'title' => $is_private ? t('New private project') : t('New project'),
|
||||
|
@ -553,7 +530,7 @@ class Project extends Base
|
|||
|
||||
if ($valid) {
|
||||
|
||||
$project_id = $this->project->create($values, $this->acl->getUserId(), true);
|
||||
$project_id = $this->project->create($values, $this->userSession->getId(), true);
|
||||
|
||||
if ($project_id) {
|
||||
$this->session->flash(t('Your project have been created successfully.'));
|
||||
|
|
|
@ -73,10 +73,10 @@ class Subtask extends Base
|
|||
}
|
||||
|
||||
if (isset($values['another_subtask']) && $values['another_subtask'] == 1) {
|
||||
$this->response->redirect('?controller=subtask&action=create&task_id='.$task['id'].'&another_subtask=1');
|
||||
$this->response->redirect('?controller=subtask&action=create&task_id='.$task['id'].'&another_subtask=1&project_id='.$task['project_id']);
|
||||
}
|
||||
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'#subtasks');
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id'].'#subtasks');
|
||||
}
|
||||
|
||||
$this->create($values, $errors);
|
||||
|
@ -110,7 +110,7 @@ class Subtask extends Base
|
|||
public function update()
|
||||
{
|
||||
$task = $this->getTask();
|
||||
$subtask = $this->getSubtask();
|
||||
$this->getSubtask();
|
||||
|
||||
$values = $this->request->getValues();
|
||||
list($valid, $errors) = $this->subTask->validateModification($values);
|
||||
|
@ -124,7 +124,7 @@ class Subtask extends Base
|
|||
$this->session->flashError(t('Unable to update your sub-task.'));
|
||||
}
|
||||
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'#subtasks');
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id'].'#subtasks');
|
||||
}
|
||||
|
||||
$this->edit($values, $errors);
|
||||
|
@ -164,7 +164,7 @@ class Subtask extends Base
|
|||
$this->session->flashError(t('Unable to remove this sub-task.'));
|
||||
}
|
||||
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'#subtasks');
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id'].'#subtasks');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -181,6 +181,6 @@ class Subtask extends Base
|
|||
$this->session->flashError(t('Unable to update your sub-task.'));
|
||||
}
|
||||
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'#subtasks');
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id'].'#subtasks');
|
||||
}
|
||||
}
|
||||
|
|
256
sources/app/Controller/Swimlane.php
Normal file
256
sources/app/Controller/Swimlane.php
Normal file
|
@ -0,0 +1,256 @@
|
|||
<?php
|
||||
|
||||
namespace Controller;
|
||||
|
||||
use Model\Swimlane as SwimlaneModel;
|
||||
|
||||
/**
|
||||
* Swimlanes
|
||||
*
|
||||
* @package controller
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class Swimlane extends Base
|
||||
{
|
||||
/**
|
||||
* Get the swimlane (common method between actions)
|
||||
*
|
||||
* @access private
|
||||
* @param integer $project_id
|
||||
* @return array
|
||||
*/
|
||||
private function getSwimlane($project_id)
|
||||
{
|
||||
$swimlane = $this->swimlane->getById($this->request->getIntegerParam('swimlane_id'));
|
||||
|
||||
if (! $swimlane) {
|
||||
$this->session->flashError(t('Swimlane not found.'));
|
||||
$this->response->redirect('?controller=swimlane&action=index&project_id='.$project_id);
|
||||
}
|
||||
|
||||
return $swimlane;
|
||||
}
|
||||
|
||||
/**
|
||||
* List of swimlanes for a given project
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function index(array $values = array(), array $errors = array())
|
||||
{
|
||||
$project = $this->getProject();
|
||||
|
||||
$this->response->html($this->projectLayout('swimlane/index', array(
|
||||
'default_swimlane' => $this->swimlane->getDefault($project['id']),
|
||||
'active_swimlanes' => $this->swimlane->getAllByStatus($project['id'], SwimlaneModel::ACTIVE),
|
||||
'inactive_swimlanes' => $this->swimlane->getAllByStatus($project['id'], SwimlaneModel::INACTIVE),
|
||||
'values' => $values + array('project_id' => $project['id']),
|
||||
'errors' => $errors,
|
||||
'project' => $project,
|
||||
'title' => t('Swimlanes')
|
||||
)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate and save a new swimlane
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
$project = $this->getProject();
|
||||
|
||||
$values = $this->request->getValues();
|
||||
list($valid, $errors) = $this->swimlane->validateCreation($values);
|
||||
|
||||
if ($valid) {
|
||||
|
||||
if ($this->swimlane->create($project['id'], $values['name'])) {
|
||||
$this->session->flash(t('Your swimlane have been created successfully.'));
|
||||
$this->response->redirect('?controller=swimlane&action=index&project_id='.$project['id']);
|
||||
}
|
||||
else {
|
||||
$this->session->flashError(t('Unable to create your swimlane.'));
|
||||
}
|
||||
}
|
||||
|
||||
$this->index($values, $errors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the default swimlane
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function change()
|
||||
{
|
||||
$project = $this->getProject();
|
||||
|
||||
$values = $this->request->getValues();
|
||||
list($valid,) = $this->swimlane->validateDefaultModification($values);
|
||||
|
||||
if ($valid) {
|
||||
|
||||
if ($this->swimlane->updateDefault($values)) {
|
||||
$this->session->flash(t('The default swimlane have been updated successfully.'));
|
||||
$this->response->redirect('?controller=swimlane&action=index&project_id='.$project['id']);
|
||||
}
|
||||
else {
|
||||
$this->session->flashError(t('Unable to update this swimlane.'));
|
||||
}
|
||||
}
|
||||
|
||||
$this->index();
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit a swimlane (display the form)
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function edit(array $values = array(), array $errors = array())
|
||||
{
|
||||
$project = $this->getProject();
|
||||
$swimlane = $this->getSwimlane($project['id']);
|
||||
|
||||
$this->response->html($this->projectLayout('swimlane/edit', array(
|
||||
'values' => empty($values) ? $swimlane : $values,
|
||||
'errors' => $errors,
|
||||
'project' => $project,
|
||||
'title' => t('Swimlanes')
|
||||
)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit a swimlane (validate the form and update the database)
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function update()
|
||||
{
|
||||
$project = $this->getProject();
|
||||
|
||||
$values = $this->request->getValues();
|
||||
list($valid, $errors) = $this->swimlane->validateModification($values);
|
||||
|
||||
if ($valid) {
|
||||
|
||||
if ($this->swimlane->rename($values['id'], $values['name'])) {
|
||||
$this->session->flash(t('Swimlane updated successfully.'));
|
||||
$this->response->redirect('?controller=swimlane&action=index&project_id='.$project['id']);
|
||||
}
|
||||
else {
|
||||
$this->session->flashError(t('Unable to update this swimlane.'));
|
||||
}
|
||||
}
|
||||
|
||||
$this->edit($values, $errors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirmation dialog before removing a swimlane
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function confirm()
|
||||
{
|
||||
$project = $this->getProject();
|
||||
$swimlane = $this->getSwimlane($project['id']);
|
||||
|
||||
$this->response->html($this->projectLayout('swimlane/remove', array(
|
||||
'project' => $project,
|
||||
'swimlane' => $swimlane,
|
||||
'title' => t('Remove a swimlane')
|
||||
)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a swimlane
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function remove()
|
||||
{
|
||||
$this->checkCSRFParam();
|
||||
$project = $this->getProject();
|
||||
$swimlane_id = $this->request->getIntegerParam('swimlane_id');
|
||||
|
||||
if ($this->swimlane->remove($project['id'], $swimlane_id)) {
|
||||
$this->session->flash(t('Swimlane removed successfully.'));
|
||||
} else {
|
||||
$this->session->flashError(t('Unable to remove this swimlane.'));
|
||||
}
|
||||
|
||||
$this->response->redirect('?controller=swimlane&action=index&project_id='.$project['id']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable a swimlane
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function disable()
|
||||
{
|
||||
$this->checkCSRFParam();
|
||||
$project = $this->getProject();
|
||||
$swimlane_id = $this->request->getIntegerParam('swimlane_id');
|
||||
|
||||
if ($this->swimlane->disable($project['id'], $swimlane_id)) {
|
||||
$this->session->flash(t('Swimlane updated successfully.'));
|
||||
} else {
|
||||
$this->session->flashError(t('Unable to update this swimlane.'));
|
||||
}
|
||||
|
||||
$this->response->redirect('?controller=swimlane&action=index&project_id='.$project['id']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable a swimlane
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function enable()
|
||||
{
|
||||
$this->checkCSRFParam();
|
||||
$project = $this->getProject();
|
||||
$swimlane_id = $this->request->getIntegerParam('swimlane_id');
|
||||
|
||||
if ($this->swimlane->enable($project['id'], $swimlane_id)) {
|
||||
$this->session->flash(t('Swimlane updated successfully.'));
|
||||
} else {
|
||||
$this->session->flashError(t('Unable to update this swimlane.'));
|
||||
}
|
||||
|
||||
$this->response->redirect('?controller=swimlane&action=index&project_id='.$project['id']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move up a swimlane
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function moveup()
|
||||
{
|
||||
$this->checkCSRFParam();
|
||||
$project = $this->getProject();
|
||||
$swimlane_id = $this->request->getIntegerParam('swimlane_id');
|
||||
|
||||
$this->swimlane->moveUp($project['id'], $swimlane_id);
|
||||
$this->response->redirect('?controller=swimlane&action=index&project_id='.$project['id']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move down a swimlane
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function movedown()
|
||||
{
|
||||
$this->checkCSRFParam();
|
||||
$project = $this->getProject();
|
||||
$swimlane_id = $this->request->getIntegerParam('swimlane_id');
|
||||
|
||||
$this->swimlane->moveDown($project['id'], $swimlane_id);
|
||||
$this->response->redirect('?controller=swimlane&action=index&project_id='.$project['id']);
|
||||
}
|
||||
}
|
|
@ -89,11 +89,12 @@ class Task extends Base
|
|||
public function create(array $values = array(), array $errors = array())
|
||||
{
|
||||
$project = $this->getProject();
|
||||
$method = $this->request->isAjax() ? 'load' : 'layout';
|
||||
$method = $this->request->isAjax() ? 'render' : 'layout';
|
||||
|
||||
if (empty($values)) {
|
||||
|
||||
$values = array(
|
||||
'swimlane_id' => $this->request->getIntegerParam('swimlane_id'),
|
||||
'column_id' => $this->request->getIntegerParam('column_id'),
|
||||
'color_id' => $this->request->getStringParam('color_id'),
|
||||
'owner_id' => $this->request->getIntegerParam('owner_id'),
|
||||
|
@ -125,9 +126,7 @@ class Task extends Base
|
|||
{
|
||||
$project = $this->getProject();
|
||||
$values = $this->request->getValues();
|
||||
$values['creator_id'] = $this->acl->getUserId();
|
||||
|
||||
$this->checkProjectPermissions($project['id']);
|
||||
$values['creator_id'] = $this->userSession->getId();
|
||||
|
||||
list($valid, $errors) = $this->taskValidator->validateCreation($values);
|
||||
|
||||
|
@ -142,7 +141,7 @@ class Task extends Base
|
|||
$this->response->redirect('?controller=task&action=create&'.http_build_query($values));
|
||||
}
|
||||
else {
|
||||
$this->response->redirect('?controller=board&action=show&project_id='.$values['project_id']);
|
||||
$this->response->redirect('?controller=board&action=show&project_id='.$project['id']);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -158,16 +157,20 @@ class Task extends Base
|
|||
*
|
||||
* @access public
|
||||
*/
|
||||
public function edit()
|
||||
public function edit(array $values = array(), array $errors = array())
|
||||
{
|
||||
$task = $this->getTask();
|
||||
$ajax = $this->request->isAjax();
|
||||
|
||||
$this->dateParser->format($task, array('date_due'));
|
||||
if (empty($values)) {
|
||||
$values = $task;
|
||||
}
|
||||
|
||||
$this->dateParser->format($values, array('date_due'));
|
||||
|
||||
$params = array(
|
||||
'values' => $task,
|
||||
'errors' => array(),
|
||||
'values' => $values,
|
||||
'errors' => $errors,
|
||||
'task' => $task,
|
||||
'users_list' => $this->projectPermission->getMemberList($task['project_id']),
|
||||
'colors_list' => $this->color->getList(),
|
||||
|
@ -178,7 +181,7 @@ class Task extends Base
|
|||
);
|
||||
|
||||
if ($ajax) {
|
||||
$this->response->html($this->template->load('task/edit', $params));
|
||||
$this->response->html($this->template->render('task/edit', $params));
|
||||
}
|
||||
else {
|
||||
$this->response->html($this->taskLayout('task/edit', $params));
|
||||
|
@ -206,7 +209,7 @@ class Task extends Base
|
|||
$this->response->redirect('?controller=board&action=show&project_id='.$task['project_id']);
|
||||
}
|
||||
else {
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id']);
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id']);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -214,18 +217,7 @@ class Task extends Base
|
|||
}
|
||||
}
|
||||
|
||||
$this->response->html($this->taskLayout('task/edit', array(
|
||||
'values' => $values,
|
||||
'errors' => $errors,
|
||||
'task' => $task,
|
||||
'columns_list' => $this->board->getColumnsList($values['project_id']),
|
||||
'users_list' => $this->projectPermission->getMemberList($values['project_id']),
|
||||
'colors_list' => $this->color->getList(),
|
||||
'categories_list' => $this->category->getList($values['project_id']),
|
||||
'date_format' => $this->config->get('application_date_format'),
|
||||
'date_formats' => $this->dateParser->getAvailableFormats(),
|
||||
'ajax' => $this->request->isAjax(),
|
||||
)));
|
||||
$this->edit($values, $errors);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -247,7 +239,7 @@ class Task extends Base
|
|||
$this->session->flashError(t('Unable to update your task.'));
|
||||
}
|
||||
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id']);
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -269,7 +261,7 @@ class Task extends Base
|
|||
$this->session->flashError(t('Unable to close this task.'));
|
||||
}
|
||||
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id']);
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id']);
|
||||
}
|
||||
|
||||
$this->response->html($this->taskLayout('task/close', array(
|
||||
|
@ -296,7 +288,7 @@ class Task extends Base
|
|||
$this->session->flashError(t('Unable to open this task.'));
|
||||
}
|
||||
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id']);
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id']);
|
||||
}
|
||||
|
||||
$this->response->html($this->taskLayout('task/open', array(
|
||||
|
@ -351,10 +343,10 @@ class Task extends Base
|
|||
|
||||
if ($task_id) {
|
||||
$this->session->flash(t('Task created successfully.'));
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task_id);
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task_id.'&project_id='.$task['project_id']);
|
||||
} else {
|
||||
$this->session->flashError(t('Unable to create this task.'));
|
||||
$this->response->redirect('?controller=task&action=duplicate&task_id='.$task['id']);
|
||||
$this->response->redirect('?controller=task&action=duplicate&task_id='.$task['id'].'&project_id='.$task['project_id']);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -392,7 +384,7 @@ class Task extends Base
|
|||
$this->response->redirect('?controller=board&action=show&project_id='.$task['project_id']);
|
||||
}
|
||||
else {
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id']);
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -409,7 +401,7 @@ class Task extends Base
|
|||
);
|
||||
|
||||
if ($ajax) {
|
||||
$this->response->html($this->template->load('task/edit_description', $params));
|
||||
$this->response->html($this->template->render('task/edit_description', $params));
|
||||
}
|
||||
else {
|
||||
$this->response->html($this->taskLayout('task/edit_description', $params));
|
||||
|
@ -426,7 +418,7 @@ class Task extends Base
|
|||
$task = $this->getTask();
|
||||
$values = $task;
|
||||
$errors = array();
|
||||
$projects_list = $this->projectPermission->getMemberProjects($this->acl->getUserId());
|
||||
$projects_list = $this->projectPermission->getMemberProjects($this->userSession->getId());
|
||||
|
||||
unset($projects_list[$task['project_id']]);
|
||||
|
||||
|
@ -439,7 +431,7 @@ class Task extends Base
|
|||
|
||||
if ($this->taskDuplication->moveToProject($task['id'], $values['project_id'])) {
|
||||
$this->session->flash(t('Task updated successfully.'));
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id']);
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$values['project_id']);
|
||||
}
|
||||
else {
|
||||
$this->session->flashError(t('Unable to update your task.'));
|
||||
|
@ -465,7 +457,7 @@ class Task extends Base
|
|||
$task = $this->getTask();
|
||||
$values = $task;
|
||||
$errors = array();
|
||||
$projects_list = $this->projectPermission->getMemberProjects($this->acl->getUserId());
|
||||
$projects_list = $this->projectPermission->getMemberProjects($this->userSession->getId());
|
||||
|
||||
unset($projects_list[$task['project_id']]);
|
||||
|
||||
|
@ -478,7 +470,7 @@ class Task extends Base
|
|||
$task_id = $this->taskDuplication->duplicateToProject($task['id'], $values['project_id']);
|
||||
if ($task_id) {
|
||||
$this->session->flash(t('Task created successfully.'));
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task_id);
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task_id.'&project_id='.$values['project_id']);
|
||||
}
|
||||
else {
|
||||
$this->session->flashError(t('Unable to create your task.'));
|
||||
|
|
|
@ -18,7 +18,7 @@ class User extends Base
|
|||
public function logout()
|
||||
{
|
||||
$this->checkCSRFParam();
|
||||
$this->authentication->backend('rememberMe')->destroy($this->acl->getUserId());
|
||||
$this->authentication->backend('rememberMe')->destroy($this->userSession->getId());
|
||||
$this->session->close();
|
||||
$this->response->redirect('?controller=user&action=login');
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ class User extends Base
|
|||
*/
|
||||
public function login(array $values = array(), array $errors = array())
|
||||
{
|
||||
if ($this->acl->isLogged()) {
|
||||
if ($this->userSession->isLogged()) {
|
||||
$this->response->redirect('?controller=app');
|
||||
}
|
||||
|
||||
|
@ -76,9 +76,9 @@ class User extends Base
|
|||
*/
|
||||
private function layout($template, array $params)
|
||||
{
|
||||
$content = $this->template->load($template, $params);
|
||||
$content = $this->template->render($template, $params);
|
||||
$params['user_content_for_layout'] = $content;
|
||||
$params['board_selector'] = $this->projectPermission->getAllowedProjects($this->acl->getUserId());
|
||||
$params['board_selector'] = $this->projectPermission->getAllowedProjects($this->userSession->getId());
|
||||
|
||||
if (isset($params['user'])) {
|
||||
$params['title'] = ($params['user']['name'] ?: $params['user']['username']).' (#'.$params['user']['id'].')';
|
||||
|
@ -101,7 +101,7 @@ class User extends Base
|
|||
$this->notfound();
|
||||
}
|
||||
|
||||
if ($this->acl->isRegularUser() && $this->acl->getUserId() != $user['id']) {
|
||||
if (! $this->userSession->isAdmin() && $this->userSession->getId() != $user['id']) {
|
||||
$this->forbidden();
|
||||
}
|
||||
|
||||
|
@ -125,7 +125,7 @@ class User extends Base
|
|||
|
||||
$this->response->html(
|
||||
$this->template->layout('user/index', array(
|
||||
'board_selector' => $this->projectPermission->getAllowedProjects($this->acl->getUserId()),
|
||||
'board_selector' => $this->projectPermission->getAllowedProjects($this->userSession->getId()),
|
||||
'projects' => $this->project->getList(),
|
||||
'nb_users' => $nb_users,
|
||||
'users' => $users,
|
||||
|
@ -151,7 +151,9 @@ class User extends Base
|
|||
public function create(array $values = array(), array $errors = array())
|
||||
{
|
||||
$this->response->html($this->template->layout('user/new', array(
|
||||
'board_selector' => $this->projectPermission->getAllowedProjects($this->acl->getUserId()),
|
||||
'timezones' => $this->config->getTimezones(true),
|
||||
'languages' => $this->config->getLanguages(true),
|
||||
'board_selector' => $this->projectPermission->getAllowedProjects($this->userSession->getId()),
|
||||
'projects' => $this->project->getList(),
|
||||
'errors' => $errors,
|
||||
'values' => $values,
|
||||
|
@ -194,6 +196,8 @@ class User extends Base
|
|||
$this->response->html($this->layout('user/show', array(
|
||||
'projects' => $this->projectPermission->getAllowedProjects($user['id']),
|
||||
'user' => $user,
|
||||
'timezones' => $this->config->getTimezones(true),
|
||||
'languages' => $this->config->getLanguages(true),
|
||||
)));
|
||||
}
|
||||
|
||||
|
@ -328,7 +332,7 @@ class User extends Base
|
|||
|
||||
$values = $this->request->getValues();
|
||||
|
||||
if ($this->acl->isAdminUser()) {
|
||||
if ($this->userSession->isAdmin()) {
|
||||
$values += array('is_admin' => 0);
|
||||
}
|
||||
else {
|
||||
|
@ -358,6 +362,8 @@ class User extends Base
|
|||
'errors' => $errors,
|
||||
'projects' => $this->projectPermission->filterProjects($this->project->getList(), $user['id']),
|
||||
'user' => $user,
|
||||
'timezones' => $this->config->getTimezones(true),
|
||||
'languages' => $this->config->getLanguages(true),
|
||||
)));
|
||||
}
|
||||
|
||||
|
@ -404,16 +410,16 @@ class User extends Base
|
|||
if (is_array($profile)) {
|
||||
|
||||
// If the user is already logged, link the account otherwise authenticate
|
||||
if ($this->acl->isLogged()) {
|
||||
if ($this->userSession->isLogged()) {
|
||||
|
||||
if ($this->authentication->backend('google')->updateUser($this->acl->getUserId(), $profile)) {
|
||||
if ($this->authentication->backend('google')->updateUser($this->userSession->getId(), $profile)) {
|
||||
$this->session->flash(t('Your Google Account is linked to your profile successfully.'));
|
||||
}
|
||||
else {
|
||||
$this->session->flashError(t('Unable to link your Google Account.'));
|
||||
}
|
||||
|
||||
$this->response->redirect('?controller=user&action=external&user_id='.$this->acl->getUserId());
|
||||
$this->response->redirect('?controller=user&action=external&user_id='.$this->userSession->getId());
|
||||
}
|
||||
else if ($this->authentication->backend('google')->authenticate($profile['id'])) {
|
||||
$this->response->redirect('?controller=app');
|
||||
|
@ -441,14 +447,14 @@ class User extends Base
|
|||
public function unlinkGoogle()
|
||||
{
|
||||
$this->checkCSRFParam();
|
||||
if ($this->authentication->backend('google')->unlink($this->acl->getUserId())) {
|
||||
if ($this->authentication->backend('google')->unlink($this->userSession->getId())) {
|
||||
$this->session->flash(t('Your Google Account is not linked anymore to your profile.'));
|
||||
}
|
||||
else {
|
||||
$this->session->flashError(t('Unable to unlink your Google Account.'));
|
||||
}
|
||||
|
||||
$this->response->redirect('?controller=user&action=external&user_id='.$this->acl->getUserId());
|
||||
$this->response->redirect('?controller=user&action=external&user_id='.$this->userSession->getId());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -466,16 +472,16 @@ class User extends Base
|
|||
if (is_array($profile)) {
|
||||
|
||||
// If the user is already logged, link the account otherwise authenticate
|
||||
if ($this->acl->isLogged()) {
|
||||
if ($this->userSession->isLogged()) {
|
||||
|
||||
if ($this->authentication->backend('gitHub')->updateUser($this->acl->getUserId(), $profile)) {
|
||||
if ($this->authentication->backend('gitHub')->updateUser($this->userSession->getId(), $profile)) {
|
||||
$this->session->flash(t('Your GitHub account was successfully linked to your profile.'));
|
||||
}
|
||||
else {
|
||||
$this->session->flashError(t('Unable to link your GitHub Account.'));
|
||||
}
|
||||
|
||||
$this->response->redirect('?controller=user&action=external&user_id='.$this->acl->getUserId());
|
||||
$this->response->redirect('?controller=user&action=external&user_id='.$this->userSession->getId());
|
||||
}
|
||||
else if ($this->authentication->backend('gitHub')->authenticate($profile['id'])) {
|
||||
$this->response->redirect('?controller=app');
|
||||
|
@ -506,13 +512,13 @@ class User extends Base
|
|||
|
||||
$this->authentication->backend('gitHub')->revokeGitHubAccess();
|
||||
|
||||
if ($this->authentication->backend('gitHub')->unlink($this->acl->getUserId())) {
|
||||
if ($this->authentication->backend('gitHub')->unlink($this->userSession->getId())) {
|
||||
$this->session->flash(t('Your GitHub account is no longer linked to your profile.'));
|
||||
}
|
||||
else {
|
||||
$this->session->flashError(t('Unable to unlink your GitHub Account.'));
|
||||
}
|
||||
|
||||
$this->response->redirect('?controller=user&action=external&user_id='.$this->acl->getUserId());
|
||||
$this->response->redirect('?controller=user&action=external&user_id='.$this->userSession->getId());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,27 @@ class Webhook extends Base
|
|||
|
||||
$result = $this->githubWebhook->parsePayload(
|
||||
$this->request->getHeader('X-Github-Event'),
|
||||
$this->request->getJson()
|
||||
$this->request->getJson() ?: array()
|
||||
);
|
||||
|
||||
echo $result ? 'PARSED' : 'IGNORED';
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Gitlab webhooks
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function gitlab()
|
||||
{
|
||||
if ($this->config->get('webhook_token') !== $this->request->getStringParam('token')) {
|
||||
$this->response->text('Not Authorized', 401);
|
||||
}
|
||||
|
||||
$this->gitlabWebhook->setProjectId($this->request->getIntegerParam('project_id'));
|
||||
|
||||
$result = $this->gitlabWebhook->parsePayload(
|
||||
$this->request->getJson() ?: array()
|
||||
);
|
||||
|
||||
echo $result ? 'PARSED' : 'IGNORED';
|
||||
|
|
58
sources/app/Core/Cache.php
Normal file
58
sources/app/Core/Cache.php
Normal file
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
namespace Core;
|
||||
|
||||
use Pimple\Container;
|
||||
|
||||
abstract class Cache
|
||||
{
|
||||
/**
|
||||
* Container instance
|
||||
*
|
||||
* @access protected
|
||||
* @var \Pimple\Container
|
||||
*/
|
||||
protected $container;
|
||||
|
||||
abstract public function init();
|
||||
abstract public function set($key, $value);
|
||||
abstract public function get($key);
|
||||
abstract public function flush();
|
||||
abstract public function remove($key);
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
* @param \Pimple\Container $container
|
||||
*/
|
||||
public function __construct(Container $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
$this->init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxy cache
|
||||
*
|
||||
* Note: Arguments must be scalar types
|
||||
*
|
||||
* @access public
|
||||
* @param string $container Container name
|
||||
* @param string $method Container method
|
||||
* @return mixed
|
||||
*/
|
||||
public function proxy($container, $method)
|
||||
{
|
||||
$args = func_get_args();
|
||||
$key = 'proxy_'.implode('_', $args);
|
||||
$result = $this->get($key);
|
||||
|
||||
if ($result === null) {
|
||||
$result = call_user_func_array(array($this->container[$container], $method), array_splice($args, 2));
|
||||
$this->set($key, $result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
|
@ -1,175 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Core;
|
||||
|
||||
/**
|
||||
* Event dispatcher class
|
||||
*
|
||||
* @package core
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class Event
|
||||
{
|
||||
/**
|
||||
* Contains all listeners
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $listeners = array();
|
||||
|
||||
/**
|
||||
* The last listener executed
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $lastListener = '';
|
||||
|
||||
/**
|
||||
* The last triggered event
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $lastEvent = '';
|
||||
|
||||
/**
|
||||
* Triggered events list
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $events = array();
|
||||
|
||||
/**
|
||||
* Attach a listener object to an event
|
||||
*
|
||||
* @access public
|
||||
* @param string $eventName Event name
|
||||
* @param Listener $listener Object that implements the Listener interface
|
||||
*/
|
||||
public function attach($eventName, Listener $listener)
|
||||
{
|
||||
if (! isset($this->listeners[$eventName])) {
|
||||
$this->listeners[$eventName] = array();
|
||||
}
|
||||
|
||||
$this->listeners[$eventName][] = $listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger an event
|
||||
*
|
||||
* @access public
|
||||
* @param string $eventName Event name
|
||||
* @param array $data Event data
|
||||
*/
|
||||
public function trigger($eventName, array $data)
|
||||
{
|
||||
if (! $this->isEventTriggered($eventName)) {
|
||||
|
||||
$this->events[$eventName] = $data;
|
||||
|
||||
if (isset($this->listeners[$eventName])) {
|
||||
|
||||
foreach ($this->listeners[$eventName] as $listener) {
|
||||
|
||||
$this->lastEvent = $eventName;
|
||||
|
||||
if ($listener->execute($data)) {
|
||||
$this->lastListener = get_class($listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last listener executed
|
||||
*
|
||||
* @access public
|
||||
* @return string Event name
|
||||
*/
|
||||
public function getLastListenerExecuted()
|
||||
{
|
||||
return $this->lastListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last fired event
|
||||
*
|
||||
* @access public
|
||||
* @return string Event name
|
||||
*/
|
||||
public function getLastTriggeredEvent()
|
||||
{
|
||||
return $this->lastEvent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of triggered events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getTriggeredEvents()
|
||||
{
|
||||
return $this->events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of triggered events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getEventData($eventName)
|
||||
{
|
||||
return isset($this->events[$eventName]) ? $this->events[$eventName] : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an event have been triggered
|
||||
*
|
||||
* @access public
|
||||
* @param string $eventName Event name
|
||||
* @return bool
|
||||
*/
|
||||
public function isEventTriggered($eventName)
|
||||
{
|
||||
return isset($this->events[$eventName]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush the list of triggered events
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function clearTriggeredEvents()
|
||||
{
|
||||
$this->events = array();
|
||||
$this->lastEvent = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a listener bind to an event
|
||||
*
|
||||
* @access public
|
||||
* @param string $eventName Event name
|
||||
* @param mixed $instance Instance name or object itself
|
||||
* @return bool Yes or no
|
||||
*/
|
||||
public function hasListener($eventName, $instance)
|
||||
{
|
||||
if (isset($this->listeners[$eventName])) {
|
||||
foreach ($this->listeners[$eventName] as $listener) {
|
||||
if ($listener instanceof $instance) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
41
sources/app/Core/FileCache.php
Normal file
41
sources/app/Core/FileCache.php
Normal file
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace Core;
|
||||
|
||||
class FileCache extends Cache
|
||||
{
|
||||
const CACHE_FOLDER = 'data/cache/';
|
||||
|
||||
public function init()
|
||||
{
|
||||
if (! is_dir(self::CACHE_FOLDER)) {
|
||||
mkdir(self::CACHE_FOLDER);
|
||||
}
|
||||
}
|
||||
|
||||
public function set($key, $value)
|
||||
{
|
||||
file_put_contents(self::CACHE_FOLDER.$key, json_encode($value));
|
||||
}
|
||||
|
||||
public function get($key)
|
||||
{
|
||||
if (file_exists(self::CACHE_FOLDER.$key)) {
|
||||
return json_decode(file_get_contents(self::CACHE_FOLDER.$key), true);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function flush()
|
||||
{
|
||||
foreach (glob(self::CACHE_FOLDER.'*') as $filename) {
|
||||
@unlink($filename);
|
||||
}
|
||||
}
|
||||
|
||||
public function remove($key)
|
||||
{
|
||||
@unlink(self::CACHE_FOLDER.$key);
|
||||
}
|
||||
}
|
659
sources/app/Core/Helper.php
Normal file
659
sources/app/Core/Helper.php
Normal file
|
@ -0,0 +1,659 @@
|
|||
<?php
|
||||
|
||||
namespace Core;
|
||||
|
||||
use Pimple\Container;
|
||||
use Parsedown;
|
||||
|
||||
/**
|
||||
* Template helpers
|
||||
*
|
||||
* @package core
|
||||
* @author Frederic Guillot
|
||||
*
|
||||
* @property \Core\Session $session
|
||||
* @property \Model\Acl $acl
|
||||
* @property \Model\User $user
|
||||
* @property \Model\UserSession $userSession
|
||||
*/
|
||||
class Helper
|
||||
{
|
||||
/**
|
||||
* Container instance
|
||||
*
|
||||
* @access protected
|
||||
* @var \Pimple\Container
|
||||
*/
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
* @param \Pimple\Container $container
|
||||
*/
|
||||
public function __construct(Container $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load automatically models
|
||||
*
|
||||
* @access public
|
||||
* @param string $name Model name
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
return $this->container[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxy cache helper for acl::isManagerActionAllowed()
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id
|
||||
* @return boolean
|
||||
*/
|
||||
public function isManager($project_id)
|
||||
{
|
||||
if ($this->userSession->isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->container['memoryCache']->proxy('acl', 'isManagerActionAllowed', $project_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the user full name
|
||||
*
|
||||
* @param array $user User properties
|
||||
* @return string
|
||||
*/
|
||||
public function getFullname(array $user = array())
|
||||
{
|
||||
return $this->user->getFullname(empty($user) ? $_SESSION['user'] : $user);
|
||||
}
|
||||
|
||||
/**
|
||||
* HTML escaping
|
||||
*
|
||||
* @param string $value Value to escape
|
||||
* @return string
|
||||
*/
|
||||
public function e($value)
|
||||
{
|
||||
return htmlspecialchars($value, ENT_QUOTES, 'UTF-8', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a Javascript asset
|
||||
*
|
||||
* @param string $filename Filename
|
||||
* @return string
|
||||
*/
|
||||
public function js($filename)
|
||||
{
|
||||
return '<script type="text/javascript" src="'.$filename.'?'.filemtime($filename).'"></script>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a stylesheet asset
|
||||
*
|
||||
* @param string $filename Filename
|
||||
* @return string
|
||||
*/
|
||||
public function css($filename)
|
||||
{
|
||||
return '<link rel="stylesheet" href="'.$filename.'?'.filemtime($filename).'" media="screen">';
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the form error class
|
||||
*
|
||||
* @param array $errors Error list
|
||||
* @param string $name Field name
|
||||
* @return string
|
||||
*/
|
||||
public function errorClass(array $errors, $name)
|
||||
{
|
||||
return ! isset($errors[$name]) ? '' : ' form-error';
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a list of form errors
|
||||
*
|
||||
* @param array $errors List of errors
|
||||
* @param string $name Field name
|
||||
* @return string
|
||||
*/
|
||||
public function errorList(array $errors, $name)
|
||||
{
|
||||
$html = '';
|
||||
|
||||
if (isset($errors[$name])) {
|
||||
|
||||
$html .= '<ul class="form-errors">';
|
||||
|
||||
foreach ($errors[$name] as $error) {
|
||||
$html .= '<li>'.$this->e($error).'</li>';
|
||||
}
|
||||
|
||||
$html .= '</ul>';
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an escaped form value
|
||||
*
|
||||
* @param mixed $values Values
|
||||
* @param string $name Field name
|
||||
* @return string
|
||||
*/
|
||||
public function formValue($values, $name)
|
||||
{
|
||||
if (isset($values->$name)) {
|
||||
return 'value="'.$this->e($values->$name).'"';
|
||||
}
|
||||
|
||||
return isset($values[$name]) ? 'value="'.$this->e($values[$name]).'"' : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Hidden CSRF token field
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function formCsrf()
|
||||
{
|
||||
return '<input type="hidden" name="csrf_token" value="'.Security::getCSRFToken().'"/>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a hidden form field
|
||||
*
|
||||
* @param string $name Field name
|
||||
* @param array $values Form values
|
||||
* @return string
|
||||
*/
|
||||
public function formHidden($name, array $values = array())
|
||||
{
|
||||
return '<input type="hidden" name="'.$name.'" id="form-'.$name.'" '.$this->formValue($values, $name).'/>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a select field
|
||||
*
|
||||
* @param string $name Field name
|
||||
* @param array $options Options
|
||||
* @param array $values Form values
|
||||
* @param array $errors Form errors
|
||||
* @param string $class CSS class
|
||||
* @return string
|
||||
*/
|
||||
public function formSelect($name, array $options, array $values = array(), array $errors = array(), $class = '')
|
||||
{
|
||||
$html = '<select name="'.$name.'" id="form-'.$name.'" class="'.$class.'">';
|
||||
|
||||
foreach ($options as $id => $value) {
|
||||
|
||||
$html .= '<option value="'.$this->e($id).'"';
|
||||
|
||||
if (isset($values->$name) && $id == $values->$name) $html .= ' selected="selected"';
|
||||
if (isset($values[$name]) && $id == $values[$name]) $html .= ' selected="selected"';
|
||||
|
||||
$html .= '>'.$this->e($value).'</option>';
|
||||
}
|
||||
|
||||
$html .= '</select>';
|
||||
$html .= $this->errorList($errors, $name);
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a radio field group
|
||||
*
|
||||
* @param string $name Field name
|
||||
* @param array $options Options
|
||||
* @param array $values Form values
|
||||
* @return string
|
||||
*/
|
||||
public function formRadios($name, array $options, array $values = array())
|
||||
{
|
||||
$html = '';
|
||||
|
||||
foreach ($options as $value => $label) {
|
||||
$html .= $this->formRadio($name, $label, $value, isset($values[$name]) && $values[$name] == $value);
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a radio field
|
||||
*
|
||||
* @param string $name Field name
|
||||
* @param string $label Form label
|
||||
* @param string $value Form value
|
||||
* @param boolean $selected Field selected or not
|
||||
* @param string $class CSS class
|
||||
* @return string
|
||||
*/
|
||||
public function formRadio($name, $label, $value, $selected = false, $class = '')
|
||||
{
|
||||
return '<label><input type="radio" name="'.$name.'" class="'.$class.'" value="'.$this->e($value).'" '.($selected ? 'selected="selected"' : '').'>'.$this->e($label).'</label>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a checkbox field
|
||||
*
|
||||
* @param string $name Field name
|
||||
* @param string $label Form label
|
||||
* @param string $value Form value
|
||||
* @param boolean $checked Field selected or not
|
||||
* @param string $class CSS class
|
||||
* @return string
|
||||
*/
|
||||
public function formCheckbox($name, $label, $value, $checked = false, $class = '')
|
||||
{
|
||||
return '<label><input type="checkbox" name="'.$name.'" class="'.$class.'" value="'.$this->e($value).'" '.($checked ? 'checked="checked"' : '').'> '.$this->e($label).'</label>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a form label
|
||||
*
|
||||
* @param string $name Field name
|
||||
* @param string $label Form label
|
||||
* @param array $attributes HTML attributes
|
||||
* @return string
|
||||
*/
|
||||
public function formLabel($label, $name, array $attributes = array())
|
||||
{
|
||||
return '<label for="form-'.$name.'" '.implode(' ', $attributes).'>'.$this->e($label).'</label>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a textarea
|
||||
*
|
||||
* @param string $name Field name
|
||||
* @param array $values Form values
|
||||
* @param array $errors Form errors
|
||||
* @param array $attributes HTML attributes
|
||||
* @param string $class CSS class
|
||||
* @return string
|
||||
*/
|
||||
public function formTextarea($name, $values = array(), array $errors = array(), array $attributes = array(), $class = '')
|
||||
{
|
||||
$class .= $this->errorClass($errors, $name);
|
||||
|
||||
$html = '<textarea name="'.$name.'" id="form-'.$name.'" class="'.$class.'" ';
|
||||
$html .= implode(' ', $attributes).'>';
|
||||
$html .= isset($values->$name) ? $this->e($values->$name) : isset($values[$name]) ? $values[$name] : '';
|
||||
$html .= '</textarea>';
|
||||
$html .= $this->errorList($errors, $name);
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a input field
|
||||
*
|
||||
* @param string $type HMTL input tag type
|
||||
* @param string $name Field name
|
||||
* @param array $values Form values
|
||||
* @param array $errors Form errors
|
||||
* @param array $attributes HTML attributes
|
||||
* @param string $class CSS class
|
||||
* @return string
|
||||
*/
|
||||
public function formInput($type, $name, $values = array(), array $errors = array(), array $attributes = array(), $class = '')
|
||||
{
|
||||
$class .= $this->errorClass($errors, $name);
|
||||
|
||||
$html = '<input type="'.$type.'" name="'.$name.'" id="form-'.$name.'" '.$this->formValue($values, $name).' class="'.$class.'" ';
|
||||
$html .= implode(' ', $attributes).'/>';
|
||||
if (in_array('required', $attributes)) $html .= '<span class="form-required">*</span>';
|
||||
$html .= $this->errorList($errors, $name);
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a text field
|
||||
*
|
||||
* @param string $name Field name
|
||||
* @param array $values Form values
|
||||
* @param array $errors Form errors
|
||||
* @param array $attributes HTML attributes
|
||||
* @param string $class CSS class
|
||||
* @return string
|
||||
*/
|
||||
public function formText($name, $values = array(), array $errors = array(), array $attributes = array(), $class = '')
|
||||
{
|
||||
return $this->formInput('text', $name, $values, $errors, $attributes, $class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a password field
|
||||
*
|
||||
* @param string $name Field name
|
||||
* @param array $values Form values
|
||||
* @param array $errors Form errors
|
||||
* @param array $attributes HTML attributes
|
||||
* @param string $class CSS class
|
||||
* @return string
|
||||
*/
|
||||
public function formPassword($name, $values = array(), array $errors = array(), array $attributes = array(), $class = '')
|
||||
{
|
||||
return $this->formInput('password', $name, $values, $errors, $attributes, $class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display an email field
|
||||
*
|
||||
* @param string $name Field name
|
||||
* @param array $values Form values
|
||||
* @param array $errors Form errors
|
||||
* @param array $attributes HTML attributes
|
||||
* @param string $class CSS class
|
||||
* @return string
|
||||
*/
|
||||
public function formEmail($name, $values = array(), array $errors = array(), array $attributes = array(), $class = '')
|
||||
{
|
||||
return $this->formInput('email', $name, $values, $errors, $attributes, $class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a number field
|
||||
*
|
||||
* @param string $name Field name
|
||||
* @param array $values Form values
|
||||
* @param array $errors Form errors
|
||||
* @param array $attributes HTML attributes
|
||||
* @param string $class CSS class
|
||||
* @return string
|
||||
*/
|
||||
public function formNumber($name, $values = array(), array $errors = array(), array $attributes = array(), $class = '')
|
||||
{
|
||||
return $this->formInput('number', $name, $values, $errors, $attributes, $class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a numeric field (allow decimal number)
|
||||
*
|
||||
* @param string $name Field name
|
||||
* @param array $values Form values
|
||||
* @param array $errors Form errors
|
||||
* @param array $attributes HTML attributes
|
||||
* @param string $class CSS class
|
||||
* @return string
|
||||
*/
|
||||
public function formNumeric($name, $values = array(), array $errors = array(), array $attributes = array(), $class = '')
|
||||
{
|
||||
return $this->formInput('text', $name, $values, $errors, $attributes, $class.' form-numeric');
|
||||
}
|
||||
|
||||
/**
|
||||
* Link
|
||||
*
|
||||
* a('link', 'task', 'show', array('task_id' => $task_id))
|
||||
*
|
||||
* @param string $label Link label
|
||||
* @param string $controller Controller name
|
||||
* @param string $action Action name
|
||||
* @param array $params Url parameters
|
||||
* @param boolean $csrf Add a CSRF token
|
||||
* @param string $class CSS class attribute
|
||||
* @param boolean $new_tab Open the link in a new tab
|
||||
* @return string
|
||||
*/
|
||||
public function a($label, $controller, $action, array $params = array(), $csrf = false, $class = '', $title = '', $new_tab = false)
|
||||
{
|
||||
return '<a href="'.$this->u($controller, $action, $params, $csrf).'" class="'.$class.'" title="'.$title.'" '.($new_tab ? 'target="_blank"' : '').'>'.$label.'</a>';
|
||||
}
|
||||
|
||||
/**
|
||||
* URL query string
|
||||
*
|
||||
* u('task', 'show', array('task_id' => $task_id))
|
||||
*
|
||||
* @param string $controller Controller name
|
||||
* @param string $action Action name
|
||||
* @param array $params Url parameters
|
||||
* @param boolean $csrf Add a CSRF token
|
||||
* @return string
|
||||
*/
|
||||
public function u($controller, $action, array $params = array(), $csrf = false)
|
||||
{
|
||||
$html = '?controller='.$controller.'&action='.$action;
|
||||
|
||||
if ($csrf) {
|
||||
$params['csrf_token'] = Security::getCSRFToken();
|
||||
}
|
||||
|
||||
foreach ($params as $key => $value) {
|
||||
$html .= '&'.$key.'='.$value;
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pagination links
|
||||
*
|
||||
* @param array $pagination Pagination information
|
||||
* @return string
|
||||
*/
|
||||
public function paginate(array $pagination)
|
||||
{
|
||||
extract($pagination);
|
||||
|
||||
if ($pagination['offset'] === 0 && ($total - $pagination['offset']) <= $limit) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$html = '<div class="pagination">';
|
||||
$html .= '<span class="pagination-previous">';
|
||||
|
||||
if ($pagination['offset'] > 0) {
|
||||
$offset = $pagination['offset'] - $limit;
|
||||
$html .= $this->a('← '.t('Previous'), $controller, $action, $params + compact('offset', 'order', 'direction'));
|
||||
}
|
||||
else {
|
||||
$html .= '← '.t('Previous');
|
||||
}
|
||||
|
||||
$html .= '</span>';
|
||||
$html .= '<span class="pagination-next">';
|
||||
|
||||
if (($total - $pagination['offset']) > $limit) {
|
||||
$offset = $pagination['offset'] + $limit;
|
||||
$html .= $this->a(t('Next').' →', $controller, $action, $params + compact('offset', 'order', 'direction'));
|
||||
}
|
||||
else {
|
||||
$html .= t('Next').' →';
|
||||
}
|
||||
|
||||
$html .= '</span>';
|
||||
$html .= '</div>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Column sorting (work with pagination)
|
||||
*
|
||||
* @param string $label Column title
|
||||
* @param string $column SQL column name
|
||||
* @param array $pagination Pagination information
|
||||
* @return string
|
||||
*/
|
||||
public function order($label, $column, array $pagination)
|
||||
{
|
||||
extract($pagination);
|
||||
|
||||
$prefix = '';
|
||||
|
||||
if ($order === $column) {
|
||||
$prefix = $direction === 'DESC' ? '▼ ' : '▲ ';
|
||||
$direction = $direction === 'DESC' ? 'ASC' : 'DESC';
|
||||
}
|
||||
|
||||
$order = $column;
|
||||
|
||||
return $prefix.$this->a($label, $controller, $action, $params + compact('offset', 'order', 'direction'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Markdown transformation
|
||||
*
|
||||
* @param string $text Markdown content
|
||||
* @param array $link Link parameters for replacement
|
||||
* @return string
|
||||
*/
|
||||
public function markdown($text, array $link = array())
|
||||
{
|
||||
$html = Parsedown::instance()
|
||||
->setMarkupEscaped(true) # escapes markup (HTML)
|
||||
->text($text);
|
||||
|
||||
// Replace task #123 by a link to the task
|
||||
if (! empty($link) && preg_match_all('!#(\d+)!i', $html, $matches, PREG_SET_ORDER)) {
|
||||
|
||||
foreach ($matches as $match) {
|
||||
|
||||
$html = str_replace(
|
||||
$match[0],
|
||||
$this->a($match[0], $link['controller'], $link['action'], $link['params'] + array('task_id' => $match[1])),
|
||||
$html
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current URL without the querystring
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCurrentBaseUrl()
|
||||
{
|
||||
$url = Request::isHTTPS() ? 'https://' : 'http://';
|
||||
$url .= $_SERVER['SERVER_NAME'];
|
||||
$url .= $_SERVER['SERVER_PORT'] == 80 || $_SERVER['SERVER_PORT'] == 443 ? '' : ':'.$_SERVER['SERVER_PORT'];
|
||||
$url .= dirname($_SERVER['PHP_SELF']) !== '/' ? dirname($_SERVER['PHP_SELF']).'/' : '/';
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispplay the flash session message
|
||||
*
|
||||
* @param string $html HTML wrapper
|
||||
* @return string
|
||||
*/
|
||||
public function flash($html)
|
||||
{
|
||||
return $this->flashMessage('flash_message', $html);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the flash session error message
|
||||
*
|
||||
* @param string $html HTML wrapper
|
||||
* @return string
|
||||
*/
|
||||
public function flashError($html)
|
||||
{
|
||||
return $this->flashMessage('flash_error_message', $html);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch and remove a flash session message
|
||||
*
|
||||
* @access private
|
||||
* @param string $name Message name
|
||||
* @param string $html HTML wrapper
|
||||
* @return string
|
||||
*/
|
||||
private function flashMessage($name, $html)
|
||||
{
|
||||
$data = '';
|
||||
|
||||
if (isset($this->session[$name])) {
|
||||
$data = sprintf($html, $this->e($this->session[$name]));
|
||||
unset($this->session[$name]);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a file size
|
||||
*
|
||||
* @param integer $size Size in bytes
|
||||
* @param integer $precision Precision
|
||||
* @return string
|
||||
*/
|
||||
public function formatBytes($size, $precision = 2)
|
||||
{
|
||||
$base = log($size) / log(1024);
|
||||
$suffixes = array('', 'k', 'M', 'G', 'T');
|
||||
|
||||
return round(pow(1024, $base - floor($base)), $precision).$suffixes[(int)floor($base)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncate a long text
|
||||
*
|
||||
* @param string $value Text
|
||||
* @param integer $max_length Max Length
|
||||
* @param string $end Text end
|
||||
* @return string
|
||||
*/
|
||||
public function summary($value, $max_length = 85, $end = '[...]')
|
||||
{
|
||||
$length = strlen($value);
|
||||
|
||||
if ($length > $max_length) {
|
||||
return substr($value, 0, $max_length).' '.$end;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if needle is contained in the haystack
|
||||
*
|
||||
* @param string $haystack Haystack
|
||||
* @param string $needle Needle
|
||||
* @return boolean
|
||||
*/
|
||||
public function contains($haystack, $needle)
|
||||
{
|
||||
return strpos($haystack, $needle) !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a value from a dictionary
|
||||
*
|
||||
* @param mixed $id Key
|
||||
* @param array $listing Dictionary
|
||||
* @param string $default_value Value displayed when the key doesn't exists
|
||||
* @return string
|
||||
*/
|
||||
public function inList($id, array $listing, $default_value = '?')
|
||||
{
|
||||
if (isset($listing[$id])) {
|
||||
return $this->e($listing[$id]);
|
||||
}
|
||||
|
||||
return $default_value;
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Core;
|
||||
|
||||
/**
|
||||
* Event listener interface
|
||||
*
|
||||
* @package core
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
interface Listener
|
||||
{
|
||||
/**
|
||||
* Execute the listener
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data
|
||||
* @return boolean
|
||||
*/
|
||||
public function execute(array $data);
|
||||
}
|
32
sources/app/Core/MemoryCache.php
Normal file
32
sources/app/Core/MemoryCache.php
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace Core;
|
||||
|
||||
class MemoryCache extends Cache
|
||||
{
|
||||
private $storage = array();
|
||||
|
||||
public function init()
|
||||
{
|
||||
}
|
||||
|
||||
public function set($key, $value)
|
||||
{
|
||||
$this->storage[$key] = $value;
|
||||
}
|
||||
|
||||
public function get($key)
|
||||
{
|
||||
return isset($this->storage[$key]) ? $this->storage[$key] : null;
|
||||
}
|
||||
|
||||
public function flush()
|
||||
{
|
||||
$this->storage = array();
|
||||
}
|
||||
|
||||
public function remove($key)
|
||||
{
|
||||
unset($this->storage[$key]);
|
||||
}
|
||||
}
|
|
@ -2,13 +2,15 @@
|
|||
|
||||
namespace Core;
|
||||
|
||||
use ArrayAccess;
|
||||
|
||||
/**
|
||||
* Session class
|
||||
*
|
||||
* @package core
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class Session
|
||||
class Session implements ArrayAccess
|
||||
{
|
||||
/**
|
||||
* Sesion lifetime
|
||||
|
@ -59,7 +61,7 @@ class Session
|
|||
ini_set('session.entropy_length', '32');
|
||||
ini_set('session.hash_bits_per_character', 6);
|
||||
|
||||
// If session was autostarted with session.auto_start = 1 in php.ini destroy it
|
||||
// If the session was autostarted with session.auto_start = 1 in php.ini destroy it
|
||||
if (isset($_SESSION)) {
|
||||
session_destroy();
|
||||
}
|
||||
|
@ -88,19 +90,17 @@ class Session
|
|||
$_SESSION = array();
|
||||
|
||||
// Destroy the session cookie
|
||||
if (ini_get('session.use_cookies')) {
|
||||
$params = session_get_cookie_params();
|
||||
$params = session_get_cookie_params();
|
||||
|
||||
setcookie(
|
||||
session_name(),
|
||||
'',
|
||||
time() - 42000,
|
||||
$params['path'],
|
||||
$params['domain'],
|
||||
$params['secure'],
|
||||
$params['httponly']
|
||||
);
|
||||
}
|
||||
setcookie(
|
||||
session_name(),
|
||||
'',
|
||||
time() - 42000,
|
||||
$params['path'],
|
||||
$params['domain'],
|
||||
$params['secure'],
|
||||
$params['httponly']
|
||||
);
|
||||
|
||||
// Destroy session data
|
||||
session_destroy();
|
||||
|
@ -127,4 +127,24 @@ class Session
|
|||
{
|
||||
$_SESSION['flash_error_message'] = $message;
|
||||
}
|
||||
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$_SESSION[$offset] = $value;
|
||||
}
|
||||
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return isset($_SESSION[$offset]);
|
||||
}
|
||||
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
unset($_SESSION[$offset]);
|
||||
}
|
||||
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return isset($_SESSION[$offset]) ? $_SESSION[$offset] : null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ use LogicException;
|
|||
* @package core
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class Template
|
||||
class Template extends Helper
|
||||
{
|
||||
/**
|
||||
* Template path
|
||||
|
@ -20,18 +20,18 @@ class Template
|
|||
const PATH = 'app/Template/';
|
||||
|
||||
/**
|
||||
* Load a template
|
||||
* Render a template
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* $template->load('template_name', ['bla' => 'value']);
|
||||
* $template->render('template_name', ['bla' => 'value']);
|
||||
*
|
||||
* @access public
|
||||
* @params string $__template_name Template name
|
||||
* @params array $__template_args Key/Value map of template variables
|
||||
* @return string
|
||||
*/
|
||||
public function load($__template_name, array $__template_args = array())
|
||||
public function render($__template_name, array $__template_args = array())
|
||||
{
|
||||
$__template_file = self::PATH.$__template_name.'.php';
|
||||
|
||||
|
@ -57,9 +57,9 @@ class Template
|
|||
*/
|
||||
public function layout($template_name, array $template_args = array(), $layout_name = 'layout')
|
||||
{
|
||||
return $this->load(
|
||||
return $this->render(
|
||||
$layout_name,
|
||||
$template_args + array('content_for_layout' => $this->load($template_name, $template_args))
|
||||
$template_args + array('content_for_layout' => $this->render($template_name, $template_args))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
namespace Core;
|
||||
|
||||
use Pimple\Container;
|
||||
|
||||
/**
|
||||
* Tool class
|
||||
*
|
||||
|
@ -33,23 +31,4 @@ class Tool
|
|||
fclose($fp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load and register a model
|
||||
*
|
||||
* @static
|
||||
* @access public
|
||||
* @param Pimple\Container $container Container instance
|
||||
* @param string $name Model name
|
||||
* @return mixed
|
||||
*/
|
||||
public static function loadModel(Container $container, $name)
|
||||
{
|
||||
if (! isset($container[$name])) {
|
||||
$class = '\Model\\'.ucfirst($name);
|
||||
$container[$name] = new $class($container);
|
||||
}
|
||||
|
||||
return $container[$name];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -181,5 +181,8 @@ class Translator
|
|||
if (file_exists($filename)) {
|
||||
self::$locales = require $filename;
|
||||
}
|
||||
else {
|
||||
self::$locales = array();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
27
sources/app/Event/AuthEvent.php
Normal file
27
sources/app/Event/AuthEvent.php
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace Event;
|
||||
|
||||
use Symfony\Component\EventDispatcher\Event as BaseEvent;
|
||||
|
||||
class AuthEvent extends BaseEvent
|
||||
{
|
||||
private $auth_name;
|
||||
private $user_id;
|
||||
|
||||
public function __construct($auth_name, $user_id)
|
||||
{
|
||||
$this->auth_name = $auth_name;
|
||||
$this->user_id = $user_id;
|
||||
}
|
||||
|
||||
public function getUserId()
|
||||
{
|
||||
return $this->user_id;
|
||||
}
|
||||
|
||||
public function getAuthType()
|
||||
{
|
||||
return $this->auth_name;
|
||||
}
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Event;
|
||||
|
||||
use Pimple\Container;
|
||||
use Core\Listener;
|
||||
use Core\Tool;
|
||||
|
||||
/**
|
||||
* Base Listener
|
||||
*
|
||||
* @package event
|
||||
* @author Frederic Guillot
|
||||
*
|
||||
* @property \Model\Comment $comment
|
||||
* @property \Model\Project $project
|
||||
* @property \Model\ProjectActivity $projectActivity
|
||||
* @property \Model\SubTask $subTask
|
||||
* @property \Model\Task $task
|
||||
* @property \Model\TaskFinder $taskFinder
|
||||
*/
|
||||
abstract class Base implements Listener
|
||||
{
|
||||
/**
|
||||
* Container instance
|
||||
*
|
||||
* @access protected
|
||||
* @var \Pimple\Container
|
||||
*/
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
* @param \Pimple\Container $container
|
||||
*/
|
||||
public function __construct(Container $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return class information
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return get_called_class();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load automatically models
|
||||
*
|
||||
* @access public
|
||||
* @param string $name Model name
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
return Tool::loadModel($this->container, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get event namespace
|
||||
*
|
||||
* Event = task.close | Namespace = task
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getEventNamespace()
|
||||
{
|
||||
$event_name = $this->container['event']->getLastTriggeredEvent();
|
||||
return substr($event_name, 0, strpos($event_name, '.'));
|
||||
}
|
||||
}
|
7
sources/app/Event/CommentEvent.php
Normal file
7
sources/app/Event/CommentEvent.php
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Event;
|
||||
|
||||
class CommentEvent extends GenericEvent
|
||||
{
|
||||
}
|
7
sources/app/Event/FileEvent.php
Normal file
7
sources/app/Event/FileEvent.php
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Event;
|
||||
|
||||
class FileEvent extends GenericEvent
|
||||
{
|
||||
}
|
45
sources/app/Event/GenericEvent.php
Normal file
45
sources/app/Event/GenericEvent.php
Normal file
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
namespace Event;
|
||||
|
||||
use ArrayAccess;
|
||||
use Symfony\Component\EventDispatcher\Event as BaseEvent;
|
||||
|
||||
class GenericEvent extends BaseEvent implements ArrayAccess
|
||||
{
|
||||
private $container = array();
|
||||
|
||||
public function __construct(array $values = array())
|
||||
{
|
||||
$this->container = $values;
|
||||
}
|
||||
|
||||
public function getAll()
|
||||
{
|
||||
return $this->container;
|
||||
}
|
||||
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
if (is_null($offset)) {
|
||||
$this->container[] = $value;
|
||||
} else {
|
||||
$this->container[$offset] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return isset($this->container[$offset]);
|
||||
}
|
||||
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
unset($this->container[$offset]);
|
||||
}
|
||||
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return isset($this->container[$offset]) ? $this->container[$offset] : null;
|
||||
}
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Event;
|
||||
|
||||
/**
|
||||
* Notification listener
|
||||
*
|
||||
* @package event
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class NotificationListener extends Base
|
||||
{
|
||||
/**
|
||||
* Template name
|
||||
*
|
||||
* @accesss private
|
||||
* @var string
|
||||
*/
|
||||
private $template = '';
|
||||
|
||||
/**
|
||||
* Set template name
|
||||
*
|
||||
* @access public
|
||||
* @param string $template Template name
|
||||
*/
|
||||
public function setTemplate($template)
|
||||
{
|
||||
$this->template = $template;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function execute(array $data)
|
||||
{
|
||||
$values = $this->getTemplateData($data);
|
||||
$users = $this->notification->getUsersList($values['task']['project_id']);
|
||||
|
||||
if ($users) {
|
||||
$this->notification->sendEmails($this->template, $users, $values);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch data for the mail template
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data
|
||||
* @return array
|
||||
*/
|
||||
public function getTemplateData(array $data)
|
||||
{
|
||||
$values = array();
|
||||
|
||||
switch ($this->getEventNamespace()) {
|
||||
case 'task':
|
||||
$values['task'] = $this->taskFinder->getDetails($data['task_id']);
|
||||
break;
|
||||
case 'subtask':
|
||||
$values['subtask'] = $this->subtask->getById($data['id'], true);
|
||||
$values['task'] = $this->taskFinder->getDetails($data['task_id']);
|
||||
break;
|
||||
case 'file':
|
||||
$values['file'] = $data;
|
||||
$values['task'] = $this->taskFinder->getDetails($data['task_id']);
|
||||
break;
|
||||
case 'comment':
|
||||
$values['comment'] = $this->comment->getById($data['id']);
|
||||
$values['task'] = $this->taskFinder->getDetails($values['comment']['task_id']);
|
||||
break;
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Event;
|
||||
|
||||
/**
|
||||
* Project activity listener
|
||||
*
|
||||
* @package event
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class ProjectActivityListener extends Base
|
||||
{
|
||||
/**
|
||||
* Execute the action
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function execute(array $data)
|
||||
{
|
||||
if (isset($data['task_id'])) {
|
||||
|
||||
$values = $this->getValues($data);
|
||||
|
||||
return $this->projectActivity->createEvent(
|
||||
$values['task']['project_id'],
|
||||
$values['task']['id'],
|
||||
$this->acl->getUserId(),
|
||||
$this->container['event']->getLastTriggeredEvent(),
|
||||
$values
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get event activity data
|
||||
*
|
||||
* @access private
|
||||
* @param array $data Event data dictionary
|
||||
* @return array
|
||||
*/
|
||||
private function getValues(array $data)
|
||||
{
|
||||
$values = array();
|
||||
$values['task'] = $this->taskFinder->getDetails($data['task_id']);
|
||||
|
||||
switch ($this->getEventNamespace()) {
|
||||
case 'subtask':
|
||||
$values['subtask'] = $this->subTask->getById($data['id'], true);
|
||||
break;
|
||||
case 'comment':
|
||||
$values['comment'] = $this->comment->getById($data['id']);
|
||||
break;
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Event;
|
||||
|
||||
/**
|
||||
* Project daily summary listener
|
||||
*
|
||||
* @package event
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class ProjectDailySummaryListener extends Base
|
||||
{
|
||||
/**
|
||||
* Execute the action
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function execute(array $data)
|
||||
{
|
||||
if (isset($data['project_id'])) {
|
||||
return $this->projectDailySummary->updateTotals($data['project_id'], date('Y-m-d'));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Event;
|
||||
|
||||
/**
|
||||
* Project modification date listener
|
||||
*
|
||||
* Update the "last_modified" field for a project
|
||||
*
|
||||
* @package event
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class ProjectModificationDateListener extends Base
|
||||
{
|
||||
/**
|
||||
* Execute the action
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function execute(array $data)
|
||||
{
|
||||
if (isset($data['project_id'])) {
|
||||
return $this->project->updateModificationDate($data['project_id']);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
7
sources/app/Event/SubtaskEvent.php
Normal file
7
sources/app/Event/SubtaskEvent.php
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Event;
|
||||
|
||||
class SubtaskEvent extends GenericEvent
|
||||
{
|
||||
}
|
7
sources/app/Event/TaskEvent.php
Normal file
7
sources/app/Event/TaskEvent.php
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Event;
|
||||
|
||||
class TaskEvent extends GenericEvent
|
||||
{
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Event;
|
||||
|
||||
/**
|
||||
* Webhook task events
|
||||
*
|
||||
* @package event
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class WebhookListener extends Base
|
||||
{
|
||||
/**
|
||||
* Url to call
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $url = '';
|
||||
|
||||
/**
|
||||
* Set webhook url
|
||||
*
|
||||
* @access public
|
||||
* @param string $url URL to call
|
||||
*/
|
||||
public function setUrl($url)
|
||||
{
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function execute(array $data)
|
||||
{
|
||||
$this->webhook->notify($this->url, $data);
|
||||
return true;
|
||||
}
|
||||
}
|
49
sources/app/Integration/Base.php
Normal file
49
sources/app/Integration/Base.php
Normal file
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
namespace Integration;
|
||||
|
||||
use Pimple\Container;
|
||||
|
||||
/**
|
||||
* Base class
|
||||
*
|
||||
* @package integration
|
||||
* @author Frederic Guillot
|
||||
*
|
||||
* @property \Model\Task $task
|
||||
* @property \Model\TaskFinder $taskFinder
|
||||
* @property \Model\User $user
|
||||
*/
|
||||
abstract class Base
|
||||
{
|
||||
/**
|
||||
* Container instance
|
||||
*
|
||||
* @access protected
|
||||
* @var \Pimple\Container
|
||||
*/
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
* @param \Pimple\Container $container
|
||||
*/
|
||||
public function __construct(Container $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load automatically class from the container
|
||||
*
|
||||
* @access public
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
return $this->container[$name];
|
||||
}
|
||||
}
|
|
@ -1,11 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace Model;
|
||||
namespace Integration;
|
||||
|
||||
use Event\GenericEvent;
|
||||
use Model\Task;
|
||||
|
||||
/**
|
||||
* Github Webhook model
|
||||
* Github Webhook
|
||||
*
|
||||
* @package model
|
||||
* @package integration
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class GithubWebhook extends Base
|
||||
|
@ -87,8 +90,11 @@ class GithubWebhook extends Base
|
|||
continue;
|
||||
}
|
||||
|
||||
if ($task['is_active'] == Task::STATUS_OPEN) {
|
||||
$this->event->trigger(self::EVENT_COMMIT, array('task_id' => $task_id) + $task);
|
||||
if ($task['is_active'] == Task::STATUS_OPEN && $task['project_id'] == $this->project_id) {
|
||||
$this->container['dispatcher']->dispatch(
|
||||
self::EVENT_COMMIT,
|
||||
new GenericEvent(array('task_id' => $task_id) + $task)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -146,7 +152,11 @@ class GithubWebhook extends Base
|
|||
'task_id' => $task['id'],
|
||||
);
|
||||
|
||||
$this->event->trigger(self::EVENT_ISSUE_COMMENT, $event);
|
||||
$this->container['dispatcher']->dispatch(
|
||||
self::EVENT_ISSUE_COMMENT,
|
||||
new GenericEvent($event)
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -169,7 +179,11 @@ class GithubWebhook extends Base
|
|||
'description' => $issue['body']."\n\n[".t('Github Issue').']('.$issue['html_url'].')',
|
||||
);
|
||||
|
||||
$this->event->trigger(self::EVENT_ISSUE_OPENED, $event);
|
||||
$this->container['dispatcher']->dispatch(
|
||||
self::EVENT_ISSUE_OPENED,
|
||||
new GenericEvent($event)
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -191,7 +205,11 @@ class GithubWebhook extends Base
|
|||
'reference' => $issue['number'],
|
||||
);
|
||||
|
||||
$this->event->trigger(self::EVENT_ISSUE_CLOSED, $event);
|
||||
$this->container['dispatcher']->dispatch(
|
||||
self::EVENT_ISSUE_CLOSED,
|
||||
new GenericEvent($event)
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -216,7 +234,11 @@ class GithubWebhook extends Base
|
|||
'reference' => $issue['number'],
|
||||
);
|
||||
|
||||
$this->event->trigger(self::EVENT_ISSUE_REOPENED, $event);
|
||||
$this->container['dispatcher']->dispatch(
|
||||
self::EVENT_ISSUE_REOPENED,
|
||||
new GenericEvent($event)
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -244,7 +266,11 @@ class GithubWebhook extends Base
|
|||
'reference' => $issue['number'],
|
||||
);
|
||||
|
||||
$this->event->trigger(self::EVENT_ISSUE_ASSIGNEE_CHANGE, $event);
|
||||
$this->container['dispatcher']->dispatch(
|
||||
self::EVENT_ISSUE_ASSIGNEE_CHANGE,
|
||||
new GenericEvent($event)
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -271,7 +297,11 @@ class GithubWebhook extends Base
|
|||
'reference' => $issue['number'],
|
||||
);
|
||||
|
||||
$this->event->trigger(self::EVENT_ISSUE_ASSIGNEE_CHANGE, $event);
|
||||
$this->container['dispatcher']->dispatch(
|
||||
self::EVENT_ISSUE_ASSIGNEE_CHANGE,
|
||||
new GenericEvent($event)
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -299,7 +329,11 @@ class GithubWebhook extends Base
|
|||
'label' => $label['name'],
|
||||
);
|
||||
|
||||
$this->event->trigger(self::EVENT_ISSUE_LABEL_CHANGE, $event);
|
||||
$this->container['dispatcher']->dispatch(
|
||||
self::EVENT_ISSUE_LABEL_CHANGE,
|
||||
new GenericEvent($event)
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -328,7 +362,11 @@ class GithubWebhook extends Base
|
|||
'category_id' => 0,
|
||||
);
|
||||
|
||||
$this->event->trigger(self::EVENT_ISSUE_LABEL_CHANGE, $event);
|
||||
$this->container['dispatcher']->dispatch(
|
||||
self::EVENT_ISSUE_LABEL_CHANGE,
|
||||
new GenericEvent($event)
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
213
sources/app/Integration/GitlabWebhook.php
Normal file
213
sources/app/Integration/GitlabWebhook.php
Normal file
|
@ -0,0 +1,213 @@
|
|||
<?php
|
||||
|
||||
namespace Integration;
|
||||
|
||||
use Event\GenericEvent;
|
||||
use Event\TaskEvent;
|
||||
use Model\Task;
|
||||
|
||||
/**
|
||||
* Gitlab Webhook
|
||||
*
|
||||
* @package integration
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class GitlabWebhook extends Base
|
||||
{
|
||||
/**
|
||||
* Events
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const EVENT_ISSUE_OPENED = 'gitlab.webhook.issue.opened';
|
||||
const EVENT_ISSUE_CLOSED = 'gitlab.webhook.issue.closed';
|
||||
const EVENT_COMMIT = 'gitlab.webhook.commit';
|
||||
|
||||
/**
|
||||
* Supported webhook events
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const TYPE_PUSH = 'push';
|
||||
const TYPE_ISSUE = 'issue';
|
||||
|
||||
/**
|
||||
* Project id
|
||||
*
|
||||
* @access private
|
||||
* @var integer
|
||||
*/
|
||||
private $project_id = 0;
|
||||
|
||||
/**
|
||||
* Set the project id
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
*/
|
||||
public function setProjectId($project_id)
|
||||
{
|
||||
$this->project_id = $project_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse events
|
||||
*
|
||||
* @access public
|
||||
* @param array $payload Gitlab event
|
||||
* @return boolean
|
||||
*/
|
||||
public function parsePayload(array $payload)
|
||||
{
|
||||
switch ($this->getType($payload)) {
|
||||
case self::TYPE_PUSH:
|
||||
return $this->handlePushEvent($payload);
|
||||
case self::TYPE_ISSUE;
|
||||
return $this->handleIssueEvent($payload);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get event type
|
||||
*
|
||||
* @access public
|
||||
* @param array $payload Gitlab event
|
||||
* @return string
|
||||
*/
|
||||
public function getType(array $payload)
|
||||
{
|
||||
if (isset($payload['object_kind']) && $payload['object_kind'] === 'issue') {
|
||||
return self::TYPE_ISSUE;
|
||||
}
|
||||
|
||||
if (isset($payload['commits'])) {
|
||||
return self::TYPE_PUSH;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse push event
|
||||
*
|
||||
* @access public
|
||||
* @param array $payload Gitlab event
|
||||
* @return boolean
|
||||
*/
|
||||
public function handlePushEvent(array $payload)
|
||||
{
|
||||
foreach ($payload['commits'] as $commit) {
|
||||
$this->handleCommit($commit);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse commit
|
||||
*
|
||||
* @access public
|
||||
* @param array $commit Gitlab commit
|
||||
* @return boolean
|
||||
*/
|
||||
public function handleCommit(array $commit)
|
||||
{
|
||||
$task_id = $this->task->getTaskIdFromText($commit['message']);
|
||||
|
||||
if (! $task_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$task = $this->taskFinder->getById($task_id);
|
||||
|
||||
if (! $task) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($task['is_active'] == Task::STATUS_OPEN && $task['project_id'] == $this->project_id) {
|
||||
|
||||
$this->container['dispatcher']->dispatch(
|
||||
self::EVENT_COMMIT,
|
||||
new TaskEvent(array('task_id' => $task_id) + $task)
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse issue event
|
||||
*
|
||||
* @access public
|
||||
* @param array $payload Gitlab event
|
||||
* @return boolean
|
||||
*/
|
||||
public function handleIssueEvent(array $payload)
|
||||
{
|
||||
switch ($payload['object_attributes']['state']) {
|
||||
case 'opened':
|
||||
return $this->handleIssueOpened($payload['object_attributes']);
|
||||
case 'closed':
|
||||
return $this->handleIssueClosed($payload['object_attributes']);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle new issues
|
||||
*
|
||||
* @access public
|
||||
* @param array $issue Issue data
|
||||
* @return boolean
|
||||
*/
|
||||
public function handleIssueOpened(array $issue)
|
||||
{
|
||||
$event = array(
|
||||
'project_id' => $this->project_id,
|
||||
'reference' => $issue['id'],
|
||||
'title' => $issue['title'],
|
||||
'description' => $issue['description']."\n\n[".t('Gitlab Issue').']('.$issue['url'].')',
|
||||
);
|
||||
|
||||
$this->container['dispatcher']->dispatch(
|
||||
self::EVENT_ISSUE_OPENED,
|
||||
new GenericEvent($event)
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle issue closing
|
||||
*
|
||||
* @access public
|
||||
* @param array $issue Issue data
|
||||
* @return boolean
|
||||
*/
|
||||
public function handleIssueClosed(array $issue)
|
||||
{
|
||||
$task = $this->taskFinder->getByReference($issue['id']);
|
||||
|
||||
if ($task) {
|
||||
$event = array(
|
||||
'project_id' => $this->project_id,
|
||||
'task_id' => $task['id'],
|
||||
'reference' => $issue['id'],
|
||||
);
|
||||
|
||||
$this->container['dispatcher']->dispatch(
|
||||
self::EVENT_ISSUE_CLOSED,
|
||||
new GenericEvent($event)
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -182,7 +182,7 @@ return array(
|
|||
'Change assignee' => 'Ændre ansvarlig',
|
||||
'Change assignee for the task "%s"' => 'Ændre ansvarlig for opgaven: "%s"',
|
||||
'Timezone' => 'Tidszone',
|
||||
'Sorry, I didn\'t found this information in my database!' => 'Denne information kunne ikke findes i databasen!',
|
||||
'Sorry, I didn\'t find this information in my database!' => 'Denne information kunne ikke findes i databasen!',
|
||||
'Page not found' => 'Siden er ikke fundet',
|
||||
'Complexity' => 'Kompleksitet',
|
||||
'limit' => 'Begrænsning',
|
||||
|
@ -194,7 +194,7 @@ return array(
|
|||
'Allow this user' => 'Tillad denne bruger',
|
||||
'Only those users have access to this project:' => 'Kunne disse brugere har adgang til dette projekt:',
|
||||
'Don\'t forget that administrators have access to everything.' => 'Glem ikke at administratorer har adgang til alt.',
|
||||
'revoke' => 'fjern',
|
||||
'Revoke' => 'Fjern',
|
||||
'List of authorized users' => 'Liste over autoriserede brugere',
|
||||
'User' => 'Bruger',
|
||||
'Nobody have access to this project.' => 'Ingen har adgang til dette projekt.',
|
||||
|
@ -213,6 +213,7 @@ return array(
|
|||
'Invalid date' => 'Ugyldig dato',
|
||||
'Must be done before %B %e, %Y' => 'Skal være fuldført inden %d.%m.%Y',
|
||||
'%B %e, %Y' => '%d.%m.%Y',
|
||||
// '%b %e, %Y' => '',
|
||||
'Automatic actions' => 'Automatiske handlinger',
|
||||
'Your automatic action have been created successfully.' => 'Din automatiske handling er oprettet.',
|
||||
'Unable to create your automatic action.' => 'Din automatiske handling kunne ikke oprettes.',
|
||||
|
@ -468,18 +469,18 @@ return array(
|
|||
'Unable to change the password.' => 'Adgangskoden kunne ikke ændres.',
|
||||
'Change category for the task "%s"' => 'Skift kategori for opgaven "%s"',
|
||||
'Change category' => 'Skift kategori',
|
||||
'%s updated the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s opdatert opgaven <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s open the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s åben opgaven <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s moved the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to the position #%d in the column "%s"' => '%s flyt opgaven <a href="?controller=task&action=show&task_id=%d">#%d</a> til positionen #%d i kolonnen "%s"',
|
||||
'%s moved the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to the column "%s"' => '%s flyttede opgaven <a href="?controller=task&action=show&task_id=%d">#%d</a> til kolonnen "%s"',
|
||||
'%s created the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s oprettede opgaven <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s closed the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '',
|
||||
'%s created a subtask for the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s oprettede en under-opgave for opgaven <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s updated a subtask for the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s opdaterede en under-opgave for opgaven <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s updated the task %s' => '%s opdatert opgaven %s',
|
||||
'%s opened the task %s' => '%s åben opgaven %s',
|
||||
'%s moved the task %s to the position #%d in the column "%s"' => '%s flyt opgaven %s til positionen #%d i kolonnen "%s"',
|
||||
'%s moved the task %s to the column "%s"' => '%s flyttede opgaven %s til kolonnen "%s"',
|
||||
'%s created the task %s' => '%s oprettede opgaven %s',
|
||||
'%s closed the task %s' => '',
|
||||
'%s created a subtask for the task %s' => '%s oprettede en under-opgave for opgaven %s',
|
||||
'%s updated a subtask for the task %s' => '%s opdaterede en under-opgave for opgaven %s',
|
||||
'Assigned to %s with an estimate of %s/%sh' => 'Tildelt til %s med en estimering på %s/%sh',
|
||||
'Not assigned, estimate of %sh' => 'Ikke tildelt, estimeret til %sh',
|
||||
'%s updated a comment on the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s opdateret en kommentar på opgaven <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s commented the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s har kommenteret opgaven <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s updated a comment on the task %s' => '%s opdateret en kommentar på opgaven %s',
|
||||
'%s commented the task %s' => '%s har kommenteret opgaven %s',
|
||||
'%s\'s activity' => '%s\'s aktvitet',
|
||||
'No activity.' => 'Ingen aktivitet',
|
||||
'RSS feed' => 'RSS feed',
|
||||
|
@ -498,7 +499,7 @@ return array(
|
|||
'Default columns for new projects (Comma-separated)' => 'Standard kolonne for nye projekter (kommasepareret)',
|
||||
'Task assignee change' => 'Opgaven ansvarlig ændring',
|
||||
'%s change the assignee of the task #%d to %s' => '%s skrift ansvarlig for opgaven #%d til %s',
|
||||
'%s change the assignee of the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to %s' => '%s skift ansvarlig for opgaven <a href="?controller=task&action=show&task_id=%d">#%d</a> til %s',
|
||||
'%s changed the assignee of the task %s to %s' => '%s skift ansvarlig for opgaven %s til %s',
|
||||
'[%s][Column Change] %s (#%d)' => '[%s][Kolonne Skift] %s (#%d)',
|
||||
'[%s][Position Change] %s (#%d)' => '[%s][Position Skift] %s (#%d)',
|
||||
'[%s][Assignee Change] %s (#%d)' => '[%s][Ansvarlig Skift] %s (#%d)',
|
||||
|
@ -555,8 +556,8 @@ return array(
|
|||
// 'Webhooks' => '',
|
||||
// 'API' => '',
|
||||
// 'Integration' => '',
|
||||
// 'Github webhook' => '',
|
||||
// 'Help on Github webhook' => '',
|
||||
// 'Github webhooks' => '',
|
||||
// 'Help on Github webhooks' => '',
|
||||
// 'Create a comment from an external provider' => '',
|
||||
// 'Github issue comment created' => '',
|
||||
// 'Configure' => '',
|
||||
|
@ -602,4 +603,49 @@ return array(
|
|||
// 'Nothing to preview...' => '',
|
||||
// 'Preview' => '',
|
||||
// 'Write' => '',
|
||||
// 'Active swimlanes' => '',
|
||||
// 'Add a new swimlane' => '',
|
||||
// 'Change default swimlane' => '',
|
||||
// 'Default swimlane' => '',
|
||||
// 'Do you really want to remove this swimlane: "%s"?' => '',
|
||||
// 'Inactive swimlanes' => '',
|
||||
// 'Set project manager' => '',
|
||||
// 'Set project member' => '',
|
||||
// 'Remove a swimlane' => '',
|
||||
// 'Rename' => '',
|
||||
// 'Show default swimlane' => '',
|
||||
// 'Swimlane modification for the project "%s"' => '',
|
||||
// 'Swimlane not found.' => '',
|
||||
// 'Swimlane removed successfully.' => '',
|
||||
// 'Swimlanes' => '',
|
||||
// 'Swimlane updated successfully.' => '',
|
||||
// 'The default swimlane have been updated successfully.' => '',
|
||||
// 'Unable to create your swimlane.' => '',
|
||||
// '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)' => '',
|
||||
// 'Gitlab commit received' => '',
|
||||
// 'Gitlab issue opened' => '',
|
||||
// 'Gitlab issue closed' => '',
|
||||
// 'Gitlab webhooks' => '',
|
||||
// 'Help on Gitlab webhooks' => '',
|
||||
// 'Integrations' => '',
|
||||
// 'Integration with third-party services' => '',
|
||||
// 'Role for this project' => '',
|
||||
// 'Project manager' => '',
|
||||
// 'Project member' => '',
|
||||
// 'A project manager can change the settings of the project and have more privileges than a standard user.' => '',
|
||||
// 'Gitlab Issue' => '',
|
||||
// 'Subtask Id' => '',
|
||||
// 'Subtasks' => '',
|
||||
// 'Subtasks Export' => '',
|
||||
// 'Subtasks exportation for "%s"' => '',
|
||||
// 'Task Title' => '',
|
||||
// 'Untitled' => '',
|
||||
// 'Application default' => '',
|
||||
// 'Language:' => '',
|
||||
// 'Timezone:' => '',
|
||||
// 'Next' => '',
|
||||
);
|
||||
|
|
|
@ -49,7 +49,7 @@ return array(
|
|||
'No project' => 'Keine Projekte',
|
||||
'Project' => 'Projekt',
|
||||
'Status' => 'Status',
|
||||
'Tasks' => 'Aufgabe',
|
||||
'Tasks' => 'Aufgaben',
|
||||
'Board' => 'Pinnwand',
|
||||
'Actions' => 'Aktionen',
|
||||
'Inactive' => 'Inaktiv',
|
||||
|
@ -182,7 +182,7 @@ return array(
|
|||
'Change assignee' => 'Zuständigkeit ändern',
|
||||
'Change assignee for the task "%s"' => 'Zuständigkeit für diese Aufgabe ändern: "%s"',
|
||||
'Timezone' => 'Zeitzone',
|
||||
'Sorry, I didn\'t found this information in my database!' => 'Diese Information wurde in der Datenbank nicht gefunden!',
|
||||
'Sorry, I didn\'t find this information in my database!' => 'Diese Information wurde in der Datenbank nicht gefunden!',
|
||||
'Page not found' => 'Seite nicht gefunden',
|
||||
'Complexity' => 'Komplexität',
|
||||
'limit' => 'Limit',
|
||||
|
@ -194,7 +194,7 @@ return array(
|
|||
'Allow this user' => 'Diesen Benutzer autorisieren',
|
||||
'Only those users have access to this project:' => 'Nur diese Benutzer haben Zugriff zum Projekt:',
|
||||
'Don\'t forget that administrators have access to everything.' => 'Nicht vergessen: Administratoren haben überall Zugriff.',
|
||||
'revoke' => 'entfernen',
|
||||
'Revoke' => 'Entfernen',
|
||||
'List of authorized users' => 'Liste der autorisierten Benutzer',
|
||||
'User' => 'Benutzer',
|
||||
'Nobody have access to this project.' => 'Niemand hat Zugriff auf dieses Projekt.',
|
||||
|
@ -202,9 +202,9 @@ return array(
|
|||
'Comments' => 'Kommentare',
|
||||
'Post comment' => 'Kommentieren',
|
||||
'Write your text in Markdown' => 'Schreibe deinen Text in Markdown-Syntax',
|
||||
'Leave a comment' => 'Kommentar eingeben...',
|
||||
'Leave a comment' => 'Kommentar eingeben',
|
||||
'Comment is required' => 'Ein Kommentar wird benötigt',
|
||||
'Leave a description' => 'Beschreibung eingeben...',
|
||||
'Leave a description' => 'Beschreibung eingeben',
|
||||
'Comment added successfully.' => 'Kommentar erfolgreich hinzugefügt.',
|
||||
'Unable to create your comment.' => 'Hinzufügen eines Kommentars nicht möglich.',
|
||||
'The description is required' => 'Eine Beschreibung wird benötigt',
|
||||
|
@ -213,8 +213,9 @@ return array(
|
|||
'Invalid date' => 'Ungültiges Datum',
|
||||
'Must be done before %B %e, %Y' => 'Muss vor dem %d.%m.%Y erledigt werden',
|
||||
'%B %e, %Y' => '%d.%m.%Y',
|
||||
// '%b %e, %Y' => '',
|
||||
'Automatic actions' => 'Automatische Aktionen',
|
||||
'Your automatic action have been created successfully.' => 'Die Automatische Aktion wurde erfolgreich erstellt.',
|
||||
'Your automatic action have been created successfully.' => 'Die automatische Aktion wurde erfolgreich erstellt.',
|
||||
'Unable to create your automatic action.' => 'Erstellen der automatischen Aktion nicht möglich.',
|
||||
'Remove an action' => 'Aktion löschen',
|
||||
'Unable to remove this action.' => 'Löschen der Aktion nicht möglich.',
|
||||
|
@ -222,8 +223,8 @@ return array(
|
|||
'Automatic actions for the project "%s"' => 'Automatische Aktionen für das Projekt "%s"',
|
||||
'Defined actions' => 'Definierte Aktionen',
|
||||
'Add an action' => 'Aktion hinzufügen',
|
||||
'Event name' => 'Ereignis',
|
||||
'Action name' => 'Aktion',
|
||||
'Event name' => 'Ereignisname',
|
||||
'Action name' => 'Aktionsname',
|
||||
'Action parameters' => 'Aktionsparameter',
|
||||
'Action' => 'Aktion',
|
||||
'Event' => 'Ereignis',
|
||||
|
@ -331,7 +332,7 @@ return array(
|
|||
'Remove a file' => 'Datei löschen',
|
||||
'Unable to remove this file.' => 'Löschen der Datei nicht möglich.',
|
||||
'File removed successfully.' => 'Datei erfolgreich gelöscht.',
|
||||
'Attach a document' => 'Datei anhängen',
|
||||
'Attach a document' => 'Dokument anhängen',
|
||||
'Do you really want to remove this file: "%s"?' => 'Soll diese Datei wirklich gelöscht werden: "%s"?',
|
||||
'open' => 'öffnen',
|
||||
'Attachments' => 'Anhänge',
|
||||
|
@ -366,7 +367,7 @@ return array(
|
|||
'Sub-task added successfully.' => 'Teilaufgabe erfolgreich angelegt.',
|
||||
'Maximum size: ' => 'Maximalgröße: ',
|
||||
'Unable to upload the file.' => 'Hochladen der Datei nicht möglich.',
|
||||
'Display another project' => 'Zu Projekt wechseln...',
|
||||
'Display another project' => 'Zu Projekt wechseln',
|
||||
'Your GitHub account was successfully linked to your profile.' => 'GitHub Account erfolgreich mit dem Profil verbunden.',
|
||||
'Unable to link your GitHub Account.' => 'Verbindung mit diesem GitHub Account nicht möglich.',
|
||||
'GitHub authentication failed' => 'Zugriff mit GitHub fehlgeschlagen',
|
||||
|
@ -420,7 +421,7 @@ return array(
|
|||
'[Kanboard] Notification' => '[Kanboard] Benachrichtigung',
|
||||
'I want to receive notifications only for those projects:' => 'Ich möchte nur für diese Projekte Benachrichtigungen erhalten:',
|
||||
'view the task on Kanboard' => 'diese Aufgabe auf dem Kanboard zeigen',
|
||||
'Public access' => 'Öffentlich',
|
||||
'Public access' => 'Öffentlicher Zugriff',
|
||||
'Category management' => 'Kategorien verwalten',
|
||||
'User management' => 'Benutzer verwalten',
|
||||
'Active tasks' => 'Aktive Aufgaben',
|
||||
|
@ -448,12 +449,12 @@ return array(
|
|||
'Username:' => 'Benutzername',
|
||||
'Name:' => 'Name',
|
||||
'Email:' => 'E-Mail',
|
||||
'Default project:' => 'Standardprojekt',
|
||||
'Notifications:' => 'Benachrichtigungen',
|
||||
'Default project:' => 'Standardprojekt:',
|
||||
'Notifications:' => 'Benachrichtigungen:',
|
||||
'Notifications' => 'Benachrichtigungen',
|
||||
'Group:' => 'Gruppe',
|
||||
'Regular user' => 'Standardbenutzer',
|
||||
'Account type:' => 'Accounttyp',
|
||||
'Account type:' => 'Accounttyp:',
|
||||
'Edit profile' => 'Profil bearbeiten',
|
||||
'Change password' => 'Passwort ändern',
|
||||
'Password modification' => 'Passwortänderung',
|
||||
|
@ -468,18 +469,18 @@ return array(
|
|||
'Unable to change the password.' => 'Passwort konnte nicht geändert werden.',
|
||||
'Change category for the task "%s"' => 'Kategorie der Aufgabe "%s" ändern',
|
||||
'Change category' => 'Kategorie ändern',
|
||||
'%s updated the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s hat die Aufgabe <a href="?controller=task&action=show&task_id=%d">#%d</a> aktualisiert',
|
||||
'%s open the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s hat die Aufgabe <a href="?controller=task&action=show&task_id=%d">#%d</a> geöffnet',
|
||||
'%s moved the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to the position #%d in the column "%s"' => '%s hat die Aufgabe <a href="?controller=task&action=show&task_id=%d">#%d</a> auf die Position #%d in der Spalte "%s" verschoben',
|
||||
'%s moved the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to the column "%s"' => '%s hat die Aufgabe <a href="?controller=task&action=show&task_id=%d">#%d</a> in die Spalte "%s" verschoben',
|
||||
'%s created the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s hat die Aufgabe <a href="?controller=task&action=show&task_id=%d">#%d</a> angelegt',
|
||||
'%s closed the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s hat die Aufgabe <a href="?controller=task&action=show&task_id=%d">#%d</a> geschlossen',
|
||||
'%s created a subtask for the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s hat eine Teilaufgabe für die Aufgabe <a href="?controller=task&action=show&task_id=%d">#%d</a> angelegt',
|
||||
'%s updated a subtask for the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s hat eine Teilaufgabe der Aufgabe <a href="?controller=task&action=show&task_id=%d">#%d</a> verändert',
|
||||
'%s updated the task %s' => '%s hat die Aufgabe %s aktualisiert',
|
||||
'%s opened the task %s' => '%s hat die Aufgabe %s geöffnet',
|
||||
'%s moved the task %s to the position #%d in the column "%s"' => '%s hat die Aufgabe %s auf die Position #%d in der Spalte "%s" verschoben',
|
||||
'%s moved the task %s to the column "%s"' => '%s hat die Aufgabe %s in die Spalte "%s" verschoben',
|
||||
'%s created the task %s' => '%s hat die Aufgabe %s angelegt',
|
||||
'%s closed the task %s' => '%s hat die Aufgabe %s geschlossen',
|
||||
'%s created a subtask for the task %s' => '%s hat eine Teilaufgabe für die Aufgabe %s angelegt',
|
||||
'%s updated a subtask for the task %s' => '%s hat eine Teilaufgabe der Aufgabe %s verändert',
|
||||
'Assigned to %s with an estimate of %s/%sh' => 'An %s zugewiesen mit einer Schätzung von %s/%s Stunden',
|
||||
'Not assigned, estimate of %sh' => 'Nicht zugewiesen, Schätzung von %s Stunden',
|
||||
'%s updated a comment on the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s hat einen Kommentat der Aufgabe <a href="?controller=task&action=show&task_id=%d">#%d</a> aktualisiert',
|
||||
'%s commented the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s hat die Aufgabe <a href="?controller=task&action=show&task_id=%d">#%d</a> kommentiert',
|
||||
'%s updated a comment on the task %s' => '%s hat einen Kommentat der Aufgabe %s aktualisiert',
|
||||
'%s commented the task %s' => '%s hat die Aufgabe %s kommentiert',
|
||||
'%s\'s activity' => '%s\'s Aktivität',
|
||||
'No activity.' => 'Keine Aktivität.',
|
||||
'RSS feed' => 'RSS Feed',
|
||||
|
@ -498,7 +499,7 @@ return array(
|
|||
'Default columns for new projects (Comma-separated)' => 'Standardspalten für neue Projekte (komma-getrennt)',
|
||||
'Task assignee change' => 'Zuständigkeit geändert',
|
||||
'%s change the assignee of the task #%d to %s' => '%s hat die Zusständigkeit der Aufgabe #%d geändert um %s',
|
||||
'%s change the assignee of the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to %s' => '%s hat die Zuständigkeit der Aufgabe <a href="?controller=task&action=show&task_id=%d">#%d</a> geändert um %s',
|
||||
'%s changed the assignee of the task %s to %s' => '%s hat die Zuständigkeit der Aufgabe %s geändert um %s',
|
||||
'[%s][Column Change] %s (#%d)' => '[%s][Spaltenänderung] %s (#%d)',
|
||||
'[%s][Position Change] %s (#%d)' => '[%s][Positionsänderung] %s (#%d)',
|
||||
'[%s][Assignee Change] %s (#%d)' => '[%s][Zuständigkeitsänderung] %s (#%d)',
|
||||
|
@ -511,7 +512,7 @@ return array(
|
|||
'Github issue assignee change' => 'Github Fehlerzuständigkeit geändert',
|
||||
'Github issue label change' => 'Github Fehlerkennzeichnung verändert',
|
||||
'Create a task from an external provider' => 'Eine Aufgabe durch einen externen Provider hinzufügen',
|
||||
// 'Change the assignee based on an external username' => '',
|
||||
'Change the assignee based on an external username' => 'Zuordnung ändern basierend auf externem Benutzernamen',
|
||||
'Change the category based on an external label' => 'Kategorie basierend auf einer externen Kennzeichnung ändern',
|
||||
'Reference' => 'Referenz',
|
||||
'Reference: %s' => 'Referenz: %s',
|
||||
|
@ -544,8 +545,8 @@ return array(
|
|||
'Time spent: %s hours' => 'Aufgewendete Zeit: %s Stunden',
|
||||
'Started on %B %e, %Y' => 'Gestartet am %B %e %Y',
|
||||
'Start date' => 'Startdatum',
|
||||
'Time estimated' => 'Geplante Zeit',
|
||||
'There is nothing assigned to you.' => 'Es ist nichts an Sie zugewiesen.',
|
||||
'Time estimated' => 'Geschätzte Zeit',
|
||||
'There is nothing assigned to you.' => 'Ihnen ist nichts zugewiesen.',
|
||||
'My tasks' => 'Meine Aufgaben',
|
||||
'Activity stream' => 'Letzte Aktivitäten',
|
||||
'Dashboard' => 'Dashboard',
|
||||
|
@ -555,11 +556,11 @@ return array(
|
|||
'Webhooks' => 'Webhooks',
|
||||
'API' => 'API',
|
||||
'Integration' => 'Integration',
|
||||
'Github webhook' => 'Github Webhook',
|
||||
'Help on Github webhook' => 'Hilfe bei einem Github Webhook',
|
||||
'Github webhooks' => 'Github Webhook',
|
||||
'Help on Github webhooks' => 'Hilfe für Github Webhooks',
|
||||
'Create a comment from an external provider' => 'Kommentar eines externen Providers hinzufügen',
|
||||
'Github issue comment created' => 'Github Fehler Kommentar hinzugefügt',
|
||||
'Configure' => 'konfigurieren',
|
||||
'Configure' => 'Einstellungen',
|
||||
'Project management' => 'Projektmanagement',
|
||||
'My projects' => 'Meine Projekte',
|
||||
'Columns' => 'Spalten',
|
||||
|
@ -602,4 +603,49 @@ return array(
|
|||
'Nothing to preview...' => 'Nichts in der Vorschau anzuzeigen ...',
|
||||
'Preview' => 'Vorschau',
|
||||
'Write' => 'Ändern',
|
||||
'Active swimlanes' => 'Aktive Swimlane',
|
||||
'Add a new swimlane' => 'Eine neue Swimlane hinzufügen',
|
||||
'Change default swimlane' => 'Standard Swimlane ändern',
|
||||
'Default swimlane' => 'Standard Swimlane',
|
||||
'Do you really want to remove this swimlane: "%s"?' => 'Diese Swimlane wirklich ändern: "%s"?',
|
||||
'Inactive swimlanes' => 'Inaktive Swimlane',
|
||||
'Set project manager' => 'zum Projektmanager machen',
|
||||
'Set project member' => 'zum Projektmitglied machen',
|
||||
'Remove a swimlane' => 'Swimlane entfernen',
|
||||
'Rename' => 'umbenennen',
|
||||
'Show default swimlane' => 'Standard Swimlane anzeigen',
|
||||
'Swimlane modification for the project "%s"' => 'Swimlane Änderung für das Projekt "% s"',
|
||||
'Swimlane not found.' => 'Swimlane nicht gefunden',
|
||||
'Swimlane removed successfully.' => 'Swimlane erfolgreich entfernt.',
|
||||
'Swimlanes' => 'Swimlanes',
|
||||
'Swimlane updated successfully.' => 'Swimlane erfolgreich geändert.',
|
||||
'The default swimlane have been updated successfully.' => 'Die standard Swimlane wurden erfolgreich aktualisiert. Die standard Swimlane wurden erfolgreich aktualisiert.',
|
||||
'Unable to create your swimlane.' => 'Es ist nicht möglich die Swimlane zu erstellen.',
|
||||
'Unable to remove this swimlane.' => 'Es ist nicht möglich die Swimlane zu entfernen.',
|
||||
'Unable to update this swimlane.' => 'Es ist nicht möglich die Swimöane zu ändern.',
|
||||
'Your swimlane have been created successfully.' => 'Die Swimlane wurde erfolgreich angelegt.',
|
||||
'Example: "Bug, Feature Request, Improvement"' => 'Beispiel: "Bug, Funktionswünsche, Verbesserung"',
|
||||
'Default categories for new projects (Comma-separated)' => 'Standard Kategorien für neue Projekte (Komma-getrennt)',
|
||||
'Gitlab commit received' => 'Gitlab commit erhalten',
|
||||
'Gitlab issue opened' => 'Gitlab Thema eröffnet',
|
||||
'Gitlab issue closed' => 'Gitlab Thema geschlossen',
|
||||
'Gitlab webhooks' => 'Gitlab Webhook',
|
||||
'Help on Gitlab webhooks' => 'Hilfe für Gitlab Webhooks',
|
||||
'Integrations' => 'Integration',
|
||||
'Integration with third-party services' => 'Integration von Fremdleistungen',
|
||||
'Role for this project' => 'Rolle für dieses Projekt',
|
||||
'Project manager' => 'Projektmanager',
|
||||
'Project member' => 'Projektmitglied',
|
||||
'A project manager can change the settings of the project and have more privileges than a standard user.' => 'Ein Projektmanager kann die Projekteinstellungen ändern und hat mehr Rechte als ein normaler Benutzer.',
|
||||
'Gitlab Issue' => 'Gitlab Thema',
|
||||
'Subtask Id' => 'Teilaufgaben Id',
|
||||
'Subtasks' => 'Teilaufgaben',
|
||||
'Subtasks Export' => 'Teilaufgaben Export',
|
||||
'Subtasks exportation for "%s"' => 'Teilaufgaben Export für "%s"',
|
||||
'Task Title' => 'Aufgaben Titel',
|
||||
'Untitled' => 'unbetitelt',
|
||||
'Application default' => 'Anwendungsstandard',
|
||||
'Language:' => 'Sprache:',
|
||||
'Timezone:' => 'Zeitzone:',
|
||||
// 'Next' => '',
|
||||
);
|
||||
|
|
|
@ -182,7 +182,7 @@ return array(
|
|||
'Change assignee' => 'Cambiar la persona asignada',
|
||||
'Change assignee for the task "%s"' => 'Cambiar la persona asignada por la tarea « %s »',
|
||||
'Timezone' => 'Zona horaria',
|
||||
'Sorry, I didn\'t found this information in my database!' => 'Lo siento no he encontrado información en la base de datos!',
|
||||
'Sorry, I didn\'t find this information in my database!' => 'Lo siento no he encontrado información en la base de datos!',
|
||||
'Page not found' => 'Página no encontrada',
|
||||
'Complexity' => 'Complejidad',
|
||||
'limit' => 'límite',
|
||||
|
@ -194,7 +194,7 @@ return array(
|
|||
'Allow this user' => 'Autorizar este usuario',
|
||||
'Only those users have access to this project:' => 'Solo estos usuarios tienen acceso a este proyecto:',
|
||||
'Don\'t forget that administrators have access to everything.' => 'No olvide que los administradores tienen acceso a todo.',
|
||||
'revoke' => 'revocar',
|
||||
'Revoke' => 'Revocar',
|
||||
'List of authorized users' => 'Lista de los usuarios autorizados',
|
||||
'User' => 'Usuario',
|
||||
// 'Nobody have access to this project.' => '',
|
||||
|
@ -213,6 +213,7 @@ return array(
|
|||
'Invalid date' => 'Fecha no válida',
|
||||
'Must be done before %B %e, %Y' => 'Debe de estar hecho antes del %d/%m/%Y',
|
||||
'%B %e, %Y' => '%d/%m/%Y',
|
||||
// '%b %e, %Y' => '',
|
||||
'Automatic actions' => 'Acciones automatizadas',
|
||||
'Your automatic action have been created successfully.' => 'La acción automatizada ha sido creada correctamente.',
|
||||
'Unable to create your automatic action.' => 'No se puede crear esta acción automatizada.',
|
||||
|
@ -452,7 +453,7 @@ return array(
|
|||
'Notifications:' => 'Notificaciones:',
|
||||
// 'Notifications' => '',
|
||||
'Group:' => 'Grupo:',
|
||||
'Regular user' => 'Usuario regular:',
|
||||
'Regular user' => 'Usuario regular',
|
||||
'Account type:' => 'Tipo de Cuenta:',
|
||||
'Edit profile' => 'Editar perfil',
|
||||
'Change password' => 'Cambiar contraseña',
|
||||
|
@ -468,18 +469,18 @@ return array(
|
|||
'Unable to change the password.' => 'No pude cambiar la contraseña.',
|
||||
'Change category for the task "%s"' => 'Cambiar la categoría de la tarea "%s"',
|
||||
'Change category' => 'Cambiar categoría',
|
||||
'%s updated the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s actualizó la tarea <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s open the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s abrió la tarea <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s moved the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to the position #%d in the column "%s"' => '%s movió la tarea <a href="?controller=task&action=show&task_id=%d">#%d</a> a la posición #%d de la columna "%s"',
|
||||
'%s moved the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to the column "%s"' => '%s movió la tarea <a href="?controller=task&action=show&task_id=%d">#%d</a> a la columna "%s"',
|
||||
'%s created the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s creó la tarea <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s closed the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s cerró la tarea <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s created a subtask for the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s creó una subtarea para la tarea <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s updated a subtask for the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s actualizó una subtarea para la tarea <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s updated the task %s' => '%s actualizó la tarea %s',
|
||||
'%s opened the task %s' => '%s abrió la tarea %s',
|
||||
'%s moved the task %s to the position #%d in the column "%s"' => '%s movió la tarea %s a la posición #%d de la columna "%s"',
|
||||
'%s moved the task %s to the column "%s"' => '%s movió la tarea %s a la columna "%s"',
|
||||
'%s created the task %s' => '%s creó la tarea %s',
|
||||
'%s closed the task %s' => '%s cerró la tarea %s',
|
||||
'%s created a subtask for the task %s' => '%s creó una subtarea para la tarea %s',
|
||||
'%s updated a subtask for the task %s' => '%s actualizó una subtarea para la tarea %s',
|
||||
'Assigned to %s with an estimate of %s/%sh' => 'Asignada a %s con una estimación de %s/%sh',
|
||||
'Not assigned, estimate of %sh' => 'No asignada, se estima en %sh',
|
||||
'%s updated a comment on the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s actualizó un comentario de la tarea <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s commented the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s comentó la tarea <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s updated a comment on the task %s' => '%s actualizó un comentario de la tarea %s',
|
||||
'%s commented the task %s' => '%s comentó la tarea %s',
|
||||
'%s\'s activity' => 'Actividad de %s',
|
||||
'No activity.' => 'Sin actividad',
|
||||
'RSS feed' => 'Fichero RSS',
|
||||
|
@ -498,7 +499,7 @@ return array(
|
|||
'Default columns for new projects (Comma-separated)' => 'Columnas por defecto de los nuevos proyectos (Separadas mediante comas)',
|
||||
'Task assignee change' => 'Cambiar persona asignada a la tarea',
|
||||
// '%s change the assignee of the task #%d to %s' => '',
|
||||
// '%s change the assignee of the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to %s' => '',
|
||||
// '%s changed the assignee of the task %s to %s' => '',
|
||||
'[%s][Column Change] %s (#%d)' => '[%s][Cambia Columna] %s (#%d)',
|
||||
'[%s][Position Change] %s (#%d)' => '[%s][Cambia Posición] %s (#%d)',
|
||||
'[%s][Assignee Change] %s (#%d)' => '[%s][Cambia Persona Asignada] %s (#%d)',
|
||||
|
@ -555,8 +556,8 @@ return array(
|
|||
// 'Webhooks' => '',
|
||||
// 'API' => '',
|
||||
// 'Integration' => '',
|
||||
// 'Github webhook' => '',
|
||||
// 'Help on Github webhook' => '',
|
||||
// 'Github webhooks' => '',
|
||||
// 'Help on Github webhooks' => '',
|
||||
// 'Create a comment from an external provider' => '',
|
||||
// 'Github issue comment created' => '',
|
||||
// 'Configure' => '',
|
||||
|
@ -602,4 +603,49 @@ return array(
|
|||
// 'Nothing to preview...' => '',
|
||||
// 'Preview' => '',
|
||||
// 'Write' => '',
|
||||
// 'Active swimlanes' => '',
|
||||
// 'Add a new swimlane' => '',
|
||||
// 'Change default swimlane' => '',
|
||||
// 'Default swimlane' => '',
|
||||
// 'Do you really want to remove this swimlane: "%s"?' => '',
|
||||
// 'Inactive swimlanes' => '',
|
||||
// 'Set project manager' => '',
|
||||
// 'Set project member' => '',
|
||||
// 'Remove a swimlane' => '',
|
||||
// 'Rename' => '',
|
||||
// 'Show default swimlane' => '',
|
||||
// 'Swimlane modification for the project "%s"' => '',
|
||||
// 'Swimlane not found.' => '',
|
||||
// 'Swimlane removed successfully.' => '',
|
||||
// 'Swimlanes' => '',
|
||||
// 'Swimlane updated successfully.' => '',
|
||||
// 'The default swimlane have been updated successfully.' => '',
|
||||
// 'Unable to create your swimlane.' => '',
|
||||
// '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)' => '',
|
||||
// 'Gitlab commit received' => '',
|
||||
// 'Gitlab issue opened' => '',
|
||||
// 'Gitlab issue closed' => '',
|
||||
// 'Gitlab webhooks' => '',
|
||||
// 'Help on Gitlab webhooks' => '',
|
||||
// 'Integrations' => '',
|
||||
// 'Integration with third-party services' => '',
|
||||
// 'Role for this project' => '',
|
||||
// 'Project manager' => '',
|
||||
// 'Project member' => '',
|
||||
// 'A project manager can change the settings of the project and have more privileges than a standard user.' => '',
|
||||
// 'Gitlab Issue' => '',
|
||||
// 'Subtask Id' => '',
|
||||
// 'Subtasks' => '',
|
||||
// 'Subtasks Export' => '',
|
||||
// 'Subtasks exportation for "%s"' => '',
|
||||
// 'Task Title' => '',
|
||||
// 'Untitled' => '',
|
||||
// 'Application default' => '',
|
||||
// 'Language:' => '',
|
||||
// 'Timezone:' => '',
|
||||
// 'Next' => '',
|
||||
);
|
||||
|
|
|
@ -182,19 +182,19 @@ return array(
|
|||
'Change assignee' => 'Vaihda suorittajaa',
|
||||
'Change assignee for the task "%s"' => 'Vaihda suorittajaa tehtävälle %s',
|
||||
'Timezone' => 'Aikavyöhyke',
|
||||
'Sorry, I didn\'t found this information in my database!' => 'Anteeksi, en löytänyt tätä tietoa tietokannastani',
|
||||
'Sorry, I didn\'t find this information in my database!' => 'Anteeksi, en löytänyt tätä tietoa tietokannastani',
|
||||
'Page not found' => 'Sivua ei löydy',
|
||||
'Complexity' => 'Monimutkaisuus',
|
||||
'limit' => 'raja',
|
||||
'Task limit' => 'Tehtävien maksimimäärä',
|
||||
// 'Task count' => '',
|
||||
'Task count' => 'Tehtävien määrä',
|
||||
'This value must be greater than %d' => 'Arvon täytyy olla suurempi kuin %d',
|
||||
'Edit project access list' => 'Muuta projektin käyttäjiä',
|
||||
'Edit users access' => 'Muuta käyttäjien pääsyä',
|
||||
'Allow this user' => 'Salli tämä projekti',
|
||||
'Only those users have access to this project:' => 'Vain näillä käyttäjillä on pääsy projektiin:',
|
||||
'Don\'t forget that administrators have access to everything.' => 'Muista että ylläpitäjät pääsevät kaikkialle.',
|
||||
'revoke' => 'poista',
|
||||
'Revoke' => 'Poista',
|
||||
'List of authorized users' => 'Sallittujen käyttäjien lista',
|
||||
'User' => 'Käyttäjät',
|
||||
// 'Nobody have access to this project.' => '',
|
||||
|
@ -213,6 +213,7 @@ return array(
|
|||
'Invalid date' => 'Virheellinen päiväys',
|
||||
'Must be done before %B %e, %Y' => 'Täytyy suorittaa ennen %d.%m.%Y',
|
||||
'%B %e, %Y' => '%d.%m.%Y',
|
||||
// '%b %e, %Y' => '',
|
||||
'Automatic actions' => 'Automaattiset toiminnot',
|
||||
'Your automatic action have been created successfully.' => 'Toiminto suoritettiin onnistuneesti.',
|
||||
'Unable to create your automatic action.' => 'Automaattisen toiminnon luominen epäonnistui.',
|
||||
|
@ -367,14 +368,14 @@ return array(
|
|||
'Maximum size: ' => 'Maksimikoko: ',
|
||||
'Unable to upload the file.' => 'Tiedoston lataus epäonnistui.',
|
||||
'Display another project' => 'Näytä toinen projekti',
|
||||
// 'Your GitHub account was successfully linked to your profile.' => '',
|
||||
// 'Unable to link your GitHub Account.' => '',
|
||||
// 'GitHub authentication failed' => '',
|
||||
// 'Your GitHub account is no longer linked to your profile.' => '',
|
||||
// 'Unable to unlink your GitHub Account.' => '',
|
||||
// 'Login with my GitHub Account' => '',
|
||||
// 'Link my GitHub Account' => '',
|
||||
// 'Unlink my GitHub Account' => '',
|
||||
'Your GitHub account was successfully linked to your profile.' => 'Github-tilisi on onnistuneesti liitetty profiiliisi',
|
||||
'Unable to link your GitHub Account.' => 'Github-tilin liittäminen epäonnistui',
|
||||
'GitHub authentication failed' => 'Github-todennus epäonnistui',
|
||||
'Your GitHub account is no longer linked to your profile.' => 'Github-tiliäsi ei ole enää liitetty profiiliisi.',
|
||||
'Unable to unlink your GitHub Account.' => 'Github-tilisi liitoksen poisto epäonnistui',
|
||||
'Login with my GitHub Account' => 'Kirjaudu sisään Github-tililläni',
|
||||
'Link my GitHub Account' => 'Liitä Github-tilini',
|
||||
'Unlink my GitHub Account' => 'Poista liitos Github-tiliini',
|
||||
'Created by %s' => 'Luonut: %s',
|
||||
'Last modified on %B %e, %Y at %k:%M %p' => 'Viimeksi muokattu %B %e, %Y kello %H:%M',
|
||||
'Tasks Export' => 'Tehtävien vienti',
|
||||
|
@ -388,24 +389,24 @@ return array(
|
|||
'Completion date' => 'Valmistumispäivä',
|
||||
'Webhook URL for task creation' => 'Webhook URL tehtävän luomiselle',
|
||||
'Webhook URL for task modification' => 'Webhook URL tehtävän muokkaamiselle',
|
||||
// 'Clone' => '',
|
||||
// 'Clone Project' => '',
|
||||
// 'Project cloned successfully.' => '',
|
||||
// 'Unable to clone this project.' => '',
|
||||
// 'Email notifications' => '',
|
||||
// 'Enable email notifications' => '',
|
||||
// 'Task position:' => '',
|
||||
// 'The task #%d have been opened.' => '',
|
||||
// 'The task #%d have been closed.' => '',
|
||||
// 'Sub-task updated' => '',
|
||||
// 'Title:' => '',
|
||||
// 'Status:' => '',
|
||||
// 'Assignee:' => '',
|
||||
// 'Time tracking:' => '',
|
||||
// 'New sub-task' => '',
|
||||
// 'New attachment added "%s"' => '',
|
||||
// 'Comment updated' => '',
|
||||
// 'New comment posted by %s' => '',
|
||||
'Clone' => 'Kahdenna',
|
||||
'Clone Project' => 'Kahdenna projekti',
|
||||
'Project cloned successfully.' => 'Projekti kahdennettu onnistuneesti',
|
||||
'Unable to clone this project.' => 'Projektin kahdennus epäonnistui',
|
||||
'Email notifications' => 'Sähköposti-ilmoitukset',
|
||||
'Enable email notifications' => 'Ota käyttöön sähköposti-ilmoitukset',
|
||||
'Task position:' => 'Tehtävän sijainti',
|
||||
'The task #%d have been opened.' => 'Tehtävä #%d on avattu',
|
||||
'The task #%d have been closed.' => 'Tehtävä #%d on suljettu',
|
||||
'Sub-task updated' => 'Alitehtävä päivitetty',
|
||||
'Title:' => 'Otsikko:',
|
||||
'Status:' => 'Tila:',
|
||||
'Assignee:' => 'Vastaanottaja:',
|
||||
'Time tracking:' => 'Ajan seuranta:',
|
||||
'New sub-task' => 'Uusi alitehtävä',
|
||||
'New attachment added "%s"' => 'Uusi liite lisätty "%s"',
|
||||
'Comment updated' => 'Kommentti päivitetty',
|
||||
'New comment posted by %s' => '%s lisäsi uuden kommentin',
|
||||
// 'List of due tasks for the project "%s"' => '',
|
||||
// '[%s][New attachment] %s (#%d)' => '',
|
||||
// '[%s][New comment] %s (#%d)' => '',
|
||||
|
@ -418,188 +419,233 @@ return array(
|
|||
// '[%s][Task opened] %s (#%d)' => '',
|
||||
// '[%s][Due tasks]' => '',
|
||||
// '[Kanboard] Notification' => '',
|
||||
// 'I want to receive notifications only for those projects:' => '',
|
||||
// 'view the task on Kanboard' => '',
|
||||
// 'Public access' => '',
|
||||
// 'Category management' => '',
|
||||
// 'User management' => '',
|
||||
// 'Active tasks' => '',
|
||||
// 'Disable public access' => '',
|
||||
// 'Enable public access' => '',
|
||||
// 'Active projects' => '',
|
||||
// 'Inactive projects' => '',
|
||||
// 'Public access disabled' => '',
|
||||
// 'Do you really want to disable this project: "%s"?' => '',
|
||||
// 'Do you really want to duplicate this project: "%s"?' => '',
|
||||
// 'Do you really want to enable this project: "%s"?' => '',
|
||||
// 'Project activation' => '',
|
||||
// 'Move the task to another project' => '',
|
||||
// 'Move to another project' => '',
|
||||
// 'Do you really want to duplicate this task?' => '',
|
||||
// 'Duplicate a task' => '',
|
||||
// 'External accounts' => '',
|
||||
// 'Account type' => '',
|
||||
// 'Local' => '',
|
||||
// 'Remote' => '',
|
||||
// 'Enabled' => '',
|
||||
// 'Disabled' => '',
|
||||
// 'Google account linked' => '',
|
||||
// 'Github account linked' => '',
|
||||
// 'Username:' => '',
|
||||
// 'Name:' => '',
|
||||
// 'Email:' => '',
|
||||
// 'Default project:' => '',
|
||||
// 'Notifications:' => '',
|
||||
// 'Notifications' => '',
|
||||
// 'Group:' => '',
|
||||
// 'Regular user' => '',
|
||||
// 'Account type:' => '',
|
||||
// 'Edit profile' => '',
|
||||
// 'Change password' => '',
|
||||
// 'Password modification' => '',
|
||||
// 'External authentications' => '',
|
||||
// 'Google Account' => '',
|
||||
// 'Github Account' => '',
|
||||
// 'Never connected.' => '',
|
||||
// 'No account linked.' => '',
|
||||
// 'Account linked.' => '',
|
||||
// 'No external authentication enabled.' => '',
|
||||
// 'Password modified successfully.' => '',
|
||||
// 'Unable to change the password.' => '',
|
||||
// 'Change category for the task "%s"' => '',
|
||||
// 'Change category' => '',
|
||||
// '%s updated the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '',
|
||||
// '%s open the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '',
|
||||
// '%s moved the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to the position #%d in the column "%s"' => '',
|
||||
// '%s moved the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to the column "%s"' => '',
|
||||
// '%s created the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '',
|
||||
// '%s closed the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '',
|
||||
// '%s created a subtask for the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '',
|
||||
// '%s updated a subtask for the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '',
|
||||
// 'Assigned to %s with an estimate of %s/%sh' => '',
|
||||
// 'Not assigned, estimate of %sh' => '',
|
||||
// '%s updated a comment on the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '',
|
||||
// '%s commented the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '',
|
||||
// '%s\'s activity' => '',
|
||||
// 'No activity.' => '',
|
||||
// 'RSS feed' => '',
|
||||
// '%s updated a comment on the task #%d' => '',
|
||||
// '%s commented on the task #%d' => '',
|
||||
// '%s updated a subtask for the task #%d' => '',
|
||||
// '%s created a subtask for the task #%d' => '',
|
||||
// '%s updated the task #%d' => '',
|
||||
// '%s created the task #%d' => '',
|
||||
// '%s closed the task #%d' => '',
|
||||
// '%s open the task #%d' => '',
|
||||
// '%s moved the task #%d to the column "%s"' => '',
|
||||
// '%s moved the task #%d to the position %d in the column "%s"' => '',
|
||||
// 'Activity' => '',
|
||||
// 'Default values are "%s"' => '',
|
||||
// 'Default columns for new projects (Comma-separated)' => '',
|
||||
// 'Task assignee change' => '',
|
||||
// '%s change the assignee of the task #%d to %s' => '',
|
||||
// '%s change the assignee of the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to %s' => '',
|
||||
'I want to receive notifications only for those projects:' => 'Haluan vastaanottaa ilmoituksia ainoastaan näistä projekteista:',
|
||||
'view the task on Kanboard' => 'katso tehtävää Kanboardissa',
|
||||
'Public access' => 'Julkinen käyttöoikeus',
|
||||
'Category management' => 'Kategorioiden hallinta',
|
||||
'User management' => 'Käyttäjähallinta',
|
||||
'Active tasks' => 'Aktiiviset tehtävät',
|
||||
'Disable public access' => 'Poista käytöstä julkinen käyttöoikeus',
|
||||
'Enable public access' => 'Ota käyttöön ',
|
||||
'Active projects' => 'Aktiiviset projektit',
|
||||
'Inactive projects' => 'Passiiviset projektit',
|
||||
'Public access disabled' => 'Julkinen käyttöoikeus ei ole käytössä',
|
||||
'Do you really want to disable this project: "%s"?' => 'Haluatko varmasti tehdä projektista "%s" passiivisen?',
|
||||
'Do you really want to duplicate this project: "%s"?' => 'Haluatko varmasti kahdentaa projektin "%s"?',
|
||||
'Do you really want to enable this project: "%s"?' => 'Haluatko varmasti aktivoida projektinen "%s"',
|
||||
'Project activation' => 'Projektin aktivointi',
|
||||
'Move the task to another project' => 'Siirrä tehtävä toiseen projektiin',
|
||||
'Move to another project' => 'Siirrä toiseen projektiin',
|
||||
'Do you really want to duplicate this task?' => 'Haluatko varmasti kahdentaa tämän tehtävän?',
|
||||
'Duplicate a task' => 'Kahdenna tehtävä',
|
||||
'External accounts' => 'Muut tilit',
|
||||
'Account type' => 'Tilin tyyppi',
|
||||
'Local' => 'Paikallinen',
|
||||
'Remote' => 'Etä',
|
||||
'Enabled' => 'Käytössä',
|
||||
'Disabled' => 'Pois käytöstä',
|
||||
'Google account linked' => 'Google-tili liitetty',
|
||||
'Github account linked' => 'Github-tili liitetty',
|
||||
'Username:' => 'Käyttäjänimi:',
|
||||
'Name:' => 'Nimi:',
|
||||
'Email:' => 'Sähköpostiosoite:',
|
||||
'Default project:' => 'Oletusprojekti:',
|
||||
'Notifications:' => 'Ilmoitukset:',
|
||||
'Notifications' => 'Ilmoitukset',
|
||||
'Group:' => 'Ryhmä:',
|
||||
'Regular user' => 'Peruskäyttäjä',
|
||||
'Account type:' => 'Tilin tyyppi:',
|
||||
'Edit profile' => 'Muokkaa profiilia',
|
||||
'Change password' => 'Vaihda salasana',
|
||||
'Password modification' => 'Salasanan vaihto',
|
||||
'External authentications' => 'Muut tunnistautumistavat',
|
||||
'Google Account' => 'Google-tili',
|
||||
'Github Account' => 'Github-tili',
|
||||
'Never connected.' => 'Ei koskaan liitetty.',
|
||||
'No account linked.' => 'Tiliä ei ole liitetty.',
|
||||
'Account linked.' => 'Tili on liitetty.',
|
||||
'No external authentication enabled.' => 'Muita tunnistautumistapoja ei ole otettu käyttöön.',
|
||||
'Password modified successfully.' => 'Salasana vaihdettu onnistuneesti.',
|
||||
'Unable to change the password.' => 'Salasanan vaihto epäonnistui.',
|
||||
'Change category for the task "%s"' => 'Vaihda tehtävän "%s" kategoria',
|
||||
'Change category' => 'Vaihda kategoria',
|
||||
'%s updated the task %s' => '%s päivitti tehtävän %s',
|
||||
'%s opened the task %s' => '%s avasi tehtävän %s',
|
||||
'%s moved the task %s to the position #%d in the column "%s"' => '%s siirsi tehtävän %s %d. sarakkeessa "%s"',
|
||||
'%s moved the task %s to the column "%s"' => '%s siirsi tehtävän %s sarakkeeseen "%s"',
|
||||
'%s created the task %s' => '%s loi tehtävän %s',
|
||||
'%s closed the task %s' => '%s sulki tehtävän %s',
|
||||
'%s created a subtask for the task %s' => '%s loi alitehtävän tehtävälle %s',
|
||||
'%s updated a subtask for the task %s' => '%s päivitti tehtävän %s alitehtävää',
|
||||
'Assigned to %s with an estimate of %s/%sh' => 'Annettu henkilölle %s arviolla %s/%sh',
|
||||
'Not assigned, estimate of %sh' => 'Ei annettu kenellekään, arvio %sh',
|
||||
'%s updated a comment on the task %s' => '%s päivitti kommentia tehtävässä %s',
|
||||
'%s commented the task %s' => '%s kommentoi tehtävää %s',
|
||||
'%s\'s activity' => 'Henkilön %s toiminta',
|
||||
'No activity.' => 'Ei toimintaa.',
|
||||
'RSS feed' => 'RSS-syöte',
|
||||
'%s updated a comment on the task #%d' => '%s päivitti kommenttia tehtävässä #%d',
|
||||
'%s commented on the task #%d' => '%s kommentoi tehtävää #%d',
|
||||
'%s updated a subtask for the task #%d' => '%s päivitti tehtävän #%d alitehtävää',
|
||||
'%s created a subtask for the task #%d' => '%s loi alitehtävän tehtävälle #%d',
|
||||
'%s updated the task #%d' => '%s päivitti tehtävää #%d',
|
||||
'%s created the task #%d' => '%s loi tehtävän #%d',
|
||||
'%s closed the task #%d' => '%s sulki tehtävän #%d',
|
||||
'%s open the task #%d' => '%s avasi tehtävän #%d',
|
||||
'%s moved the task #%d to the column "%s"' => '%s siirsi tehtävän #%d sarakkeeseen "%s"',
|
||||
'%s moved the task #%d to the position %d in the column "%s"' => '%s siirsi tehtävän #%d %d. sarakkeessa %s',
|
||||
'Activity' => 'Toiminta',
|
||||
'Default values are "%s"' => 'Oletusarvot ovat "%s"',
|
||||
'Default columns for new projects (Comma-separated)' => 'Oletussarakkeet uusille projekteille',
|
||||
'Task assignee change' => 'Tehtävän saajan vaihto',
|
||||
'%s change the assignee of the task #%d to %s' => '%s vaihtoi tehtävän #%d saajaksi %s',
|
||||
'%s changed the assignee of the task %s to %s' => '%s vaihtoi tehtävän %s saajaksi %s',
|
||||
// '[%s][Column Change] %s (#%d)' => '',
|
||||
// '[%s][Position Change] %s (#%d)' => '',
|
||||
// '[%s][Assignee Change] %s (#%d)' => '',
|
||||
// 'New password for the user "%s"' => '',
|
||||
// 'Choose an event' => '',
|
||||
// 'Github commit received' => '',
|
||||
// 'Github issue opened' => '',
|
||||
// 'Github issue closed' => '',
|
||||
// 'Github issue reopened' => '',
|
||||
// 'Github issue assignee change' => '',
|
||||
// 'Github issue label change' => '',
|
||||
// 'Create a task from an external provider' => '',
|
||||
// 'Change the assignee based on an external username' => '',
|
||||
// 'Change the category based on an external label' => '',
|
||||
// 'Reference' => '',
|
||||
// 'Reference: %s' => '',
|
||||
// 'Label' => '',
|
||||
// 'Database' => '',
|
||||
// 'About' => '',
|
||||
// 'Database driver:' => '',
|
||||
// 'Board settings' => '',
|
||||
// 'URL and token' => '',
|
||||
// 'Webhook settings' => '',
|
||||
// 'URL for task creation:' => '',
|
||||
// 'Reset token' => '',
|
||||
// 'API endpoint:' => '',
|
||||
// 'Refresh interval for private board' => '',
|
||||
// 'Refresh interval for public board' => '',
|
||||
// 'Task highlight period' => '',
|
||||
// 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => '',
|
||||
// 'Frequency in second (60 seconds by default)' => '',
|
||||
// 'Frequency in second (0 to disable this feature, 10 seconds by default)' => '',
|
||||
// 'Application URL' => '',
|
||||
// 'Example: http://example.kanboard.net/ (used by email notifications)' => '',
|
||||
// 'Token regenerated.' => '',
|
||||
// 'Date format' => '',
|
||||
// 'ISO format is always accepted, example: "%s" and "%s"' => '',
|
||||
// 'New private project' => '',
|
||||
// 'This project is private' => '',
|
||||
// 'Type here to create a new sub-task' => '',
|
||||
// 'Add' => '',
|
||||
// 'Estimated time: %s hours' => '',
|
||||
// 'Time spent: %s hours' => '',
|
||||
// 'Started on %B %e, %Y' => '',
|
||||
// 'Start date' => '',
|
||||
// 'Time estimated' => '',
|
||||
// 'There is nothing assigned to you.' => '',
|
||||
// 'My tasks' => '',
|
||||
// 'Activity stream' => '',
|
||||
// 'Dashboard' => '',
|
||||
// 'Confirmation' => '',
|
||||
// 'Allow everybody to access to this project' => '',
|
||||
// 'Everybody have access to this project.' => '',
|
||||
'New password for the user "%s"' => 'Uusi salasana käyttäjälle "%s"',
|
||||
'Choose an event' => 'Valitse toiminta',
|
||||
'Github commit received' => 'Github-kommitti vastaanotettu',
|
||||
'Github issue opened' => 'Github-issue avattu',
|
||||
'Github issue closed' => 'Github-issue suljettu',
|
||||
'Github issue reopened' => 'Github-issue uudelleenavattu',
|
||||
'Github issue assignee change' => 'Github-issuen saajan vaihto',
|
||||
'Github issue label change' => 'Github-issuen labelin vaihto',
|
||||
'Create a task from an external provider' => 'Luo tehtävä ulkoiselta tarjoajalta',
|
||||
'Change the assignee based on an external username' => 'Vaihda tehtävän saajaa perustuen ulkoiseen käyttäjänimeen',
|
||||
'Change the category based on an external label' => 'Vaihda kategoriaa perustuen ulkoiseen labeliin',
|
||||
'Reference' => 'Viite',
|
||||
'Reference: %s' => 'Viite: %s',
|
||||
'Label' => 'Label',
|
||||
'Database' => 'Tietokanta',
|
||||
'About' => 'Tietoja',
|
||||
'Database driver:' => 'Tietokantaohjelmisto:',
|
||||
'Board settings' => 'Taulun asetukset',
|
||||
'URL and token' => 'URL ja token',
|
||||
'Webhook settings' => 'Webhookin asetukset',
|
||||
'URL for task creation:' => 'URL tehtävän luomiseksi:',
|
||||
'Reset token' => 'Vaihda token',
|
||||
'API endpoint:' => 'API päätepiste:',
|
||||
'Refresh interval for private board' => 'Päivitystiheys yksityisille tauluille',
|
||||
'Refresh interval for public board' => 'Päivitystiheys julkisille tauluille',
|
||||
'Task highlight period' => 'Tehtävän korostusaika',
|
||||
'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => 'Aika (sekunteina) kuinka kauan tehtävä voidaan katsoa äskettäin muokatuksi (0 poistaa toiminnon käytöstä, oletuksena 2 päivää)',
|
||||
'Frequency in second (60 seconds by default)' => 'Päivitystiheys sekunteina (60 sekuntia oletuksena)',
|
||||
'Frequency in second (0 to disable this feature, 10 seconds by default)' => 'Päivitystiheys sekunteina (0 poistaa toiminnon käytöstä, oletuksena 10 sekuntia)',
|
||||
'Application URL' => 'Sovelluksen URL',
|
||||
'Example: http://example.kanboard.net/ (used by email notifications)' => 'Esimerkiksi: http://example.kanboard.net/ (käytetään sähköposti-ilmoituksissa)',
|
||||
'Token regenerated.' => 'Token uudelleenluotu.',
|
||||
'Date format' => 'Päiväyksen muoto',
|
||||
'ISO format is always accepted, example: "%s" and "%s"' => 'ISO-muoto on aina hyväksytty, esimerkiksi %s ja %s',
|
||||
'New private project' => 'Uusi yksityinen projekti',
|
||||
'This project is private' => 'Tämä projekti on yksityinen',
|
||||
'Type here to create a new sub-task' => 'Kirjoita tähän luodaksesi uuden alitehtävän',
|
||||
'Add' => 'Lisää',
|
||||
'Estimated time: %s hours' => 'Arvioitu aika: %s tuntia',
|
||||
'Time spent: %s hours' => 'Aikaa kulunut: %s tuntia',
|
||||
'Started on %B %e, %Y' => 'Aloitettu %B %e, %Y',
|
||||
'Start date' => 'Aloituspäivä',
|
||||
'Time estimated' => 'Arvioitu aika',
|
||||
'There is nothing assigned to you.' => 'Ei tehtäviä, joihin sinut olisi merkitty tekijäksi.',
|
||||
'My tasks' => 'Minun tehtävät',
|
||||
'Activity stream' => 'Toiminta',
|
||||
'Dashboard' => 'Työpöytä',
|
||||
'Confirmation' => 'Vahvistus',
|
||||
'Allow everybody to access to this project' => 'Anna kaikille käyttöoikeus tähän projektiin',
|
||||
'Everybody have access to this project.' => 'Kaikilla on käyttöoikeus projektiin.',
|
||||
// 'Webhooks' => '',
|
||||
// 'API' => '',
|
||||
// 'Integration' => '',
|
||||
// 'Github webhook' => '',
|
||||
// 'Help on Github webhook' => '',
|
||||
'Integration' => 'Integraatio',
|
||||
// 'Github webhooks' => '',
|
||||
// 'Help on Github webhooks' => '',
|
||||
// 'Create a comment from an external provider' => '',
|
||||
// 'Github issue comment created' => '',
|
||||
// 'Configure' => '',
|
||||
// 'Project management' => '',
|
||||
// 'My projects' => '',
|
||||
// 'Columns' => '',
|
||||
// 'Task' => '',
|
||||
// 'Your are not member of any project.' => '',
|
||||
// 'Percentage' => '',
|
||||
// 'Number of tasks' => '',
|
||||
// 'Task distribution' => '',
|
||||
// 'Reportings' => '',
|
||||
'Configure' => 'Konfiguroi',
|
||||
'Project management' => 'Projektin hallinta',
|
||||
'My projects' => 'Minun projektini',
|
||||
'Columns' => 'Sarakkeet',
|
||||
'Task' => 'Tehtävät',
|
||||
'Your are not member of any project.' => 'Et ole minkään projektin jäsen.',
|
||||
'Percentage' => 'Prosentti',
|
||||
'Number of tasks' => 'Tehtävien määrä',
|
||||
'Task distribution' => 'Tehtävien jakauma',
|
||||
'Reportings' => 'Raportoinnit',
|
||||
// 'Task repartition for "%s"' => '',
|
||||
// 'Analytics' => '',
|
||||
// 'Subtask' => '',
|
||||
// 'My subtasks' => '',
|
||||
'Analytics' => 'Analytiikka',
|
||||
'Subtask' => 'Alitehtävä',
|
||||
'My subtasks' => 'Minun alitehtäväni',
|
||||
// 'User repartition' => '',
|
||||
// 'User repartition for "%s"' => '',
|
||||
// 'Clone this project' => '',
|
||||
// 'Column removed successfully.' => '',
|
||||
// 'Edit Project' => '',
|
||||
// 'Github Issue' => '',
|
||||
// 'Not enough data to show the graph.' => '',
|
||||
// 'Previous' => '',
|
||||
// 'The id must be an integer' => '',
|
||||
// 'The project id must be an integer' => '',
|
||||
// 'The status must be an integer' => '',
|
||||
// 'The subtask id is required' => '',
|
||||
// 'The subtask id must be an integer' => '',
|
||||
// 'The task id is required' => '',
|
||||
// 'The task id must be an integer' => '',
|
||||
// 'The user id must be an integer' => '',
|
||||
// 'This value is required' => '',
|
||||
// 'This value must be numeric' => '',
|
||||
// 'Unable to create this task.' => '',
|
||||
// 'Cumulative flow diagram' => '',
|
||||
// 'Cumulative flow diagram for "%s"' => '',
|
||||
// 'Daily project summary' => '',
|
||||
// 'Daily project summary export' => '',
|
||||
// 'Daily project summary export for "%s"' => '',
|
||||
// 'Exports' => '',
|
||||
// 'This export contains the number of tasks per column grouped per day.' => '',
|
||||
// 'Nothing to preview...' => '',
|
||||
// 'Preview' => '',
|
||||
// 'Write' => '',
|
||||
'Clone this project' => 'Kahdenna projekti',
|
||||
'Column removed successfully.' => 'Sarake poistettu onnstuneesti.',
|
||||
'Edit Project' => 'Muokkaa projektia',
|
||||
'Github Issue' => 'Github-issue',
|
||||
'Not enough data to show the graph.' => 'Ei riittävästi dataa graafin näyttämiseksi.',
|
||||
'Previous' => 'Edellinen',
|
||||
'The id must be an integer' => 'ID:n on oltava kokonaisluku',
|
||||
'The project id must be an integer' => 'Projektin ID:n on oltava kokonaisluku',
|
||||
'The status must be an integer' => 'Tilan on oltava kokonaisluku',
|
||||
'The subtask id is required' => 'Alitehtävän ID vaaditaan',
|
||||
'The subtask id must be an integer' => 'Alitehtävän ID:ntulee olla kokonaisluku',
|
||||
'The task id is required' => 'Tehtävän ID vaaditaan',
|
||||
'The task id must be an integer' => 'Tehtävän ID on oltava kokonaisluku',
|
||||
'The user id must be an integer' => 'Käyttäjän ID on oltava kokonaisluku',
|
||||
'This value is required' => 'Tämä arvo on pakollinen',
|
||||
'This value must be numeric' => 'Tämän arvon tulee olla numeerinen',
|
||||
'Unable to create this task.' => 'Tehtävän luonti epäonnistui',
|
||||
'Cumulative flow diagram' => 'Kumulatiivinen vuokaavio',
|
||||
'Cumulative flow diagram for "%s"' => 'Kumulatiivinen vuokaavio kohteelle "%s"',
|
||||
'Daily project summary' => 'Päivittäinen yhteenveto',
|
||||
'Daily project summary export' => 'Päivittäisen yhteenvedon vienti',
|
||||
'Daily project summary export for "%s"' => 'Päivittäisen yhteenvedon vienti kohteeseen "%s"',
|
||||
'Exports' => 'Viennit',
|
||||
'This export contains the number of tasks per column grouped per day.' => 'Tämä tiedosto sisältää tehtäviä sarakkeisiin päiväkohtaisesti ryhmilteltyinä',
|
||||
'Nothing to preview...' => 'Ei esikatselua...',
|
||||
'Preview' => 'Ei esikatselua',
|
||||
'Write' => 'Kirjoita',
|
||||
'Active swimlanes' => 'Aktiiviset kaistat',
|
||||
'Add a new swimlane' => 'Lisää uusi kaista',
|
||||
'Change default swimlane' => 'Vaihda oletuskaistaa',
|
||||
'Default swimlane' => 'Oletuskaista',
|
||||
'Do you really want to remove this swimlane: "%s"?' => 'Haluatko varmasti poistaa tämän kaistan: "%s"?',
|
||||
'Inactive swimlanes' => 'Passiiviset kaistat',
|
||||
// 'Set project manager' => '',
|
||||
// 'Set project member' => '',
|
||||
'Remove a swimlane' => 'Poista kaista',
|
||||
'Rename' => 'Uudelleennimeä',
|
||||
'Show default swimlane' => 'Näytä oletuskaista',
|
||||
'Swimlane modification for the project "%s"' => 'Kaistamuutos projektille "%s"',
|
||||
'Swimlane not found.' => 'Kaistaa ei löydy',
|
||||
'Swimlane removed successfully.' => 'Kaista poistettu onnistuneesti.',
|
||||
'Swimlanes' => 'Kaistat',
|
||||
'Swimlane updated successfully.' => 'Kaista päivitetty onnistuneesti.',
|
||||
'The default swimlane have been updated successfully.' => 'Oletuskaista päivitetty onnistuneesti.',
|
||||
'Unable to create your swimlane.' => 'Kaistan luonti epäonnistui.',
|
||||
'Unable to remove this swimlane.' => 'Kaistan poisto epäonnistui.',
|
||||
'Unable to update this swimlane.' => 'Kaistan päivittäminen epäonnistui.',
|
||||
'Your swimlane have been created successfully.' => 'Kaista luotu onnistuneesti.',
|
||||
'Example: "Bug, Feature Request, Improvement"' => 'Esimerkiksi: "Bugit, Ominaisuuspyynnöt, Parannukset"',
|
||||
'Default categories for new projects (Comma-separated)' => 'Oletuskategoriat uusille projekteille (pilkuin eroteltu)',
|
||||
// 'Gitlab commit received' => '',
|
||||
// 'Gitlab issue opened' => '',
|
||||
// 'Gitlab issue closed' => '',
|
||||
// 'Gitlab webhooks' => '',
|
||||
// 'Help on Gitlab webhooks' => '',
|
||||
// 'Integrations' => '',
|
||||
// 'Integration with third-party services' => '',
|
||||
// 'Role for this project' => '',
|
||||
// 'Project manager' => '',
|
||||
// 'Project member' => '',
|
||||
// 'A project manager can change the settings of the project and have more privileges than a standard user.' => '',
|
||||
// 'Gitlab Issue' => '',
|
||||
// 'Subtask Id' => '',
|
||||
// 'Subtasks' => '',
|
||||
// 'Subtasks Export' => '',
|
||||
// 'Subtasks exportation for "%s"' => '',
|
||||
// 'Task Title' => '',
|
||||
// 'Untitled' => '',
|
||||
// 'Application default' => '',
|
||||
// 'Language:' => '',
|
||||
// 'Timezone:' => '',
|
||||
// 'Next' => '',
|
||||
);
|
||||
|
|
|
@ -182,11 +182,11 @@ return array(
|
|||
'Change assignee' => 'Changer la personne assignée',
|
||||
'Change assignee for the task "%s"' => 'Changer la personne assignée pour la tâche « %s »',
|
||||
'Timezone' => 'Fuseau horaire',
|
||||
'Sorry, I didn\'t found this information in my database!' => 'Désolé, je n\'ai pas trouvé cette information dans ma base de données !',
|
||||
'Sorry, I didn\'t find this information in my database!' => 'Désolé, je n\'ai pas trouvé cette information dans ma base de données !',
|
||||
'Page not found' => 'Page introuvable',
|
||||
'Complexity' => 'Complexité',
|
||||
'limit' => 'limite',
|
||||
'Task limit' => 'Nombre maximum de tâches',
|
||||
'Task limit' => 'Tâches Max.',
|
||||
'Task count' => 'Nombre de tâches',
|
||||
'This value must be greater than %d' => 'Cette valeur doit être plus grande que %d',
|
||||
'Edit project access list' => 'Modifier l\'accès au projet',
|
||||
|
@ -194,7 +194,7 @@ return array(
|
|||
'Allow this user' => 'Autoriser cet utilisateur',
|
||||
'Only those users have access to this project:' => 'Seulement ces utilisateurs ont accès à ce projet :',
|
||||
'Don\'t forget that administrators have access to everything.' => 'N\'oubliez pas que les administrateurs ont accès à tout.',
|
||||
'revoke' => 'révoquer',
|
||||
'Revoke' => 'Révoquer',
|
||||
'List of authorized users' => 'Liste des utilisateurs autorisés',
|
||||
'User' => 'Utilisateur',
|
||||
'Nobody have access to this project.' => 'Personne n\'est autorisé à accéder au projet.',
|
||||
|
@ -213,6 +213,7 @@ return array(
|
|||
'Invalid date' => 'Date invalide',
|
||||
'Must be done before %B %e, %Y' => 'Doit être fait avant le %d/%m/%Y',
|
||||
'%B %e, %Y' => '%d %B %Y',
|
||||
'%b %e, %Y' => '%d/%m/%Y',
|
||||
'Automatic actions' => 'Actions automatisées',
|
||||
'Your automatic action have been created successfully.' => 'Votre action automatisée a été ajouté avec succès.',
|
||||
'Unable to create your automatic action.' => 'Impossible de créer votre action automatisée.',
|
||||
|
@ -468,18 +469,18 @@ return array(
|
|||
'Unable to change the password.' => 'Impossible de changer le mot de passe.',
|
||||
'Change category for the task "%s"' => 'Changer la catégorie pour la tâche « %s »',
|
||||
'Change category' => 'Changer de catégorie',
|
||||
'%s updated the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s a mis à jour la tâche <a href="?controller=task&action=show&task_id=%d">n°%d</a>',
|
||||
'%s open the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s a ouvert la tâche <a href="?controller=task&action=show&task_id=%d">n°%d</a>',
|
||||
'%s moved the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to the position #%d in the column "%s"' => '%s a déplacé la tâche <a href="?controller=task&action=show&task_id=%d">n°%d</a> à la position n°%d dans la colonne « %s »',
|
||||
'%s moved the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to the column "%s"' => '%s a déplacé la tâche <a href="?controller=task&action=show&task_id=%d">n°%d</a> dans la colonne « %s »',
|
||||
'%s created the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s a créé la tâche <a href="?controller=task&action=show&task_id=%d">n°%d</a>',
|
||||
'%s closed the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s a fermé la tâche <a href="?controller=task&action=show&task_id=%d">n°%d</a>',
|
||||
'%s created a subtask for the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s a créé une sous-tâche pour la tâche <a href="?controller=task&action=show&task_id=%d">n°%d</a>',
|
||||
'%s updated a subtask for the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s a mis à jour une sous-tâche appartenant à la tâche <a href="?controller=task&action=show&task_id=%d">n°%d</a>',
|
||||
'%s updated the task %s' => '%s a mis à jour la tâche %s',
|
||||
'%s opened the task %s' => '%s a ouvert la tâche %s',
|
||||
'%s moved the task %s to the position #%d in the column "%s"' => '%s a déplacé la tâche %s à la position n°%d dans la colonne « %s »',
|
||||
'%s moved the task %s to the column "%s"' => '%s a déplacé la tâche %s dans la colonne « %s »',
|
||||
'%s created the task %s' => '%s a créé la tâche %s',
|
||||
'%s closed the task %s' => '%s a fermé la tâche %s',
|
||||
'%s created a subtask for the task %s' => '%s a créé une sous-tâche pour la tâche %s',
|
||||
'%s updated a subtask for the task %s' => '%s a mis à jour une sous-tâche appartenant à la tâche %s',
|
||||
'Assigned to %s with an estimate of %s/%sh' => 'Assigné à %s avec un estimé de %s/%sh',
|
||||
'Not assigned, estimate of %sh' => 'Personne assigné, estimé de %sh',
|
||||
'%s updated a comment on the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s a mis à jour un commentaire appartenant à la tâche <a href="?controller=task&action=show&task_id=%d">n°%d</a>',
|
||||
'%s commented the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s a ajouté un commentaire sur la tâche <a href="?controller=task&action=show&task_id=%d">n°%d</a>',
|
||||
'%s updated a comment on the task %s' => '%s a mis à jour un commentaire appartenant à la tâche %s',
|
||||
'%s commented the task %s' => '%s a ajouté un commentaire sur la tâche %s',
|
||||
'%s\'s activity' => 'Activité du projet %s',
|
||||
'No activity.' => 'Aucune activité.',
|
||||
'RSS feed' => 'Flux RSS',
|
||||
|
@ -497,11 +498,11 @@ return array(
|
|||
'Default values are "%s"' => 'Les valeurs par défaut sont « %s »',
|
||||
'Default columns for new projects (Comma-separated)' => 'Colonnes par défaut pour les nouveaux projets (séparé par des virgules)',
|
||||
'Task assignee change' => 'Modification de la personne assignée sur une tâche',
|
||||
'%s change the assignee of the task #%d to %s' => '%s a changé la personne assignée sur la tâche #%d pour %s',
|
||||
'%s change the assignee of the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to %s' => '%s a changé la personne assignée sur la tâche <a href="?controller=task&action=show&task_id=%d">n°%d</a> pour %s',
|
||||
'[%s][Column Change] %s (#%d)' => '[%s][Changement de colonne] %s (#%d)',
|
||||
'[%s][Position Change] %s (#%d)' => '[%s][Changement de position] %s (#%d)',
|
||||
'[%s][Assignee Change] %s (#%d)' => '[%s][Changement d\'assigné] %s (#%d)',
|
||||
'%s change the assignee of the task #%d to %s' => '%s a changé la personne assignée sur la tâche n˚%d pour %s',
|
||||
'%s changed the assignee of the task %s to %s' => '%s a changé la personne assignée sur la tâche %s pour %s',
|
||||
'[%s][Column Change] %s (#%d)' => '[%s][Changement de colonne] %s (n˚%d)',
|
||||
'[%s][Position Change] %s (#%d)' => '[%s][Changement de position] %s (n˚%d)',
|
||||
'[%s][Assignee Change] %s (#%d)' => '[%s][Changement d\'assigné] %s (n˚%d)',
|
||||
'New password for the user "%s"' => 'Nouveau mot de passe pour l\'utilisateur « %s »',
|
||||
'Choose an event' => 'Choisir un événement',
|
||||
'Github commit received' => '« Commit » reçu via Github',
|
||||
|
@ -555,8 +556,8 @@ return array(
|
|||
'Webhooks' => 'Webhooks',
|
||||
'API' => 'API',
|
||||
'Integration' => 'Intégration',
|
||||
'Github webhook' => 'Webhook Github',
|
||||
'Help on Github webhook' => 'Aide sur les webhooks Github',
|
||||
'Github webhooks' => 'Webhook Github',
|
||||
'Help on Github webhooks' => 'Aide sur les webhooks Github',
|
||||
'Create a comment from an external provider' => 'Créer un commentaire depuis un fournisseur externe',
|
||||
'Github issue comment created' => 'Commentaire créé sur un ticket Github',
|
||||
'Configure' => 'Configurer',
|
||||
|
@ -602,4 +603,50 @@ return array(
|
|||
'Nothing to preview...' => 'Rien à prévisualiser...',
|
||||
'Preview' => 'Prévisualiser',
|
||||
'Write' => 'Écrire',
|
||||
'Active swimlanes' => 'Swimlanes actives',
|
||||
'Add a new swimlane' => 'Ajouter une nouvelle swimlane',
|
||||
'Change default swimlane' => 'Modifier la swimlane par défaut',
|
||||
'Default swimlane' => 'Swimlane par défaut',
|
||||
'Do you really want to remove this swimlane: "%s"?' => 'Voulez-vous vraiment supprimer cette swimlane : « %s » ?',
|
||||
'Inactive swimlanes' => 'Swimlanes inactives',
|
||||
'Set project manager' => 'Mettre chef de projet',
|
||||
'Set project member' => 'Mettre membre du projet',
|
||||
'Remove a swimlane' => 'Supprimer une swimlane',
|
||||
'Rename' => 'Renommer',
|
||||
'Show default swimlane' => 'Afficher la swimlane par défaut',
|
||||
'Swimlane modification for the project "%s"' => 'Modification d\'une swimlane pour le projet « %s »',
|
||||
'Swimlane not found.' => 'Cette swimlane est introuvable.',
|
||||
'Swimlane removed successfully.' => 'Swimlane supprimée avec succès.',
|
||||
'Swimlanes' => 'Swimlanes',
|
||||
'Swimlane updated successfully.' => 'Swimlane mise à jour avec succès.',
|
||||
'The default swimlane have been updated successfully.' => 'La swimlane par défaut a été mise à jour avec succès.',
|
||||
'Unable to create your swimlane.' => 'Impossible de créer votre swimlane.',
|
||||
'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)',
|
||||
'Gitlab commit received' => '« Commit » reçu via Gitlab',
|
||||
'Gitlab issue opened' => 'Ouverture d\'un ticket sur Gitlab',
|
||||
'Gitlab issue closed' => 'Fermeture d\'un ticket sur Gitlab',
|
||||
'Gitlab webhooks' => 'Webhook Gitlab',
|
||||
'Help on Gitlab webhooks' => 'Aide sur les webhooks Gitlab',
|
||||
'Integrations' => 'Intégrations',
|
||||
'Integration with third-party services' => 'Intégration avec des services externes',
|
||||
'Role for this project' => 'Rôle pour ce projet',
|
||||
'Project manager' => 'Chef de projet',
|
||||
'Project member' => 'Membre du projet',
|
||||
'A project manager can change the settings of the project and have more privileges than a standard user.' => 'Un chef de projet peut changer les paramètres du projet et possède plus de privilèges qu\'un utilisateur standard.',
|
||||
'Gitlab Issue' => 'Ticket Gitlab',
|
||||
'Subtask Id' => 'Identifiant de la sous-tâche',
|
||||
'Subtasks' => 'Sous-tâches',
|
||||
'Subtasks Export' => 'Exportation des sous-tâches',
|
||||
'Subtasks exportation for "%s"' => 'Exportation des sous-tâches pour le projet « %s »',
|
||||
'Task Title' => 'Titre de la tâche',
|
||||
'Untitled' => 'Sans nom',
|
||||
'Application default' => 'Valeur par défaut de l\'application',
|
||||
'Language:' => 'Langue :',
|
||||
'Timezone:' => 'Fuseau horaire :',
|
||||
'Next' => 'Suivant',
|
||||
'#%d' => 'n˚%d',
|
||||
);
|
||||
|
|
651
sources/app/Locale/hu_HU/translations.php
Normal file
651
sources/app/Locale/hu_HU/translations.php
Normal file
|
@ -0,0 +1,651 @@
|
|||
<?php
|
||||
|
||||
return array(
|
||||
'None' => 'Semelyik',
|
||||
'edit' => 'szerkesztés',
|
||||
'Edit' => 'Szerkesztés',
|
||||
'remove' => 'eltávolít',
|
||||
'Remove' => 'Eltávolít',
|
||||
'Update' => 'Frissítés',
|
||||
'Yes' => 'Igen',
|
||||
'No' => 'Nincs',
|
||||
'cancel' => 'mégsem',
|
||||
'or' => 'vagy',
|
||||
'Yellow' => 'sárga',
|
||||
'Blue' => 'kék',
|
||||
'Green' => 'zöld',
|
||||
'Purple' => 'ibolya',
|
||||
'Red' => 'piros',
|
||||
'Orange' => 'narancs',
|
||||
'Grey' => 'szürke',
|
||||
'Save' => 'Mentés',
|
||||
'Login' => 'Bejelentkezés',
|
||||
'Official website:' => 'Hivatalos honlap:',
|
||||
'Unassigned' => 'Nincs felelős',
|
||||
'View this task' => 'Feladat megtekintése',
|
||||
'Remove user' => 'Felhasználó törlése',
|
||||
'Do you really want to remove this user: "%s"?' => 'Tényleg törli ezt a felhasználót: "%s"?',
|
||||
'New user' => 'új felhasználó',
|
||||
'All users' => 'Minden felhasználó',
|
||||
'Username' => 'Felhasználónév',
|
||||
'Password' => 'Jelszó',
|
||||
'Default project' => 'Alapértelmezett projekt',
|
||||
'Administrator' => 'Rendszergazda',
|
||||
'Sign in' => 'Jelentkezzen be',
|
||||
'Users' => 'Felhasználók',
|
||||
'No user' => 'Nincs felhasználó',
|
||||
'Forbidden' => 'tiltott',
|
||||
'Access Forbidden' => 'Hozzáférés megtagadva',
|
||||
'Only administrators can access to this page.' => 'Csak a rendszergazdák férhetnek hozzá az oldalhoz.',
|
||||
'Edit user' => 'Felhasználó módosítása',
|
||||
'Logout' => 'Kilépés',
|
||||
'Bad username or password' => 'Rossz felhasználónév vagy jelszó',
|
||||
'users' => 'felhasználók',
|
||||
'projects' => 'projektek',
|
||||
'Edit project' => 'Projekt szerkesztése',
|
||||
'Name' => 'Név',
|
||||
'Activated' => 'Aktiválva',
|
||||
'Projects' => 'Projektek',
|
||||
'No project' => 'Nincs projekt',
|
||||
'Project' => 'Projekt',
|
||||
'Status' => 'Állapot',
|
||||
'Tasks' => 'Feladat',
|
||||
'Board' => 'Tábla',
|
||||
'Actions' => 'Műveletek',
|
||||
'Inactive' => 'Inaktív',
|
||||
'Active' => 'Aktív',
|
||||
'Column %d' => 'Oszlop %d',
|
||||
'Add this column' => 'Oszlop hozzáadása',
|
||||
'%d tasks on the board' => 'A táblán %d feladat',
|
||||
'%d tasks in total' => 'Összesen %d feladat',
|
||||
'Unable to update this board.' => 'Nem lehet frissíteni a táblát.',
|
||||
'Edit board' => 'Tábla szerkesztése',
|
||||
'Disable' => 'Letilt',
|
||||
'Enable' => 'Engedélyez',
|
||||
'New project' => 'Új projekt',
|
||||
'Do you really want to remove this project: "%s"?' => 'Valóban törölni akarja ezt a projektet: "%s"?',
|
||||
'Remove project' => 'Projekt törlése',
|
||||
'Boards' => 'Táblák',
|
||||
'Edit the board for "%s"' => 'Tábla szerkesztése "%s"',
|
||||
'All projects' => 'Minden projekt',
|
||||
'Change columns' => 'Oszlop módosítása',
|
||||
'Add a new column' => 'Új oszlop',
|
||||
'Title' => 'Cím',
|
||||
'Add Column' => 'Oszlopot hozzáad',
|
||||
'Project "%s"' => 'Projekt "%s"',
|
||||
'Nobody assigned' => 'Nincs felelős',
|
||||
'Assigned to %s' => 'Felelős: %s',
|
||||
'Remove a column' => 'Oszlop törlése',
|
||||
'Remove a column from a board' => 'Oszlop törlése a tábláról',
|
||||
'Unable to remove this column.' => 'Az oszlop törlése nem lehetséges.',
|
||||
'Do you really want to remove this column: "%s"?' => 'Valóban törölni akarja ezt az oszlopot: "%s"?',
|
||||
'This action will REMOVE ALL TASKS associated to this column!' => 'Az oszlophoz rendelt ÖSSZES FELADAT TÖRLŐDNI FOG!',
|
||||
'Settings' => 'Beállítások',
|
||||
'Application settings' => 'Alkalmazás beállítások',
|
||||
'Language' => 'Nyelv',
|
||||
'Webhook token:' => 'Webhook token:',
|
||||
'API token:' => 'API token:',
|
||||
'More information' => 'További információ',
|
||||
'Database size:' => 'Adatbázis méret:',
|
||||
'Download the database' => 'Adatbázis letöltése',
|
||||
'Optimize the database' => 'Adatbázis optimalizálása',
|
||||
'(VACUUM command)' => '(VACUUM parancs)',
|
||||
'(Gzip compressed Sqlite file)' => '(Gzip tömörített SQLite fájl)',
|
||||
'User settings' => 'Felhasználói beállítások',
|
||||
'My default project:' => 'Alapértelmezett project:',
|
||||
'Close a task' => 'Feladat lezárása',
|
||||
'Do you really want to close this task: "%s"?' => 'Tényleg le akarja zárni ezt a feladatot: "%s"?',
|
||||
'Edit a task' => 'Feladat módosítása',
|
||||
'Column' => 'Oszlop',
|
||||
'Color' => 'Szín',
|
||||
'Assignee' => 'Felelős',
|
||||
'Create another task' => 'Új feladat létrehozása',
|
||||
'New task' => 'új feladat',
|
||||
'Open a task' => 'Feladat megnyitása',
|
||||
'Do you really want to open this task: "%s"?' => 'Tényleg meg akarja nyitni ezt a feladatot: "%s"?',
|
||||
'Back to the board' => 'Vissza a táblához',
|
||||
'Created on %B %e, %Y at %k:%M %p' => 'Létrehozva: %Y.%m.%d %k:%M %p',
|
||||
'There is nobody assigned' => 'Nincs felelős',
|
||||
'Column on the board:' => 'Tábla oszlopa:',
|
||||
'Status is open' => 'Állapot nyitva',
|
||||
'Status is closed' => 'Állapot zárva',
|
||||
'Close this task' => 'Feladat bezárása',
|
||||
'Open this task' => 'Feladat megnyitása',
|
||||
'There is no description.' => 'Nincs elérhető leírás.',
|
||||
'Add a new task' => 'Új feladat hozzáadása',
|
||||
'The username is required' => 'Felhasználói név szükséges',
|
||||
'The maximum length is %d characters' => 'A maximális hossz %d karakter',
|
||||
'The minimum length is %d characters' => 'A minimális hossza %d karakter',
|
||||
'The password is required' => 'Jelszó szükséges',
|
||||
'This value must be an integer' => 'Ez az érték csak egész szám lehet',
|
||||
'The username must be unique' => 'A felhasználó nevének egyedinek kell lennie',
|
||||
'The username must be alphanumeric' => 'A felhasználói név csak alfanumerikus lehet (betűk és számok)',
|
||||
'The user id is required' => 'A felhasználói azonosítót meg kell adni',
|
||||
'Passwords don\'t match' => 'A jelszavak nem egyeznek',
|
||||
'The confirmation is required' => 'Megerősítés szükséges',
|
||||
'The column is required' => 'Az oszlopot meg kell adni',
|
||||
'The project is required' => 'A projektet meg kell adni',
|
||||
'The color is required' => 'A színt meg kell adni',
|
||||
'The id is required' => 'Az ID-t (azonosítót) meg kell adni',
|
||||
'The project id is required' => 'A projekt ID-t (azonosítót) meg kell adni',
|
||||
'The project name is required' => 'A projekt nevét meg kell adni',
|
||||
'This project must be unique' => 'A projekt nevének egyedinek kell lennie',
|
||||
'The title is required' => 'A címet meg kell adni',
|
||||
'The language is required' => 'A nyelvet meg kell adni',
|
||||
'There is no active project, the first step is to create a new project.' => 'Nincs aktív projekt. Először létre kell hozni egy projektet.',
|
||||
'Settings saved successfully.' => 'A beállítások sikeresen mentve.',
|
||||
'Unable to save your settings.' => 'Beállítások mentése nem sikerült.',
|
||||
'Database optimization done.' => 'Adatbázis optimalizálás kész.',
|
||||
'Your project have been created successfully.' => 'A projekt sikeresen elkészült.',
|
||||
'Unable to create your project.' => 'Projekt létrehozása nem sikerült.',
|
||||
'Project updated successfully.' => 'Projekt sikeres frissítve.',
|
||||
'Unable to update this project.' => 'Projekt frissítése nem sikerült.',
|
||||
'Unable to remove this project.' => 'Projekt törlése nem sikerült.',
|
||||
'Project removed successfully.' => 'Projekt sikeresen törölve.',
|
||||
'Project activated successfully.' => 'Projekt sikeresen aktiválta.',
|
||||
'Unable to activate this project.' => 'Projekt aktiválása nem sikerült.',
|
||||
'Project disabled successfully.' => 'Projekt sikeresen letiltva.',
|
||||
'Unable to disable this project.' => 'Projekt letiltása nem sikerült.',
|
||||
'Unable to open this task.' => 'A feladat megnyitása nem sikerült.',
|
||||
'Task opened successfully.' => 'Feladat sikeresen megnyitva .',
|
||||
'Unable to close this task.' => 'A feladat lezárása nem sikerült.',
|
||||
'Task closed successfully.' => 'Feladat sikeresen lezárva.',
|
||||
'Unable to update your task.' => 'A feladat frissítése nem sikerült.',
|
||||
'Task updated successfully.' => 'Feladat sikeresen frissítve.',
|
||||
'Unable to create your task.' => 'A feladat létrehozása nem sikerült.',
|
||||
'Task created successfully.' => 'Feladat sikeresen létrehozva.',
|
||||
'User created successfully.' => 'Felhasználó létrehozva .',
|
||||
'Unable to create your user.' => 'Felhasználó létrehozása nem sikerült.',
|
||||
'User updated successfully.' => 'Felhasználó sikeresen frissítve.',
|
||||
'Unable to update your user.' => 'Felhasználó frissítése nem sikerült.',
|
||||
'User removed successfully.' => 'Felhasználó sikeresen törölve.',
|
||||
'Unable to remove this user.' => 'Felhasználó törlése nem sikerült.',
|
||||
'Board updated successfully.' => 'Tábla sikeresen frissítve.',
|
||||
'Ready' => 'Kész',
|
||||
'Backlog' => 'Napló',
|
||||
'Work in progress' => 'Dolgozom',
|
||||
'Done' => 'Kész',
|
||||
'Application version:' => 'Alkalmazás verzió:',
|
||||
'Completed on %B %e, %Y at %k:%M %p' => 'Elkészült %Y.%m.%d %H:%M ..',
|
||||
'%B %e, %Y at %k:%M %p' => '%Y.%m.%d %H:%M',
|
||||
'Date created' => 'Létrehozás időpontja',
|
||||
'Date completed' => 'Befejezés időpontja',
|
||||
'Id' => 'ID',
|
||||
'No task' => 'Nincs feladat',
|
||||
'Completed tasks' => 'Elvégzett feladatok',
|
||||
'List of projects' => 'Projektek listája',
|
||||
'Completed tasks for "%s"' => 'Elvégzett feladatok "%s"',
|
||||
'%d closed tasks' => '%d lezárt feladat',
|
||||
'No task for this project' => 'Nincs feladat ebben a projektben',
|
||||
'Public link' => 'Nyilvános link',
|
||||
'There is no column in your project!' => 'Nincs oszlop a projektben!',
|
||||
'Change assignee' => 'Felelős módosítása',
|
||||
'Change assignee for the task "%s"' => 'Feladat felelősének módosítása: "%s"',
|
||||
'Timezone' => 'Időzóna',
|
||||
'Sorry, I didn\'t find this information in my database!' => 'Ez az információ nem található az adatbázisban!',
|
||||
'Page not found' => 'Az oldal nem található',
|
||||
'Complexity' => 'Bonyolultság',
|
||||
'limit' => 'határ',
|
||||
'Task limit' => 'Maximális számú feladat',
|
||||
'Task count' => 'Feladatok száma',
|
||||
'This value must be greater than %d' => 'Az értéknek nagyobbnak kell lennie, mint %d',
|
||||
'Edit project access list' => 'Projekt hozzáférés módosítása',
|
||||
'Edit users access' => 'Felhasználók hozzáférésének módosítása',
|
||||
'Allow this user' => 'Engedélyezi ezt a felhasználót',
|
||||
'Only those users have access to this project:' => 'Csak ezek a felhasználók férhetnek hozzá a projekthez:',
|
||||
'Don\'t forget that administrators have access to everything.' => 'Ne felejtsük el: a rendszergazdák mindenhez hozzáférnek.',
|
||||
'Revoke' => 'Visszavon',
|
||||
'List of authorized users' => 'Az engedélyezett felhasználók',
|
||||
'User' => 'Felhasználó',
|
||||
'Nobody have access to this project.' => 'Senkinek sincs hozzáférése a projekthez.',
|
||||
'You are not allowed to access to this project.' => 'Nincs hozzáférési joga a projekthez.',
|
||||
'Comments' => 'Hozzászólások',
|
||||
'Post comment' => 'Hozzászólás elküldése',
|
||||
'Write your text in Markdown' => 'Írja be a szöveget Markdown szintaxissal',
|
||||
'Leave a comment' => 'Írjon hozzászólást ...',
|
||||
'Comment is required' => 'A hozzászólás mező kötelező',
|
||||
'Leave a description' => 'Írjon leírást ...',
|
||||
'Comment added successfully.' => 'Hozzászólás sikeresen elküldve.',
|
||||
'Unable to create your comment.' => 'Hozzászólás létrehozása nem lehetséges.',
|
||||
'The description is required' => 'A leírás szükséges',
|
||||
'Edit this task' => 'Feladat módosítása',
|
||||
'Due Date' => 'Határidő',
|
||||
'Invalid date' => 'Érvénytelen dátum',
|
||||
'Must be done before %B %e, %Y' => 'Kész kell lennie %Y.%m.%d előtt',
|
||||
'%B %e, %Y' => '%Y.%m.%d',
|
||||
// '%b %e, %Y' => '',
|
||||
'Automatic actions' => 'Automatikus intézkedések',
|
||||
'Your automatic action have been created successfully.' => 'Az automatikus intézkedés sikeresen elkészült.',
|
||||
'Unable to create your automatic action.' => 'Automatikus intézkedés létrehozása nem lehetséges.',
|
||||
'Remove an action' => 'Intézkedés törlése',
|
||||
'Unable to remove this action.' => 'Intézkedés törlése nem lehetséges.',
|
||||
'Action removed successfully.' => 'Intézkedés sikeresen törölve.',
|
||||
'Automatic actions for the project "%s"' => 'Automatikus intézkedések a projektben "%s"',
|
||||
'Defined actions' => 'Intézkedések',
|
||||
'Add an action' => 'Intézkedés létrehozása',
|
||||
'Event name' => 'Esemény neve',
|
||||
'Action name' => 'Intézkedés neve',
|
||||
'Action parameters' => 'Intézkedés paraméterei',
|
||||
'Action' => 'Intézkedés',
|
||||
'Event' => 'Esemény',
|
||||
'When the selected event occurs execute the corresponding action.' => 'Ha a kiválasztott esemény bekövetkezik, hajtsa végre a megfelelő intézkedéseket.',
|
||||
'Next step' => 'Következő lépés',
|
||||
'Define action parameters' => 'Határozza meg az intézkedés paramétereit',
|
||||
'Save this action' => 'Intézkedés mentése',
|
||||
'Do you really want to remove this action: "%s"?' => 'Valóban törölni akarja ezt az intézkedést: "%s"?',
|
||||
'Remove an automatic action' => 'Automatikus intézkedés törlése',
|
||||
'Close the task' => 'Feladat lezárása',
|
||||
'Assign the task to a specific user' => 'Feladat kiosztása megadott felhasználónak',
|
||||
'Assign the task to the person who does the action' => 'Feladat kiosztása az intézkedő személynek',
|
||||
'Duplicate the task to another project' => 'Feladat másolása másik projektbe',
|
||||
'Move a task to another column' => 'Feladat mozgatása másik oszlopba',
|
||||
'Move a task to another position in the same column' => 'Feladat mozgatása oszlopon belül',
|
||||
'Task modification' => 'Feladat módosítása',
|
||||
'Task creation' => 'Feladat létrehozása',
|
||||
'Open a closed task' => 'Lezárt feladat megnyitása',
|
||||
'Closing a task' => 'Feladat lezárása',
|
||||
'Assign a color to a specific user' => 'Szín hozzárendelése a felhasználóhoz',
|
||||
'Column title' => 'Oszlopfejléc',
|
||||
'Position' => 'Pozíció',
|
||||
'Move Up' => 'Fel',
|
||||
'Move Down' => 'Le',
|
||||
'Duplicate to another project' => 'Másold egy másik projektbe',
|
||||
'Duplicate' => 'Másolat',
|
||||
'link' => 'link',
|
||||
'Update this comment' => 'Hozzászólás frissítése',
|
||||
'Comment updated successfully.' => 'Megjegyzés sikeresen frissítve.',
|
||||
'Unable to update your comment.' => 'Megjegyzés frissítése nem sikerült.',
|
||||
'Remove a comment' => 'Megjegyzés törlése',
|
||||
'Comment removed successfully.' => 'Megjegyzés sikeresen törölve.',
|
||||
'Unable to remove this comment.' => 'Megjegyzés törölése nem lehetséges.',
|
||||
'Do you really want to remove this comment?' => 'Valóban törölni szeretné ezt a megjegyzést?',
|
||||
'Only administrators or the creator of the comment can access to this page.' => 'Csak a rendszergazdák és a megjegyzés létrehozója férhet hozzá az oldalhoz.',
|
||||
'Details' => 'Részletek',
|
||||
'Current password for the user "%s"' => 'Felhasználó jelenlegi jelszava "%s"',
|
||||
'The current password is required' => 'A jelenlegi jelszót meg kell adni',
|
||||
'Wrong password' => 'Hibás jelszó',
|
||||
'Reset all tokens' => 'Reseteld az összes tokent',
|
||||
'All tokens have been regenerated.' => 'Minden token újra lett generálva.',
|
||||
'Unknown' => 'Ismeretlen',
|
||||
'Last logins' => 'Legutóbbi bejelentkezések',
|
||||
'Login date' => 'Bejelentkezés dátuma',
|
||||
'Authentication method' => 'Azonosítási módszer',
|
||||
'IP address' => 'IP-cím',
|
||||
'User agent' => 'User Agent',
|
||||
'Persistent connections' => 'Tartós (perzisztens) kapcsolatok',
|
||||
'No session.' => 'Nincs session.',
|
||||
'Expiration date' => 'Lejárati dátum',
|
||||
'Remember Me' => 'Emlékezz rám',
|
||||
'Creation date' => 'Létrehozás dátuma',
|
||||
'Filter by user' => 'Szűrés felhasználó szerint',
|
||||
'Filter by due date' => 'Szűrés határidő szerint',
|
||||
'Everybody' => 'Mindenki',
|
||||
'Open' => 'Nyitott',
|
||||
'Closed' => 'Lezárt',
|
||||
'Search' => 'Keres',
|
||||
'Nothing found.' => 'Semmit sem találtam.',
|
||||
'Search in the project "%s"' => 'Keresés a projektben "%s"',
|
||||
'Due date' => 'Határidő',
|
||||
'Others formats accepted: %s and %s' => 'Egyéb érvényes formátumok: %s és %s',
|
||||
'Description' => 'Leírás',
|
||||
'%d comments' => '%d megjegyzés',
|
||||
'%d comment' => '%d megjegyzés',
|
||||
'Email address invalid' => 'Érvénytelen e-mail cím',
|
||||
'Your Google Account is not linked anymore to your profile.' => 'Google Fiók már nincs a profilhoz kapcsolva.',
|
||||
'Unable to unlink your Google Account.' => 'Leválasztás a Google fiókról nem lehetséges.',
|
||||
'Google authentication failed' => 'Google azonosítás sikertelen',
|
||||
'Unable to link your Google Account.' => 'Google profilhoz kapcsolás nem sikerült.',
|
||||
'Your Google Account is linked to your profile successfully.' => 'Sikeresen összekapcsolva a Google fiókkal.',
|
||||
'Email' => 'E-mail',
|
||||
'Link my Google Account' => 'Kapcsold össze a Google fiókkal',
|
||||
'Unlink my Google Account' => 'Válaszd le a Google fiókomat',
|
||||
'Login with my Google Account' => 'Jelentkezzen be Google fiókkal',
|
||||
'Project not found.' => 'A projekt nem található.',
|
||||
'Task #%d' => 'Feladat #%d.',
|
||||
'Task removed successfully.' => 'Feladat törlése sikerült.',
|
||||
'Unable to remove this task.' => 'A feladatot nem lehet törölni.',
|
||||
'Remove a task' => 'Feladat törlése',
|
||||
'Do you really want to remove this task: "%s"?' => 'Valóban törölni akarja ezt a feladatot: "%s"?',
|
||||
'Assign automatically a color based on a category' => 'Szín hozzárendelése automatikusan kategória alapján',
|
||||
'Assign automatically a category based on a color' => 'Kategória hozzárendelése automatikusan szín alapján',
|
||||
'Task creation or modification' => 'Feladat létrehozása vagy módosítása',
|
||||
'Category' => 'Kategória',
|
||||
'Category:' => 'Kategória:',
|
||||
'Categories' => 'Kategóriák',
|
||||
'Category not found.' => 'Kategória nem található.',
|
||||
'Your category have been created successfully.' => 'Kategória sikeresen létrejött.',
|
||||
'Unable to create your category.' => 'A kategória létrehozása nem lehetséges.',
|
||||
'Your category have been updated successfully.' => 'Kategória sikeresen frissítve.',
|
||||
'Unable to update your category.' => 'Kategória frissítése nem lehetséges.',
|
||||
'Remove a category' => 'Kategória törlése',
|
||||
'Category removed successfully.' => 'Kategória törlése megtörtént.',
|
||||
'Unable to remove this category.' => 'A kategória törlése nem lehetséges.',
|
||||
'Category modification for the project "%s"' => 'Kategória módosítása a projektben "%s"',
|
||||
'Category Name' => 'Kategória neve',
|
||||
'Categories for the project "%s"' => 'Projekt kategóriák "%s"',
|
||||
'Add a new category' => 'Új kategória',
|
||||
'Do you really want to remove this category: "%s"?' => 'Valóban törölni akarja ezt a kategóriát "%s"?',
|
||||
'Filter by category' => 'Szűrés kategóriára',
|
||||
'All categories' => 'Minden kategória',
|
||||
'No category' => 'Nincs kategória',
|
||||
'The name is required' => 'A név megadása kötelező',
|
||||
'Remove a file' => 'Fájl törlése',
|
||||
'Unable to remove this file.' => 'Fájl törlése nem lehetséges.',
|
||||
'File removed successfully.' => 'A fájl törlése sikerült.',
|
||||
'Attach a document' => 'Fájl csatolása',
|
||||
'Do you really want to remove this file: "%s"?' => 'Valóban törölni akarja a fájlt: "%s"?',
|
||||
'open' => 'nyitott',
|
||||
'Attachments' => 'Mellékletek',
|
||||
'Edit the task' => 'Feladat módosítása',
|
||||
'Edit the description' => 'Leírás szerkesztése',
|
||||
'Add a comment' => 'Új megjegyzés',
|
||||
'Edit a comment' => 'Megjegyzés szerkesztése',
|
||||
'Summary' => 'Összegzés',
|
||||
'Time tracking' => 'Idő követés',
|
||||
'Estimate:' => 'Becsült:',
|
||||
'Spent:' => 'Eltöltött:',
|
||||
'Do you really want to remove this sub-task?' => 'Valóban törölni akarja ezt a részfeladatot "%s"?',
|
||||
'Remaining:' => 'Hátralévő:',
|
||||
'hours' => 'óra',
|
||||
'spent' => 'eltöltött',
|
||||
'estimated' => 'becsült',
|
||||
'Sub-Tasks' => 'részfeladatok',
|
||||
'Add a sub-task' => 'Részfeladat létrehozása',
|
||||
'Original estimate' => 'Eredeti időbecslés',
|
||||
'Create another sub-task' => 'További részfeladat létrehozása',
|
||||
'Time spent' => 'Eltöltött idő',
|
||||
'Edit a sub-task' => 'Részfeladat szerkesztése',
|
||||
'Remove a sub-task' => 'Részfeladat törlése',
|
||||
'The time must be a numeric value' => 'Idő csak számérték lehet',
|
||||
'Todo' => 'Teendő',
|
||||
'In progress' => 'Folyamatban',
|
||||
'Sub-task removed successfully.' => 'Részfeladat sikeresen törölve.',
|
||||
'Unable to remove this sub-task.' => 'Részfeladat törlése nem lehetséges.',
|
||||
'Sub-task updated successfully.' => 'Részfeladat sikeresen frissítve.',
|
||||
'Unable to update your sub-task.' => 'Részfeladat frissítése nem lehetséges.',
|
||||
'Unable to create your sub-task.' => 'Részfeladat létrehozása nem lehetséges.',
|
||||
'Sub-task added successfully.' => 'Részfeladat sikeresen létrejött.',
|
||||
'Maximum size: ' => 'Maximális méret:',
|
||||
'Unable to upload the file.' => 'Fájl feltöltése nem lehetséges.',
|
||||
'Display another project' => 'Másik projekt megjelenítése',
|
||||
'Your GitHub account was successfully linked to your profile.' => 'GitHub fiók sikeresen csatolva a profilhoz.',
|
||||
'Unable to link your GitHub Account.' => 'Nem lehet csatolni a GitHub fiókot.',
|
||||
'GitHub authentication failed' => 'GitHub azonosítás sikertelen',
|
||||
'Your GitHub account is no longer linked to your profile.' => 'GitHub fiók már nincs profilhoz kapcsolva.',
|
||||
'Unable to unlink your GitHub Account.' => 'GitHub fiók leválasztása nem lehetséges.',
|
||||
'Login with my GitHub Account' => 'Jelentkezzen be GitHub fiókkal',
|
||||
'Link my GitHub Account' => 'GitHub fiók csatolása',
|
||||
'Unlink my GitHub Account' => 'GitHub fiók leválasztása',
|
||||
'Created by %s' => 'Készítette: %s',
|
||||
'Last modified on %B %e, %Y at %k:%M %p' => 'Utolsó módosítás %Y.%m.%d %H:%M',
|
||||
'Tasks Export' => 'Feladatok exportálása',
|
||||
'Tasks exportation for "%s"' => 'Feladatok exportálása "%s" részére',
|
||||
'Start Date' => 'Kezdés dátuma',
|
||||
'End Date' => 'Befejezés dátuma',
|
||||
'Execute' => 'Végrehajt',
|
||||
'Task Id' => 'Feladat ID',
|
||||
'Creator' => 'Készítette',
|
||||
'Modification date' => 'Módosítás dátuma',
|
||||
'Completion date' => 'Befejezés határideje',
|
||||
'Webhook URL for task creation' => 'Webhook URL a feladat létrehozásakor',
|
||||
'Webhook URL for task modification' => 'Webhook URL a feladatot módosításakor',
|
||||
'Clone' => 'Másolat',
|
||||
'Clone Project' => 'Projekt megkettőzése',
|
||||
'Project cloned successfully.' => 'A projekt sikeresen megkettőzve.',
|
||||
'Unable to clone this project.' => 'Projekt megkettőzése nem sikerült.',
|
||||
'Email notifications' => 'E-mail értesítések',
|
||||
'Enable email notifications' => 'Engedélyezze az e-mail értesítéseket',
|
||||
'Task position:' => 'Feladat helye:',
|
||||
'The task #%d have been opened.' => 'Feladat #%d megnyitva.',
|
||||
'The task #%d have been closed.' => 'Feladat #%d lezárva.',
|
||||
'Sub-task updated' => 'Részfeladat frissítve',
|
||||
'Title:' => 'Cím',
|
||||
'Status:' => 'Állapot',
|
||||
'Assignee:' => 'Felelős:',
|
||||
'Time tracking:' => 'Idő követés:',
|
||||
'New sub-task' => 'Új részfeladat',
|
||||
'New attachment added "%s"' => 'Új melléklet "%s" hozzáadva.',
|
||||
'Comment updated' => 'Megjegyzés frissítve',
|
||||
'New comment posted by %s' => 'Új megjegyzés %s',
|
||||
'List of due tasks for the project "%s"' => 'Projekt esedékes feladatai "%s"',
|
||||
'[%s][New attachment] %s (#%d)' => '[%s] [Új csatolmány] %s (#%d)',
|
||||
'[%s][New comment] %s (#%d)' => '[%s] [Új hozzászólás] %s (#%d)',
|
||||
'[%s][Comment updated] %s (#%d)' => '[%s] [Megjegyzés frissítve] %s (#%d)',
|
||||
'[%s][New subtask] %s (#%d)' => '[%s] [Új részfeladat] %s (#%d)',
|
||||
'[%s][Subtask updated] %s (#%d)' => '[%s] [Részfeladat frissítve] %s (#%d)',
|
||||
'[%s][New task] %s (#%d)' => '[%s] [Új feladat] %s (#%d)',
|
||||
'[%s][Task updated] %s (#%d)' => '[%s] [Feladat frissítve] %s (#%d)',
|
||||
'[%s][Task closed] %s (#%d)' => '[%s] [Feladat lezárva]%s (#%d)',
|
||||
'[%s][Task opened] %s (#%d)' => '[%s] [Feladat megnyitva] %s (#%d)',
|
||||
'[%s][Due tasks]' => '[%s] [Esedékes feladatok]',
|
||||
'[Kanboard] Notification' => '[Kanboard] értesítés',
|
||||
'I want to receive notifications only for those projects:' => 'Csak ezekről a projektekről kérek értesítést:',
|
||||
'view the task on Kanboard' => 'feladat megtekintése a Kanboardon',
|
||||
'Public access' => 'Nyilvános hozzáférés',
|
||||
'Category management' => 'Kategóriák kezelése',
|
||||
'User management' => 'Felhasználók kezelése',
|
||||
'Active tasks' => 'Aktív feladatok',
|
||||
'Disable public access' => 'Nyilvános hozzáférés letiltása',
|
||||
'Enable public access' => 'Nyilvános hozzáférés engedélyezése',
|
||||
'Active projects' => 'Aktív projektek',
|
||||
'Inactive projects' => 'Inaktív projektek',
|
||||
'Public access disabled' => 'Nyilvános hozzáférés letiltva',
|
||||
'Do you really want to disable this project: "%s"?' => 'Tényleg szeretné letiltani ezt a projektet: "%s"',
|
||||
'Do you really want to duplicate this project: "%s"?' => 'Tényleg szeretné megkettőzni ezt a projektet: "%s"',
|
||||
'Do you really want to enable this project: "%s"?' => 'Tényleg szeretné engedélyezni ezt a projektet: "%s"',
|
||||
'Project activation' => 'Projekt aktiválás',
|
||||
'Move the task to another project' => 'Feladatot mozgatása másik projektbe',
|
||||
'Move to another project' => 'Másik projektbe',
|
||||
'Do you really want to duplicate this task?' => 'Tényleg szeretné megkettőzni ezt a feladatot?',
|
||||
'Duplicate a task' => 'Feladat megkettőzése',
|
||||
'External accounts' => 'Külső fiókok',
|
||||
'Account type' => 'Fiók típus',
|
||||
'Local' => 'Helyi',
|
||||
'Remote' => 'Távoli',
|
||||
'Enabled' => 'Engedélyezve',
|
||||
'Disabled' => 'Letiltva',
|
||||
'Google account linked' => 'Google fiók összekapcsolva',
|
||||
'Github account linked' => 'GitHub fiók összekapcsolva',
|
||||
'Username:' => 'Felhasználónév',
|
||||
'Name:' => 'Név',
|
||||
'Email:' => 'E-mail',
|
||||
'Default project:' => 'Alapértelmezett projekt:',
|
||||
'Notifications:' => 'Értesítések:',
|
||||
'Notifications' => 'Értesítések',
|
||||
'Group:' => 'Csoport:',
|
||||
'Regular user' => 'Default User',
|
||||
'Account type:' => 'Fiók típus:',
|
||||
'Edit profile' => 'Profil szerkesztése',
|
||||
'Change password' => 'Jelszó módosítása',
|
||||
'Password modification' => 'Jelszó módosítása',
|
||||
'External authentications' => 'Külső azonosítás',
|
||||
'Google Account' => 'Google fiók',
|
||||
'Github Account' => 'Github fiók',
|
||||
'Never connected.' => 'Sosem csatlakozva.',
|
||||
'No account linked.' => 'Nincs csatlakoztatott fiók.',
|
||||
'Account linked.' => 'Fiók csatlakoztatva.',
|
||||
'No external authentication enabled.' => 'Külső azonosítás nincs engedélyezve.',
|
||||
'Password modified successfully.' => 'Jelszó sikeresen módosítva.',
|
||||
'Unable to change the password.' => 'Jelszó módosítás sikertelen.',
|
||||
'Change category for the task "%s"' => 'Feladat kategória módosítása "%s"',
|
||||
'Change category' => 'Kategória módosítása',
|
||||
'%s updated the task %s' => '%s frissítette a feladatot %s',
|
||||
'%s opened the task %s' => '%s megnyitott a feladatot %s',
|
||||
'%s moved the task %s to the position #%d in the column "%s"' => '%s átmozgatta a feladatot %s #%d pozícióba a "%s" oszlopban',
|
||||
'%s moved the task %s to the column "%s"' => '%s átmozgatta a feladatot %s "%s" oszlopba',
|
||||
'%s created the task %s' => '%s létrehozta a feladatot %s',
|
||||
'%s closed the task %s' => '%s lezárta a feladatot %s',
|
||||
'%s created a subtask for the task %s' => '%s létrehozott egy részfeladat a feladathoz %s',
|
||||
'%s updated a subtask for the task %s' => '%s frissített egy részfeladatot a feladathoz %s',
|
||||
'Assigned to %s with an estimate of %s/%sh' => '%s-nek kiosztva %s/%s óra becsült idő mellett',
|
||||
'Not assigned, estimate of %sh' => 'Nincs kiosztva, becsült idő: %s óra',
|
||||
'%s updated a comment on the task %s' => '%s frissítette a megjegyzését a feladatban %s',
|
||||
'%s commented the task %s' => '%s megjegyzést fűzött a feladathoz %s',
|
||||
'%s\'s activity' => '%s tevékenysége',
|
||||
'No activity.' => 'Nincs tevékenység.',
|
||||
'RSS feed' => 'RSS feed',
|
||||
'%s updated a comment on the task #%d' => '%s frissített egy megjegyzést a feladatban #%d',
|
||||
'%s commented on the task #%d' => '%s megjegyzést tett a feladathoz #%d',
|
||||
'%s updated a subtask for the task #%d' => '%s frissített egy részfeladatot a feladatban #%d',
|
||||
'%s created a subtask for the task #%d' => '%s létrehozott egy részfeladatot a feladatban #%d',
|
||||
'%s updated the task #%d' => '%s frissítette a feladatot #%d',
|
||||
'%s created the task #%d' => '%s létrehozta a feladatot #%d',
|
||||
'%s closed the task #%d' => '%s lezárta a feladatot #%d',
|
||||
'%s open the task #%d' => '%s megnyitotta a feladatot #%d',
|
||||
'%s moved the task #%d to the column "%s"' => '%s átmozgatta a feladatot #%d a "%s" oszlopba',
|
||||
'%s moved the task #%d to the position %d in the column "%s"' => '%s átmozgatta a feladatot #%d a %d pozícióba a "%s" oszlopban',
|
||||
'Activity' => 'Tevékenység',
|
||||
'Default values are "%s"' => 'Az alapértelmezett értékek "%s"',
|
||||
'Default columns for new projects (Comma-separated)' => 'Alapértelmezett oszlopok az új projektekben (vesszővel elválasztva)',
|
||||
'Task assignee change' => 'Felelős módosítása',
|
||||
'%s change the assignee of the task #%d to %s' => '%s a felelőst módosította #%d %s',
|
||||
'%s changed the assignee of the task %s to %s' => '%s a felelőst %s módosította: %s',
|
||||
'[%s][Column Change] %s (#%d)' => '[%s] [Oszlop módosítás] %s (#%d)',
|
||||
'[%s][Position Change] %s (#%d)' => '[%s] [Pozíció módosítás] %s (#%d)',
|
||||
'[%s][Assignee Change] %s (#%d)' => '[%s] [Felelős módosítás] %s (#%d)',
|
||||
'New password for the user "%s"' => 'Felhasználó új jelszava "%s"',
|
||||
'Choose an event' => 'Válasszon eseményt',
|
||||
'Github commit received' => 'GitHub commit érkezett',
|
||||
'Github issue opened' => 'GitHub issue nyílt',
|
||||
'Github issue closed' => 'GitHub issue zárt',
|
||||
'Github issue reopened' => 'GitHub issue újranyitva',
|
||||
'Github issue assignee change' => 'GitHub issue felelős változás',
|
||||
'Github issue label change' => 'GitHub issue címke változás',
|
||||
'Create a task from an external provider' => 'Feladat létrehozása külsős számára',
|
||||
'Change the assignee based on an external username' => 'Felelős módosítása külső felhasználónév alapján',
|
||||
'Change the category based on an external label' => 'Kategória módosítása külső címke alapján',
|
||||
'Reference' => 'Hivatkozás',
|
||||
'Reference: %s' => 'Hivatkozás: %s',
|
||||
'Label' => 'Címke',
|
||||
'Database' => 'Adatbázis',
|
||||
'About' => 'Kanboard információ',
|
||||
'Database driver:' => 'Adatbázis driver:',
|
||||
'Board settings' => 'Tábla beállítások',
|
||||
'URL and token' => 'URL és tokenek',
|
||||
'Webhook settings' => 'Webhook beállítások',
|
||||
'URL for task creation:' => 'Feladat létrehozás URL:',
|
||||
'Reset token' => 'Reset token',
|
||||
'API endpoint:' => 'API endpoint:',
|
||||
'Refresh interval for private board' => 'Privát táblák frissítési intervalluma',
|
||||
'Refresh interval for public board' => 'Nyilvános táblák frissítési intervalluma',
|
||||
'Task highlight period' => 'Feladat kiemelés időtartama',
|
||||
'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => 'Mennyi ideig tekintendő egy feladat "mostanában" módosítottnak (másodpercben) (0: funkció letiltva, alapértelmezés szerint 2 nap)',
|
||||
'Frequency in second (60 seconds by default)' => 'Infó másodpercben (alapértelmezett 60 másodperc)',
|
||||
'Frequency in second (0 to disable this feature, 10 seconds by default)' => 'Infó másodpercben (0 funkció letiltva, alapértelmezés szerint 10 másodperc)',
|
||||
'Application URL' => 'Alkalmazás URL',
|
||||
'Example: http://example.kanboard.net/ (used by email notifications)' => 'Példa: http://example.kanboard.net/ (e-mail értesítőben)',
|
||||
'Token regenerated.' => 'Token újragenerálva.',
|
||||
'Date format' => 'Dátum formátum',
|
||||
'ISO format is always accepted, example: "%s" and "%s"' => 'ISO formátum mindig elfogadott, pl: "%s" és "%s"',
|
||||
'New private project' => 'Új privát projekt',
|
||||
'This project is private' => 'Ez egy privát projekt',
|
||||
'Type here to create a new sub-task' => 'Ide írva létrehozhat egy új részfeladatot',
|
||||
'Add' => 'Hozzáad',
|
||||
'Estimated time: %s hours' => 'Becsült idő: %s óra',
|
||||
'Time spent: %s hours' => 'Eltöltött idő: %s óra',
|
||||
'Started on %B %e, %Y' => 'Elkezdve: %Y.%m.%d',
|
||||
'Start date' => 'Kezdés dátuma',
|
||||
'Time estimated' => 'Becsült időtartam',
|
||||
'There is nothing assigned to you.' => 'Nincs kiosztott feladat.',
|
||||
'My tasks' => 'Feladataim',
|
||||
'Activity stream' => 'Legutóbbi tevékenységek',
|
||||
'Dashboard' => 'Műszerfal',
|
||||
'Confirmation' => 'Megerősítés',
|
||||
'Allow everybody to access to this project' => 'Engedélyezze a projekt elérését mindenkinek',
|
||||
'Everybody have access to this project.' => 'Mindenki elérheti a projektet',
|
||||
'Webhooks' => 'Webhook',
|
||||
'API' => 'API',
|
||||
'Integration' => 'Integráció',
|
||||
'Github webhooks' => 'Github webhooks',
|
||||
'Help on Github webhooks' => 'Github Webhook súgó',
|
||||
'Create a comment from an external provider' => 'Megjegyzés létrehozása külső felhasználótól',
|
||||
'Github issue comment created' => 'Github issue megjegyzés létrehozva',
|
||||
'Configure' => 'Konfigurál',
|
||||
'Project management' => 'Projekt menedzsment',
|
||||
'My projects' => 'Projektjeim',
|
||||
'Columns' => 'Oszlopok',
|
||||
'Task' => 'Feladat',
|
||||
'Your are not member of any project.' => 'Ön nem tagja projektnek.',
|
||||
'Percentage' => 'Százalék',
|
||||
'Number of tasks' => 'A feladatok száma',
|
||||
'Task distribution' => 'Feladatelosztás',
|
||||
'Reportings' => 'Jelentések',
|
||||
'Task repartition for "%s"' => 'Feladat újraosztása "%s" számára',
|
||||
'Analytics' => 'Analitika',
|
||||
'Subtask' => 'Részfeladat',
|
||||
'My subtasks' => 'Részfeladataim',
|
||||
'User repartition' => 'Felhasználó újrafelosztás',
|
||||
'User repartition for "%s"' => 'Felhasználó újrafelosztás "%s" számára',
|
||||
'Clone this project' => 'Projekt megkettőzése',
|
||||
'Column removed successfully.' => 'Oszlop sikeresen eltávolítva.',
|
||||
'Edit Project' => 'Projekt szerkesztése',
|
||||
'Github Issue' => 'Github issue',
|
||||
'Not enough data to show the graph.' => 'Nincs elég adat a grafikonhoz.',
|
||||
'Previous' => 'Előző',
|
||||
'The id must be an integer' => 'Az ID csak egész szám lehet',
|
||||
'The project id must be an integer' => 'A projekt ID csak egész szám lehet',
|
||||
'The status must be an integer' => 'Az állapot csak egész szám lehet',
|
||||
'The subtask id is required' => 'A részfeladat ID-t meg kell adni',
|
||||
'The subtask id must be an integer' => 'A részfeladat ID csak egész szám lehet',
|
||||
'The task id is required' => 'A feladat ID-t meg kell adni',
|
||||
'The task id must be an integer' => 'A feladat ID csak egész szám lehet',
|
||||
'The user id must be an integer' => 'A felhasználói ID csak egész szám lehet',
|
||||
'This value is required' => 'Ez a mező kötelező',
|
||||
'This value must be numeric' => 'Ez a mező csak szám lehet',
|
||||
'Unable to create this task.' => 'A feladat nem hozható létre,',
|
||||
'Cumulative flow diagram' => 'Kumulatív Flow Diagram',
|
||||
'Cumulative flow diagram for "%s"' => 'Kumulatív Flow Diagram "%s" számára',
|
||||
'Daily project summary' => 'Napi projektösszefoglaló',
|
||||
'Daily project summary export' => 'Napi projektösszefoglaló exportálása',
|
||||
'Daily project summary export for "%s"' => 'Napi projektösszefoglaló exportálása "%s" számára',
|
||||
'Exports' => 'Exportálások',
|
||||
'This export contains the number of tasks per column grouped per day.' => 'Ez az export tartalmazza a feladatok számát oszloponként összesítve, napokra lebontva.',
|
||||
'Nothing to preview...' => 'Nincs semmi az előnézetben ...',
|
||||
'Preview' => 'Előnézet',
|
||||
'Write' => 'Írd',
|
||||
// 'Active swimlanes' => '',
|
||||
// 'Add a new swimlane' => '',
|
||||
// 'Change default swimlane' => '',
|
||||
// 'Default swimlane' => '',
|
||||
// 'Do you really want to remove this swimlane: "%s"?' => '',
|
||||
// 'Inactive swimlanes' => '',
|
||||
// 'Set project manager' => '',
|
||||
// 'Set project member' => '',
|
||||
// 'Remove a swimlane' => '',
|
||||
// 'Rename' => '',
|
||||
// 'Show default swimlane' => '',
|
||||
// 'Swimlane modification for the project "%s"' => '',
|
||||
// 'Swimlane not found.' => '',
|
||||
// 'Swimlane removed successfully.' => '',
|
||||
// 'Swimlanes' => '',
|
||||
// 'Swimlane updated successfully.' => '',
|
||||
// 'The default swimlane have been updated successfully.' => '',
|
||||
// 'Unable to create your swimlane.' => '',
|
||||
// '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)' => '',
|
||||
// 'Gitlab commit received' => '',
|
||||
// 'Gitlab issue opened' => '',
|
||||
// 'Gitlab issue closed' => '',
|
||||
// 'Gitlab webhooks' => '',
|
||||
// 'Help on Gitlab webhooks' => '',
|
||||
// 'Integrations' => '',
|
||||
// 'Integration with third-party services' => '',
|
||||
// 'Role for this project' => '',
|
||||
// 'Project manager' => '',
|
||||
// 'Project member' => '',
|
||||
// 'A project manager can change the settings of the project and have more privileges than a standard user.' => '',
|
||||
// 'Gitlab Issue' => '',
|
||||
// 'Subtask Id' => '',
|
||||
// 'Subtasks' => '',
|
||||
// 'Subtasks Export' => '',
|
||||
// 'Subtasks exportation for "%s"' => '',
|
||||
// 'Task Title' => '',
|
||||
// 'Untitled' => '',
|
||||
// 'Application default' => '',
|
||||
// 'Language:' => '',
|
||||
// 'Timezone:' => '',
|
||||
// 'Next' => '',
|
||||
);
|
|
@ -182,7 +182,7 @@ return array(
|
|||
'Change assignee' => 'Cambiare la persona assegnata',
|
||||
'Change assignee for the task "%s"' => 'Cambiare la persona assegnata per il compito « %s »',
|
||||
'Timezone' => 'Fuso orario',
|
||||
'Sorry, I didn\'t found this information in my database!' => 'Mi dispiace, non ho trovato questa informazione sulla base dati!',
|
||||
'Sorry, I didn\'t find this information in my database!' => 'Mi dispiace, non ho trovato questa informazione sulla base dati!',
|
||||
'Page not found' => 'Pagina non trovata',
|
||||
// 'Complexity' => '',
|
||||
'limit' => 'limite',
|
||||
|
@ -194,7 +194,7 @@ return array(
|
|||
'Allow this user' => 'Permettere a questo utente',
|
||||
'Only those users have access to this project:' => 'Solo questi utenti hanno accesso a questo progetto:',
|
||||
'Don\'t forget that administrators have access to everything.' => 'Non dimenticare che gli amministratori hanno accesso a tutto.',
|
||||
'revoke' => 'revocare',
|
||||
'Revoke' => 'Revocare',
|
||||
'List of authorized users' => 'Lista di utenti autorizzati',
|
||||
'User' => 'Utente',
|
||||
// 'Nobody have access to this project.' => '',
|
||||
|
@ -213,6 +213,7 @@ return array(
|
|||
'Invalid date' => 'Data sbagliata',
|
||||
// 'Must be done before %B %e, %Y' => '',
|
||||
// '%B %e, %Y' => '',
|
||||
// '%b %e, %Y' => '',
|
||||
'Automatic actions' => 'Azioni automatiche',
|
||||
'Your automatic action have been created successfully.' => 'l\'azione automatica è stata creata correttamente.',
|
||||
'Unable to create your automatic action.' => 'Non si può creare quest\'azione automatica.',
|
||||
|
@ -468,18 +469,18 @@ return array(
|
|||
// 'Unable to change the password.' => '',
|
||||
// 'Change category for the task "%s"' => '',
|
||||
// 'Change category' => '',
|
||||
// '%s updated the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '',
|
||||
// '%s open the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '',
|
||||
// '%s moved the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to the position #%d in the column "%s"' => '',
|
||||
// '%s moved the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to the column "%s"' => '',
|
||||
// '%s created the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '',
|
||||
// '%s closed the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '',
|
||||
// '%s created a subtask for the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '',
|
||||
// '%s updated a subtask for the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '',
|
||||
// '%s updated the task %s' => '',
|
||||
// '%s opened the task %s' => '',
|
||||
// '%s moved the task %s to the position #%d in the column "%s"' => '',
|
||||
// '%s moved the task %s to the column "%s"' => '',
|
||||
// '%s created the task %s' => '',
|
||||
// '%s closed the task %s' => '',
|
||||
// '%s created a subtask for the task %s' => '',
|
||||
// '%s updated a subtask for the task %s' => '',
|
||||
// 'Assigned to %s with an estimate of %s/%sh' => '',
|
||||
// 'Not assigned, estimate of %sh' => '',
|
||||
// '%s updated a comment on the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '',
|
||||
// '%s commented the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '',
|
||||
// '%s updated a comment on the task %s' => '',
|
||||
// '%s commented the task %s' => '',
|
||||
// '%s\'s activity' => '',
|
||||
// 'No activity.' => '',
|
||||
// 'RSS feed' => '',
|
||||
|
@ -498,7 +499,7 @@ return array(
|
|||
// 'Default columns for new projects (Comma-separated)' => '',
|
||||
// 'Task assignee change' => '',
|
||||
// '%s change the assignee of the task #%d to %s' => '',
|
||||
// '%s change the assignee of the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to %s' => '',
|
||||
// '%s changed the assignee of the task %s to %s' => '',
|
||||
// '[%s][Column Change] %s (#%d)' => '',
|
||||
// '[%s][Position Change] %s (#%d)' => '',
|
||||
// '[%s][Assignee Change] %s (#%d)' => '',
|
||||
|
@ -555,8 +556,8 @@ return array(
|
|||
// 'Webhooks' => '',
|
||||
// 'API' => '',
|
||||
// 'Integration' => '',
|
||||
// 'Github webhook' => '',
|
||||
// 'Help on Github webhook' => '',
|
||||
// 'Github webhooks' => '',
|
||||
// 'Help on Github webhooks' => '',
|
||||
// 'Create a comment from an external provider' => '',
|
||||
// 'Github issue comment created' => '',
|
||||
// 'Configure' => '',
|
||||
|
@ -602,4 +603,49 @@ return array(
|
|||
// 'Nothing to preview...' => '',
|
||||
// 'Preview' => '',
|
||||
// 'Write' => '',
|
||||
// 'Active swimlanes' => '',
|
||||
// 'Add a new swimlane' => '',
|
||||
// 'Change default swimlane' => '',
|
||||
// 'Default swimlane' => '',
|
||||
// 'Do you really want to remove this swimlane: "%s"?' => '',
|
||||
// 'Inactive swimlanes' => '',
|
||||
// 'Set project manager' => '',
|
||||
// 'Set project member' => '',
|
||||
// 'Remove a swimlane' => '',
|
||||
// 'Rename' => '',
|
||||
// 'Show default swimlane' => '',
|
||||
// 'Swimlane modification for the project "%s"' => '',
|
||||
// 'Swimlane not found.' => '',
|
||||
// 'Swimlane removed successfully.' => '',
|
||||
// 'Swimlanes' => '',
|
||||
// 'Swimlane updated successfully.' => '',
|
||||
// 'The default swimlane have been updated successfully.' => '',
|
||||
// 'Unable to create your swimlane.' => '',
|
||||
// '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)' => '',
|
||||
// 'Gitlab commit received' => '',
|
||||
// 'Gitlab issue opened' => '',
|
||||
// 'Gitlab issue closed' => '',
|
||||
// 'Gitlab webhooks' => '',
|
||||
// 'Help on Gitlab webhooks' => '',
|
||||
// 'Integrations' => '',
|
||||
// 'Integration with third-party services' => '',
|
||||
// 'Role for this project' => '',
|
||||
// 'Project manager' => '',
|
||||
// 'Project member' => '',
|
||||
// 'A project manager can change the settings of the project and have more privileges than a standard user.' => '',
|
||||
// 'Gitlab Issue' => '',
|
||||
// 'Subtask Id' => '',
|
||||
// 'Subtasks' => '',
|
||||
// 'Subtasks Export' => '',
|
||||
// 'Subtasks exportation for "%s"' => '',
|
||||
// 'Task Title' => '',
|
||||
// 'Untitled' => '',
|
||||
// 'Application default' => '',
|
||||
// 'Language:' => '',
|
||||
// 'Timezone:' => '',
|
||||
// 'Next' => '',
|
||||
);
|
||||
|
|
|
@ -182,7 +182,7 @@ return array(
|
|||
'Change assignee' => '担当を変更する',
|
||||
'Change assignee for the task "%s"' => 'タスク「%s」の担当を変更する',
|
||||
'Timezone' => 'タイムゾーン',
|
||||
'Sorry, I didn\'t found this information in my database!' => 'データベース上で情報が見つかりませんでした!',
|
||||
'Sorry, I didn\'t find this information in my database!' => 'データベース上で情報が見つかりませんでした!',
|
||||
'Page not found' => 'ページが見つかりません',
|
||||
'Complexity' => '複雑さ',
|
||||
'limit' => '制限',
|
||||
|
@ -194,7 +194,7 @@ return array(
|
|||
'Allow this user' => 'このユーザを許可する',
|
||||
'Only those users have access to this project:' => 'これらのユーザのみがプロジェクトにアクセスできます:',
|
||||
'Don\'t forget that administrators have access to everything.' => '管理者には全ての権限が与えられます。',
|
||||
'revoke' => '許可を取り下げる',
|
||||
'Revoke' => '許可を取り下げる',
|
||||
'List of authorized users' => '許可されたユーザ',
|
||||
'User' => 'ユーザ',
|
||||
'Nobody have access to this project.' => 'だれもプロジェクトにアクセスできません。',
|
||||
|
@ -213,6 +213,7 @@ return array(
|
|||
'Invalid date' => '日付が無効です',
|
||||
'Must be done before %B %e, %Y' => '%Y/%m/%d までに完了',
|
||||
'%B %e, %Y' => '%d %B %Y',
|
||||
// '%b %e, %Y' => '',
|
||||
'Automatic actions' => '自動アクションを管理する',
|
||||
'Your automatic action have been created successfully.' => '自動アクションを作成しました。',
|
||||
'Unable to create your automatic action.' => '自動アクションの作成に失敗しました。',
|
||||
|
@ -468,18 +469,18 @@ return array(
|
|||
'Unable to change the password.' => 'パスワードが変更できませんでした。',
|
||||
'Change category for the task "%s"' => 'タスク「%s」のカテゴリの変更',
|
||||
'Change category' => 'カテゴリの変更',
|
||||
'%s updated the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s がタスク <a href="?controller=task&action=show&task_id=%d">#%d</a> をアップデートしました',
|
||||
'%s open the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s がタスク <a href="?controller=task&action=show&task_id=%d">#%d</a> をオープンしました',
|
||||
'%s moved the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to the position #%d in the column "%s"' => '%s がタスク <a href="?controller=task&action=show&task_id=%d">#%d</a> をポジション #%d カラム %s に移動しました',
|
||||
'%s moved the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to the column "%s"' => '%s がタスク <a href="?controller=task&action=show&task_id=%d">#%d</a> をカラム「%s」に移動しました',
|
||||
'%s created the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s がタスク <a href="?controller=task&action=show&task_id=%d">#%d</a> を作成しました',
|
||||
'%s closed the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s がタスク <a href="?controller=task&action=show&task_id=%d">#%d</a> をクローズしました',
|
||||
'%s created a subtask for the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s がタスク <a href="?controller=task&action=show&task_id=%d">#%d</a> のサブタスクを追加しました',
|
||||
'%s updated a subtask for the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s がタスク <a href="?controller=task&action=show&task_id=%d">#%d</a> のサブタスクを更新しました',
|
||||
'%s updated the task %s' => '%s がタスク %s をアップデートしました',
|
||||
'%s opened the task %s' => '%s がタスク %s をオープンしました',
|
||||
'%s moved the task %s to the position #%d in the column "%s"' => '%s がタスク %s をポジション #%d カラム %s に移動しました',
|
||||
'%s moved the task %s to the column "%s"' => '%s がタスク %s をカラム「%s」に移動しました',
|
||||
'%s created the task %s' => '%s がタスク %s を作成しました',
|
||||
'%s closed the task %s' => '%s がタスク %s をクローズしました',
|
||||
'%s created a subtask for the task %s' => '%s がタスク %s のサブタスクを追加しました',
|
||||
'%s updated a subtask for the task %s' => '%s がタスク %s のサブタスクを更新しました',
|
||||
'Assigned to %s with an estimate of %s/%sh' => '担当者 %s に予想 %s/%sh に変更されました',
|
||||
'Not assigned, estimate of %sh' => '担当者無しで予想 %sh に変更されました',
|
||||
'%s updated a comment on the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s がタスク <a href="?controller=task&action=show&task_id=%d">#%d</a> のコメントを更新しました',
|
||||
'%s commented the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s がタスク <a href="?controller=task&action=show&task_id=%d">#%d</a> にコメントしました',
|
||||
'%s updated a comment on the task %s' => '%s がタスク %s のコメントを更新しました',
|
||||
'%s commented the task %s' => '%s がタスク %s にコメントしました',
|
||||
'%s\'s activity' => '%s のアクティビティ',
|
||||
'No activity.' => 'アクティビティなし。',
|
||||
'RSS feed' => 'RSS フィード',
|
||||
|
@ -498,7 +499,7 @@ return array(
|
|||
'Default columns for new projects (Comma-separated)' => '新規プロジェクトのデフォルトカラム (コンマで区切って入力)',
|
||||
'Task assignee change' => '担当者の変更',
|
||||
'%s change the assignee of the task #%d to %s' => '%s がタスク #%d の担当を %s に変更しました',
|
||||
'%s change the assignee of the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to %s' => '%s がタスク <a href="?controller=task&action=show&task_id=%d">#%d</a> の担当を %s に変更しました',
|
||||
'%s changed the assignee of the task %s to %s' => '%s がタスク %s の担当を %s に変更しました',
|
||||
'[%s][Column Change] %s (#%d)' => '[%s][カラムの変更] %s (#%d)',
|
||||
'[%s][Position Change] %s (#%d)' => '[%s][位置の変更] %s (#%d)',
|
||||
'[%s][Assignee Change] %s (#%d)' => '[%s][担当者変更] %s (#%d)',
|
||||
|
@ -555,8 +556,8 @@ return array(
|
|||
// 'Webhooks' => '',
|
||||
// 'API' => '',
|
||||
// 'Integration' => '',
|
||||
// 'Github webhook' => '',
|
||||
// 'Help on Github webhook' => '',
|
||||
// 'Github webhooks' => '',
|
||||
// 'Help on Github webhooks' => '',
|
||||
// 'Create a comment from an external provider' => '',
|
||||
// 'Github issue comment created' => '',
|
||||
// 'Configure' => '',
|
||||
|
@ -602,4 +603,49 @@ return array(
|
|||
// 'Nothing to preview...' => '',
|
||||
// 'Preview' => '',
|
||||
// 'Write' => '',
|
||||
// 'Active swimlanes' => '',
|
||||
// 'Add a new swimlane' => '',
|
||||
// 'Change default swimlane' => '',
|
||||
// 'Default swimlane' => '',
|
||||
// 'Do you really want to remove this swimlane: "%s"?' => '',
|
||||
// 'Inactive swimlanes' => '',
|
||||
// 'Set project manager' => '',
|
||||
// 'Set project member' => '',
|
||||
// 'Remove a swimlane' => '',
|
||||
// 'Rename' => '',
|
||||
// 'Show default swimlane' => '',
|
||||
// 'Swimlane modification for the project "%s"' => '',
|
||||
// 'Swimlane not found.' => '',
|
||||
// 'Swimlane removed successfully.' => '',
|
||||
// 'Swimlanes' => '',
|
||||
// 'Swimlane updated successfully.' => '',
|
||||
// 'The default swimlane have been updated successfully.' => '',
|
||||
// 'Unable to create your swimlane.' => '',
|
||||
// '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)' => '',
|
||||
// 'Gitlab commit received' => '',
|
||||
// 'Gitlab issue opened' => '',
|
||||
// 'Gitlab issue closed' => '',
|
||||
// 'Gitlab webhooks' => '',
|
||||
// 'Help on Gitlab webhooks' => '',
|
||||
// 'Integrations' => '',
|
||||
// 'Integration with third-party services' => '',
|
||||
// 'Role for this project' => '',
|
||||
// 'Project manager' => '',
|
||||
// 'Project member' => '',
|
||||
// 'A project manager can change the settings of the project and have more privileges than a standard user.' => '',
|
||||
// 'Gitlab Issue' => '',
|
||||
// 'Subtask Id' => '',
|
||||
// 'Subtasks' => '',
|
||||
// 'Subtasks Export' => '',
|
||||
// 'Subtasks exportation for "%s"' => '',
|
||||
// 'Task Title' => '',
|
||||
// 'Untitled' => '',
|
||||
// 'Application default' => '',
|
||||
// 'Language:' => '',
|
||||
// 'Timezone:' => '',
|
||||
// 'Next' => '',
|
||||
);
|
||||
|
|
|
@ -182,7 +182,7 @@ return array(
|
|||
'Change assignee' => 'Zmień odpowiedzialną osobę',
|
||||
'Change assignee for the task "%s"' => 'Zmień odpowiedzialną osobę dla zadania "%s"',
|
||||
'Timezone' => 'Strefa czasowa',
|
||||
'Sorry, I didn\'t found this information in my database!' => 'Niestety nie znaleziono tej informacji w bazie danych',
|
||||
'Sorry, I didn\'t find this information in my database!' => 'Niestety nie znaleziono tej informacji w bazie danych',
|
||||
'Page not found' => 'Strona nie istnieje',
|
||||
'Complexity' => 'Poziom trudności',
|
||||
'limit' => 'limit',
|
||||
|
@ -194,7 +194,7 @@ return array(
|
|||
'Allow this user' => 'Dodaj użytkownika',
|
||||
'Only those users have access to this project:' => 'Użytkownicy mający dostęp:',
|
||||
'Don\'t forget that administrators have access to everything.' => 'Pamiętaj: Administratorzy mają zawsze dostęp do wszystkiego!',
|
||||
'revoke' => 'odbierz dostęp',
|
||||
'Revoke' => 'Odbierz dostęp',
|
||||
'List of authorized users' => 'Lista użytkowników mających dostęp',
|
||||
'User' => 'Użytkownik',
|
||||
// 'Nobody have access to this project.' => '',
|
||||
|
@ -213,6 +213,7 @@ return array(
|
|||
'Invalid date' => 'Błędna data',
|
||||
'Must be done before %B %e, %Y' => 'Termin do %e %B %Y',
|
||||
'%B %e, %Y' => '%e %B %Y',
|
||||
// '%b %e, %Y' => '',
|
||||
'Automatic actions' => 'Akcje automatyczne',
|
||||
'Your automatic action have been created successfully.' => 'Twoja akcja została dodana',
|
||||
'Unable to create your automatic action.' => 'Nie udało się utworzyć akcji',
|
||||
|
@ -468,18 +469,18 @@ return array(
|
|||
// 'Unable to change the password.' => '',
|
||||
// 'Change category for the task "%s"' => '',
|
||||
// 'Change category' => '',
|
||||
// '%s updated the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '',
|
||||
// '%s open the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '',
|
||||
// '%s moved the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to the position #%d in the column "%s"' => '',
|
||||
// '%s moved the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to the column "%s"' => '',
|
||||
// '%s created the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '',
|
||||
// '%s closed the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '',
|
||||
// '%s created a subtask for the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '',
|
||||
// '%s updated a subtask for the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '',
|
||||
// '%s updated the task %s' => '',
|
||||
// '%s opened the task %s' => '',
|
||||
// '%s moved the task %s to the position #%d in the column "%s"' => '',
|
||||
// '%s moved the task %s to the column "%s"' => '',
|
||||
// '%s created the task %s' => '',
|
||||
// '%s closed the task %s' => '',
|
||||
// '%s created a subtask for the task %s' => '',
|
||||
// '%s updated a subtask for the task %s' => '',
|
||||
// 'Assigned to %s with an estimate of %s/%sh' => '',
|
||||
// 'Not assigned, estimate of %sh' => '',
|
||||
// '%s updated a comment on the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '',
|
||||
// '%s commented the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '',
|
||||
// '%s updated a comment on the task %s' => '',
|
||||
// '%s commented the task %s' => '',
|
||||
// '%s\'s activity' => '',
|
||||
// 'No activity.' => '',
|
||||
// 'RSS feed' => '',
|
||||
|
@ -498,7 +499,7 @@ return array(
|
|||
// 'Default columns for new projects (Comma-separated)' => '',
|
||||
// 'Task assignee change' => '',
|
||||
// '%s change the assignee of the task #%d to %s' => '',
|
||||
// '%s change the assignee of the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to %s' => '',
|
||||
// '%s changed the assignee of the task %s to %s' => '',
|
||||
// '[%s][Column Change] %s (#%d)' => '',
|
||||
// '[%s][Position Change] %s (#%d)' => '',
|
||||
// '[%s][Assignee Change] %s (#%d)' => '',
|
||||
|
@ -555,8 +556,8 @@ return array(
|
|||
// 'Webhooks' => '',
|
||||
// 'API' => '',
|
||||
// 'Integration' => '',
|
||||
// 'Github webhook' => '',
|
||||
// 'Help on Github webhook' => '',
|
||||
// 'Github webhooks' => '',
|
||||
// 'Help on Github webhooks' => '',
|
||||
// 'Create a comment from an external provider' => '',
|
||||
// 'Github issue comment created' => '',
|
||||
// 'Configure' => '',
|
||||
|
@ -602,4 +603,49 @@ return array(
|
|||
// 'Nothing to preview...' => '',
|
||||
// 'Preview' => '',
|
||||
// 'Write' => '',
|
||||
// 'Active swimlanes' => '',
|
||||
// 'Add a new swimlane' => '',
|
||||
// 'Change default swimlane' => '',
|
||||
// 'Default swimlane' => '',
|
||||
// 'Do you really want to remove this swimlane: "%s"?' => '',
|
||||
// 'Inactive swimlanes' => '',
|
||||
// 'Set project manager' => '',
|
||||
// 'Set project member' => '',
|
||||
// 'Remove a swimlane' => '',
|
||||
// 'Rename' => '',
|
||||
// 'Show default swimlane' => '',
|
||||
// 'Swimlane modification for the project "%s"' => '',
|
||||
// 'Swimlane not found.' => '',
|
||||
// 'Swimlane removed successfully.' => '',
|
||||
// 'Swimlanes' => '',
|
||||
// 'Swimlane updated successfully.' => '',
|
||||
// 'The default swimlane have been updated successfully.' => '',
|
||||
// 'Unable to create your swimlane.' => '',
|
||||
// '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)' => '',
|
||||
// 'Gitlab commit received' => '',
|
||||
// 'Gitlab issue opened' => '',
|
||||
// 'Gitlab issue closed' => '',
|
||||
// 'Gitlab webhooks' => '',
|
||||
// 'Help on Gitlab webhooks' => '',
|
||||
// 'Integrations' => '',
|
||||
// 'Integration with third-party services' => '',
|
||||
// 'Role for this project' => '',
|
||||
// 'Project manager' => '',
|
||||
// 'Project member' => '',
|
||||
// 'A project manager can change the settings of the project and have more privileges than a standard user.' => '',
|
||||
// 'Gitlab Issue' => '',
|
||||
// 'Subtask Id' => '',
|
||||
// 'Subtasks' => '',
|
||||
// 'Subtasks Export' => '',
|
||||
// 'Subtasks exportation for "%s"' => '',
|
||||
// 'Task Title' => '',
|
||||
// 'Untitled' => '',
|
||||
// 'Application default' => '',
|
||||
// 'Language:' => '',
|
||||
// 'Timezone:' => '',
|
||||
// 'Next' => '',
|
||||
);
|
||||
|
|
|
@ -4,8 +4,8 @@ return array(
|
|||
'None' => 'Nenhum',
|
||||
'edit' => 'editar',
|
||||
'Edit' => 'Editar',
|
||||
'remove' => 'apagar',
|
||||
'Remove' => 'Apagar',
|
||||
'remove' => 'remover',
|
||||
'Remove' => 'Remover',
|
||||
'Update' => 'Atualizar',
|
||||
'Yes' => 'Sim',
|
||||
'No' => 'Não',
|
||||
|
@ -14,175 +14,175 @@ return array(
|
|||
'Yellow' => 'Amarelo',
|
||||
'Blue' => 'Azul',
|
||||
'Green' => 'Verde',
|
||||
'Purple' => 'Violeta',
|
||||
'Purple' => 'Roxo',
|
||||
'Red' => 'Vermelho',
|
||||
'Orange' => 'Laranja',
|
||||
'Grey' => 'Cinza',
|
||||
'Save' => 'Salvar',
|
||||
'Login' => 'Login',
|
||||
'Official website:' => 'Site web oficial :',
|
||||
'Official website:' => 'Site oficial:',
|
||||
'Unassigned' => 'Não Atribuída',
|
||||
'View this task' => 'Ver esta tarefa',
|
||||
'Remove user' => 'Remover usuário',
|
||||
'Do you really want to remove this user: "%s"?' => 'Quer realmente remover este usuário: "%s"?',
|
||||
'Do you really want to remove this user: "%s"?' => 'Você realmente deseja remover este usuário: "%s"?',
|
||||
'New user' => 'Novo usuário',
|
||||
'All users' => 'Todos os usuários',
|
||||
'Username' => 'Nome do usuário',
|
||||
'Username' => 'Nome de usuário',
|
||||
'Password' => 'Senha',
|
||||
'Default project' => 'Projeto default',
|
||||
'Default project' => 'Projeto padrão',
|
||||
'Administrator' => 'Administrador',
|
||||
'Sign in' => 'Logar',
|
||||
'Sign in' => 'Entrar',
|
||||
'Users' => 'Usuários',
|
||||
'No user' => 'Sem usuário',
|
||||
'Forbidden' => 'Proibido',
|
||||
'Access Forbidden' => 'Acesso negado',
|
||||
'Only administrators can access to this page.' => 'Somente administradores têm acesso a esta página.',
|
||||
'Edit user' => 'Editar usuário',
|
||||
'Logout' => 'Logout',
|
||||
'Logout' => 'Sair',
|
||||
'Bad username or password' => 'Usuário ou senha inválidos',
|
||||
'users' => 'usuários',
|
||||
'projects' => 'projetos',
|
||||
'Edit project' => 'Editar projeto',
|
||||
'Name' => 'Nome',
|
||||
'Activated' => 'Ativo',
|
||||
'Activated' => 'Ativado',
|
||||
'Projects' => 'Projetos',
|
||||
'No project' => 'Nenhum projeto',
|
||||
'Project' => 'Projeto',
|
||||
'Status' => 'Status',
|
||||
'Tasks' => 'Tarefas',
|
||||
'Board' => 'Quadro',
|
||||
'Board' => 'Board',
|
||||
'Actions' => 'Ações',
|
||||
'Inactive' => 'Inativo',
|
||||
'Active' => 'Ativo',
|
||||
'Column %d' => 'Coluna %d',
|
||||
'Add this column' => 'Adicionar esta coluna',
|
||||
'%d tasks on the board' => '%d tarefas no quadro',
|
||||
'%d tasks on the board' => '%d tarefas no board',
|
||||
'%d tasks in total' => '%d tarefas no total',
|
||||
'Unable to update this board.' => 'Impossível atualizar este quadro.',
|
||||
'Edit board' => 'Modificar quadro',
|
||||
'Unable to update this board.' => 'Não foi possível atualizar este board.',
|
||||
'Edit board' => 'Editar board',
|
||||
'Disable' => 'Desativar',
|
||||
'Enable' => 'Ativar',
|
||||
'New project' => 'Novo projeto',
|
||||
'Do you really want to remove this project: "%s"?' => 'Quer realmente remover este projeto: "%s" ?',
|
||||
'Do you really want to remove this project: "%s"?' => 'Você realmente deseja remover este projeto: "%s" ?',
|
||||
'Remove project' => 'Remover projeto',
|
||||
'Boards' => 'Quadros',
|
||||
'Edit the board for "%s"' => 'Editar o quadro para "%s"',
|
||||
'Boards' => 'Boards',
|
||||
'Edit the board for "%s"' => 'Editar o board para "%s"',
|
||||
'All projects' => 'Todos os projetos',
|
||||
'Change columns' => 'Modificar colunas',
|
||||
'Add a new column' => 'Adicionar uma nova coluna',
|
||||
'Title' => 'Título',
|
||||
'Add Column' => 'Adicionar coluna',
|
||||
'Add Column' => 'Adicionar Coluna',
|
||||
'Project "%s"' => 'Projeto "%s"',
|
||||
'Nobody assigned' => 'Ninguém designado',
|
||||
'Assigned to %s' => 'Designado para %s',
|
||||
'Remove a column' => 'Remover uma coluna',
|
||||
'Remove a column from a board' => 'Remover uma coluna do quadro',
|
||||
'Unable to remove this column.' => 'Impossível remover esta coluna.',
|
||||
'Do you really want to remove this column: "%s"?' => 'Quer realmente remover esta coluna: "%s"?',
|
||||
'This action will REMOVE ALL TASKS associated to this column!' => 'Esta ação vai REMOVER TODAS AS TAREFAS associadas a esta coluna!',
|
||||
'Settings' => 'Preferências',
|
||||
'Application settings' => 'Preferências da aplicação',
|
||||
'Remove a column from a board' => 'Remover uma coluna do board',
|
||||
'Unable to remove this column.' => 'Não foi possível remover esta coluna.',
|
||||
'Do you really want to remove this column: "%s"?' => 'Você realmente deseja remover esta coluna: "%s"?',
|
||||
'This action will REMOVE ALL TASKS associated to this column!' => 'Esta ação irá REMOVER TODAS AS TAREFAS associadas a esta coluna!',
|
||||
'Settings' => 'Configurações',
|
||||
'Application settings' => 'Configurações da aplicação',
|
||||
'Language' => 'Idioma',
|
||||
'Webhook token:' => 'Token de webhooks:',
|
||||
'API token:' => 'API Token:',
|
||||
'More information' => 'Mais informação',
|
||||
'More information' => 'Mais informações',
|
||||
'Database size:' => 'Tamanho do banco de dados:',
|
||||
'Download the database' => 'Download do banco de dados',
|
||||
'Optimize the database' => 'Otimizar o banco de dados',
|
||||
'(VACUUM command)' => '(Comando VACUUM)',
|
||||
'(Gzip compressed Sqlite file)' => '(Arquivo Sqlite comprimido com Gzip)',
|
||||
'User settings' => 'Configurações do usuário',
|
||||
'My default project:' => 'Meu projeto default:',
|
||||
'Close a task' => 'Encerrar uma tarefa',
|
||||
'Do you really want to close this task: "%s"?' => 'Quer realmente encerrar esta tarefa: "%s"?',
|
||||
'My default project:' => 'Meu projeto padrão:',
|
||||
'Close a task' => 'Finalizar uma tarefa',
|
||||
'Do you really want to close this task: "%s"?' => 'Você realmente deseja finalizar esta tarefa: "%s"?',
|
||||
'Edit a task' => 'Editar uma tarefa',
|
||||
'Column' => 'Coluna',
|
||||
'Color' => 'Cor',
|
||||
'Assignee' => 'Designação',
|
||||
'Create another task' => 'Criar uma outra tarefa (aproveitando os dados preenchidos)',
|
||||
'Create another task' => 'Criar outra tarefa',
|
||||
'New task' => 'Nova tarefa',
|
||||
'Open a task' => 'Abrir uma tarefa',
|
||||
'Do you really want to open this task: "%s"?' => 'Quer realmente abrir esta tarefa: "%s"?',
|
||||
'Back to the board' => 'Voltar ao quadro',
|
||||
'Do you really want to open this task: "%s"?' => 'Você realmente deseja abrir esta tarefa: "%s"?',
|
||||
'Back to the board' => 'Voltar ao board',
|
||||
'Created on %B %e, %Y at %k:%M %p' => 'Criado em %d %B %Y às %H:%M',
|
||||
'There is nobody assigned' => 'Não há ninguém designado',
|
||||
'Column on the board:' => 'Coluna no quadro:',
|
||||
'Column on the board:' => 'Coluna no board:',
|
||||
'Status is open' => 'Status está aberto',
|
||||
'Status is closed' => 'Status está encerrado',
|
||||
'Close this task' => 'Encerrar esta tarefa',
|
||||
'Status is closed' => 'Status está finalizado',
|
||||
'Close this task' => 'Finalizar esta tarefa',
|
||||
'Open this task' => 'Abrir esta tarefa',
|
||||
'There is no description.' => 'Não há descrição.',
|
||||
'Add a new task' => 'Adicionar uma nova tarefa',
|
||||
'The username is required' => 'O nome de usuário é obrigatório',
|
||||
'The maximum length is %d characters' => 'O tamanho máximo são %d caracteres',
|
||||
'The minimum length is %d characters' => 'O tamanho mínimo são %d caracteres',
|
||||
'The maximum length is %d characters' => 'O tamanho máximo é %d caracteres',
|
||||
'The minimum length is %d characters' => 'O tamanho mínimo é %d caracteres',
|
||||
'The password is required' => 'A senha é obrigatória',
|
||||
'This value must be an integer' => 'O valor deve ser um inteiro',
|
||||
'This value must be an integer' => 'O valor deve ser um número inteiro',
|
||||
'The username must be unique' => 'O nome de usuário deve ser único',
|
||||
'The username must be alphanumeric' => 'O nome de usuário deve ser alfanumérico, sem espaços ou _',
|
||||
'The user id is required' => 'O id de usuário é obrigatório',
|
||||
'Passwords don\'t match' => 'As senhas não conferem',
|
||||
'The username must be alphanumeric' => 'O nome de usuário deve ser alfanumérico',
|
||||
'The user id is required' => 'O ID de usuário é obrigatório',
|
||||
'Passwords don\'t match' => 'As senhas não coincidem',
|
||||
'The confirmation is required' => 'A confirmação é obrigatória',
|
||||
'The column is required' => 'A coluna é obrigatória',
|
||||
'The project is required' => 'O projeto é obrigatório',
|
||||
'The color is required' => 'A cor é obrigatória',
|
||||
'The id is required' => 'O id é obrigatório',
|
||||
'The project id is required' => 'O id do projeto é obrigatório',
|
||||
'The id is required' => 'O ID é obrigatório',
|
||||
'The project id is required' => 'O ID do projeto é obrigatório',
|
||||
'The project name is required' => 'O nome do projeto é obrigatório',
|
||||
'This project must be unique' => 'Este projeto deve ser único',
|
||||
'The title is required' => 'O título é obrigatório',
|
||||
'The language is required' => 'O idioma é obrigatório',
|
||||
'There is no active project, the first step is to create a new project.' => 'Não há projeto ativo. O primeiro passo é criar um novo projeto.',
|
||||
'Settings saved successfully.' => 'Configurações salvas com sucesso.',
|
||||
'Unable to save your settings.' => 'Impossível salvar suas configurações.',
|
||||
'Database optimization done.' => 'Otimização do banco de dados terminada.',
|
||||
'Unable to save your settings.' => 'Não é possível salvar suas configurações.',
|
||||
'Database optimization done.' => 'Otimização do banco de dados finalizada.',
|
||||
'Your project have been created successfully.' => 'Seu projeto foi criado com sucesso.',
|
||||
'Unable to create your project.' => 'Impossível criar seu projeto.',
|
||||
'Unable to create your project.' => 'Não é possível criar o seu projeto.',
|
||||
'Project updated successfully.' => 'Projeto atualizado com sucesso.',
|
||||
'Unable to update this project.' => 'Impossível atualizar este projeto.',
|
||||
'Unable to remove this project.' => 'Impossível remover este projeto.',
|
||||
'Unable to update this project.' => 'Não é possível atualizar este projeto.',
|
||||
'Unable to remove this project.' => 'Não é possível remover este projeto.',
|
||||
'Project removed successfully.' => 'Projeto removido com sucesso.',
|
||||
'Project activated successfully.' => 'Projeto ativado com sucesso.',
|
||||
'Unable to activate this project.' => 'Impossível ativar este projeto.',
|
||||
'Project disabled successfully.' => 'Projeto desabilitado com sucesso.',
|
||||
'Unable to disable this project.' => 'Impossível desabilitar este projeto.',
|
||||
'Unable to open this task.' => 'Impossível abrir esta tarefa.',
|
||||
'Unable to activate this project.' => 'Não é possível ativar este projeto.',
|
||||
'Project disabled successfully.' => 'Projeto desativado com sucesso.',
|
||||
'Unable to disable this project.' => 'Não é possível desativar este projeto.',
|
||||
'Unable to open this task.' => 'Não é possível abrir esta tarefa.',
|
||||
'Task opened successfully.' => 'Tarefa aberta com sucesso.',
|
||||
'Unable to close this task.' => 'Impossível encerrar esta tarefa.',
|
||||
'Task closed successfully.' => 'Tarefa encerrada com sucesso.',
|
||||
'Unable to update your task.' => 'Impossível atualizar sua tarefa.',
|
||||
'Unable to close this task.' => 'Não é possível finalizar esta tarefa.',
|
||||
'Task closed successfully.' => 'Tarefa finalizada com sucesso.',
|
||||
'Unable to update your task.' => 'Não é possível atualizar a sua tarefa.',
|
||||
'Task updated successfully.' => 'Tarefa atualizada com sucesso.',
|
||||
'Unable to create your task.' => 'Impossível criar sua tarefa.',
|
||||
'Unable to create your task.' => 'Não é possível criar a sua tarefa.',
|
||||
'Task created successfully.' => 'Tarefa criada com sucesso.',
|
||||
'User created successfully.' => 'Usuário criado com sucesso.',
|
||||
'Unable to create your user.' => 'Impossível criar seu usuário.',
|
||||
'Unable to create your user.' => 'Não é possível criar o seu usuário.',
|
||||
'User updated successfully.' => 'Usuário atualizado com sucesso.',
|
||||
'Unable to update your user.' => 'Impossível atualizar seu usuário.',
|
||||
'Unable to update your user.' => 'Não é possível atualizar o seu usuário.',
|
||||
'User removed successfully.' => 'Usuário removido com sucesso.',
|
||||
'Unable to remove this user.' => 'Impossível remover este usuário.',
|
||||
'Board updated successfully.' => 'Quadro atualizado com sucesso.',
|
||||
'Unable to remove this user.' => 'Não é possível remover este usuário.',
|
||||
'Board updated successfully.' => 'Board atualizado com sucesso.',
|
||||
'Ready' => 'Pronto',
|
||||
'Backlog' => 'Backlog',
|
||||
'Work in progress' => 'Em andamento',
|
||||
'Done' => 'Encerrado',
|
||||
'Done' => 'Finalizado',
|
||||
'Application version:' => 'Versão da aplicação:',
|
||||
'Completed on %B %e, %Y at %k:%M %p' => 'Encerrado em %d %B %Y às %H:%M',
|
||||
'Completed on %B %e, %Y at %k:%M %p' => 'Finalizado em %d %B %Y às %H:%M',
|
||||
'%B %e, %Y at %k:%M %p' => '%d %B %Y às %H:%M',
|
||||
'Date created' => 'Data de criação',
|
||||
'Date completed' => 'Data de encerramento',
|
||||
'Date completed' => 'Data da finalização',
|
||||
'Id' => 'Id',
|
||||
'No task' => 'Nenhuma tarefa',
|
||||
'Completed tasks' => 'tarefas completadas',
|
||||
'Completed tasks' => 'Tarefas completadas',
|
||||
'List of projects' => 'Lista de projetos',
|
||||
'Completed tasks for "%s"' => 'Tarefas completadas por "%s"',
|
||||
'%d closed tasks' => '%d tarefas encerradas',
|
||||
'No task for this project' => 'Nenhuma tarefa para este projeto',
|
||||
'%d closed tasks' => '%d tarefas finalizadas',
|
||||
'No task for this project' => 'Não há tarefa para este projeto',
|
||||
'Public link' => 'Link público',
|
||||
'There is no column in your project!' => 'Não há colunas no seu projeto!',
|
||||
'Change assignee' => 'Mudar a designação',
|
||||
'Change assignee for the task "%s"' => 'Modificar designação para a tarefa "%s"',
|
||||
'Timezone' => 'Fuso horário',
|
||||
'Sorry, I didn\'t found this information in my database!' => 'Desculpe, não encontrei esta informação no meu banco de dados!',
|
||||
'Sorry, I didn\'t find this information in my database!' => 'Desculpe, não encontrei esta informação no meu banco de dados!',
|
||||
'Page not found' => 'Página não encontrada',
|
||||
'Complexity' => 'Complexidade',
|
||||
'limit' => 'limite',
|
||||
|
@ -191,10 +191,10 @@ return array(
|
|||
'This value must be greater than %d' => 'Este valor deve ser maior que %d',
|
||||
'Edit project access list' => 'Editar lista de acesso ao projeto',
|
||||
'Edit users access' => 'Editar acesso de usuários',
|
||||
'Allow this user' => 'Permitir esse usuário',
|
||||
'Only those users have access to this project:' => 'Somente estes usuários têm acesso a este projeto:',
|
||||
'Allow this user' => 'Permitir este usuário',
|
||||
'Only those users have access to this project:' => 'Somente esses usuários têm acesso a este projeto:',
|
||||
'Don\'t forget that administrators have access to everything.' => 'Não esqueça que administradores têm acesso a tudo.',
|
||||
'revoke' => 'revogar',
|
||||
'Revoke' => 'Revogar',
|
||||
'List of authorized users' => 'Lista de usuários autorizados',
|
||||
'User' => 'Usuário',
|
||||
'Nobody have access to this project.' => 'Ninguém tem acesso a este projeto.',
|
||||
|
@ -205,19 +205,20 @@ return array(
|
|||
'Leave a comment' => 'Deixe um comentário',
|
||||
'Comment is required' => 'Comentário é obrigatório',
|
||||
'Leave a description' => 'Deixe uma descrição',
|
||||
'Comment added successfully.' => 'Cpmentário adicionado com sucesso.',
|
||||
'Unable to create your comment.' => 'Impossível criar seu comentário.',
|
||||
'Comment added successfully.' => 'Comentário adicionado com sucesso.',
|
||||
'Unable to create your comment.' => 'Não é possível criar o seu comentário.',
|
||||
'The description is required' => 'A descrição é obrigatória',
|
||||
'Edit this task' => 'Editar esta tarefa',
|
||||
'Due Date' => 'Data de vencimento',
|
||||
'Invalid date' => 'Data inválida',
|
||||
'Must be done before %B %e, %Y' => 'Deve ser feito antes de %d %B %Y',
|
||||
'Must be done before %B %e, %Y' => 'Deve ser finalizado antes de %d %B %Y',
|
||||
'%B %e, %Y' => '%d %B %Y',
|
||||
'%b %e, %Y' => '%d %B %Y',
|
||||
'Automatic actions' => 'Ações automáticas',
|
||||
'Your automatic action have been created successfully.' => 'Sua ação automética foi criada com sucesso.',
|
||||
'Unable to create your automatic action.' => 'Impossível criar sua ação automática.',
|
||||
'Unable to create your automatic action.' => 'Não é possível criar sua ação automática.',
|
||||
'Remove an action' => 'Remover uma ação',
|
||||
'Unable to remove this action.' => 'Impossível remover esta ação.',
|
||||
'Unable to remove this action.' => 'Não é possível remover esta ação.',
|
||||
'Action removed successfully.' => 'Ação removida com sucesso.',
|
||||
'Automatic actions for the project "%s"' => 'Ações automáticas para o projeto "%s"',
|
||||
'Defined actions' => 'Ações definidas',
|
||||
|
@ -227,22 +228,22 @@ return array(
|
|||
'Action parameters' => 'Parâmetros da ação',
|
||||
'Action' => 'Ação',
|
||||
'Event' => 'Evento',
|
||||
'When the selected event occurs execute the corresponding action.' => 'Quando o evento selecionado ocorrer, execute a ação correspondente.',
|
||||
'When the selected event occurs execute the corresponding action.' => 'Quando o evento selecionado ocorrer execute a ação correspondente.',
|
||||
'Next step' => 'Próximo passo',
|
||||
'Define action parameters' => 'Definir parêmetros da ação',
|
||||
'Save this action' => 'Salvar esta ação',
|
||||
'Do you really want to remove this action: "%s"?' => 'Você quer realmente remover esta ação: "%s"?',
|
||||
'Remove an automatic action' => 'Remove uma ação automática',
|
||||
'Close the task' => 'Encerrar tarefa',
|
||||
'Do you really want to remove this action: "%s"?' => 'Você realmente deseja remover esta ação: "%s"?',
|
||||
'Remove an automatic action' => 'Remover uma ação automática',
|
||||
'Close the task' => 'Finalizar tarefa',
|
||||
'Assign the task to a specific user' => 'Designar a tarefa para um usuário específico',
|
||||
'Assign the task to the person who does the action' => 'Designar a tarefa para a pessoa que executa a ação',
|
||||
'Duplicate the task to another project' => 'Duplicar a tarefa para um outro projeto',
|
||||
'Move a task to another column' => 'Mover a tarefa para outra coluna',
|
||||
'Move a task to another position in the same column' => 'Mover a tarefa para outra posição, na mesma coluna',
|
||||
'Move a task to another position in the same column' => 'Mover a tarefa para outra posição na mesma coluna',
|
||||
'Task modification' => 'Modificação de tarefa',
|
||||
'Task creation' => 'Criação de tarefa',
|
||||
'Open a closed task' => 'Reabrir uma tarefa encerrada',
|
||||
'Closing a task' => 'Encerrando uma tarefa',
|
||||
'Open a closed task' => 'Reabrir uma tarefa finalizada',
|
||||
'Closing a task' => 'Finalizando uma tarefa',
|
||||
'Assign a color to a specific user' => 'Designar uma cor para um usuário específico',
|
||||
'Column title' => 'Título da coluna',
|
||||
'Position' => 'Posição',
|
||||
|
@ -253,26 +254,26 @@ return array(
|
|||
'link' => 'link',
|
||||
'Update this comment' => 'Atualizar este comentário',
|
||||
'Comment updated successfully.' => 'Comentário atualizado com sucesso.',
|
||||
'Unable to update your comment.' => 'Impossível atualizar seu comentário.',
|
||||
'Unable to update your comment.' => 'Não é possível atualizar o seu comentário.',
|
||||
'Remove a comment' => 'Remover um comentário',
|
||||
'Comment removed successfully.' => 'Comentário removido com sucesso.',
|
||||
'Unable to remove this comment.' => 'Impossível remover este comentário.',
|
||||
'Do you really want to remove this comment?' => 'Você tem certeza de que quer remover este comentário?',
|
||||
'Only administrators or the creator of the comment can access to this page.' => 'Somente administradores ou o criator deste comentário tem acesso a esta página.',
|
||||
'Unable to remove this comment.' => 'Não é possível remover este comentário.',
|
||||
'Do you really want to remove this comment?' => 'Você realmente deseja remover este comentário?',
|
||||
'Only administrators or the creator of the comment can access to this page.' => 'Somente os administradores ou o criator deste comentário possuem acesso a esta página.',
|
||||
'Details' => 'Detalhes',
|
||||
'Current password for the user "%s"' => 'Senha atual para o usuário "%s"',
|
||||
'The current password is required' => 'A senha atual é obrigatória',
|
||||
'Wrong password' => 'Senha errada',
|
||||
'Reset all tokens' => 'Reiniciar todos os tokens',
|
||||
'Wrong password' => 'Senha incorreta',
|
||||
'Reset all tokens' => 'Resetar todos os tokens',
|
||||
'All tokens have been regenerated.' => 'Todos os tokens foram gerados novamente.',
|
||||
'Unknown' => 'Desconhecido',
|
||||
'Last logins' => 'Últimos logins',
|
||||
'Login date' => 'Data de login',
|
||||
'Authentication method' => 'Método de autenticação',
|
||||
'IP address' => 'Endereço IP',
|
||||
'User agent' => 'Agente usuário',
|
||||
'User agent' => 'User Agent',
|
||||
'Persistent connections' => 'Conexões persistentes',
|
||||
'No session.' => 'Sem sessão.',
|
||||
'No session.' => 'Nenhuma sessão.',
|
||||
'Expiration date' => 'Data de expiração',
|
||||
'Remember Me' => 'Lembre-se de mim',
|
||||
'Creation date' => 'Data de criação',
|
||||
|
@ -280,25 +281,25 @@ return array(
|
|||
'Filter by due date' => 'Filtrar por data de vencimento',
|
||||
'Everybody' => 'Todos',
|
||||
'Open' => 'Abrir',
|
||||
'Closed' => 'Encerrado',
|
||||
'Closed' => 'Finalizado',
|
||||
'Search' => 'Pesquisar',
|
||||
'Nothing found.' => 'Não encontrado.',
|
||||
'Search in the project "%s"' => 'Procure no projeto "%s"',
|
||||
'Nothing found.' => 'Nada foi encontrado.',
|
||||
'Search in the project "%s"' => 'Pesquisar no projeto "%s"',
|
||||
'Due date' => 'Data de vencimento',
|
||||
'Others formats accepted: %s and %s' => 'Outros formatos permitidos: %s e %s',
|
||||
'Description' => 'Descrição',
|
||||
'%d comments' => '%d comentários',
|
||||
'%d comment' => '%d comentário',
|
||||
'Email address invalid' => 'Endereço de e-mail inválido',
|
||||
'Your Google Account is not linked anymore to your profile.' => 'Sua conta Google não está mais associada ao seu perfil.',
|
||||
'Unable to unlink your Google Account.' => 'Impossível desassociar sua conta Google.',
|
||||
'Your Google Account is not linked anymore to your profile.' => 'Sua conta do Google não está mais associada ao seu perfil.',
|
||||
'Unable to unlink your Google Account.' => 'Não foi possível desassociar a sua Conta do Google.',
|
||||
'Google authentication failed' => 'Autenticação do Google falhou.',
|
||||
'Unable to link your Google Account.' => 'Impossível associar a sua conta do Google.',
|
||||
'Your Google Account is linked to your profile successfully.' => 'Sua Conta do Google está ligada ao seu perfil com sucesso.',
|
||||
'Unable to link your Google Account.' => 'Não foi possível associar a sua Conta do Google.',
|
||||
'Your Google Account is linked to your profile successfully.' => 'Sua Conta do Google foi associada ao seu perfil com sucesso.',
|
||||
'Email' => 'E-mail',
|
||||
'Link my Google Account' => 'Vincular minha conta Google',
|
||||
'Unlink my Google Account' => 'Desvincular minha conta do Google',
|
||||
'Login with my Google Account' => 'Entrar com minha conta do Google',
|
||||
'Link my Google Account' => 'Vincular minha Conta do Google',
|
||||
'Unlink my Google Account' => 'Desvincular minha Conta do Google',
|
||||
'Login with my Google Account' => 'Entrar com minha Conta do Google',
|
||||
'Project not found.' => 'Projeto não encontrado.',
|
||||
'Task #%d' => 'Tarefa #%d',
|
||||
'Task removed successfully.' => 'Tarefa removida com sucesso.',
|
||||
|
@ -312,8 +313,8 @@ return array(
|
|||
'Category:' => 'Categoria:',
|
||||
'Categories' => 'Categorias',
|
||||
'Category not found.' => 'Categoria não encontrada.',
|
||||
'Your category have been created successfully.' => 'Seu categoria foi criada com sucesso.',
|
||||
'Unable to create your category.' => 'Não é possível criar sua categoria.',
|
||||
'Your category have been created successfully.' => 'Sua categoria foi criada com sucesso.',
|
||||
'Unable to create your category.' => 'Não foi possível criar a sua categoria.',
|
||||
'Your category have been updated successfully.' => 'A sua categoria foi atualizada com sucesso.',
|
||||
'Unable to update your category.' => 'Não foi possível atualizar a sua categoria.',
|
||||
'Remove a category' => 'Remover uma categoria',
|
||||
|
@ -326,7 +327,7 @@ return array(
|
|||
'Do you really want to remove this category: "%s"?' => 'Você realmente deseja remover esta categoria: "%s"',
|
||||
'Filter by category' => 'Filtrar por categoria',
|
||||
'All categories' => 'Todas as categorias',
|
||||
'No category' => 'Sem categoria',
|
||||
'No category' => 'Nenhum categoria',
|
||||
'The name is required' => 'O nome é obrigatório',
|
||||
'Remove a file' => 'Remover um arquivo',
|
||||
'Unable to remove this file.' => 'Não foi possível remover este arquivo.',
|
||||
|
@ -343,60 +344,60 @@ return array(
|
|||
'Time tracking' => 'Rastreamento de tempo',
|
||||
'Estimate:' => 'Estimado:',
|
||||
'Spent:' => 'Gasto:',
|
||||
'Do you really want to remove this sub-task?' => 'Você realmente deseja remover esta sub-tarefa?',
|
||||
'Do you really want to remove this sub-task?' => 'Você realmente deseja remover esta subtarefa?',
|
||||
'Remaining:' => 'Restante:',
|
||||
'hours' => 'horas',
|
||||
'spent' => 'gasto',
|
||||
'estimated' => 'estimada',
|
||||
'Sub-Tasks' => 'Sub-tarefas',
|
||||
'Add a sub-task' => 'Adicionar uma sub-tarefa',
|
||||
'estimated' => 'estimado',
|
||||
'Sub-Tasks' => 'Subtarefas',
|
||||
'Add a sub-task' => 'Adicionar uma subtarefa',
|
||||
'Original estimate' => 'Estimativa original',
|
||||
'Create another sub-task' => 'Criar uma outra sub-tarefa',
|
||||
'Create another sub-task' => 'Criar uma outra subtarefa',
|
||||
'Time spent' => 'Tempo gasto',
|
||||
'Edit a sub-task' => 'Editar uma sub-tarefa',
|
||||
'Remove a sub-task' => 'Remover uma sub-tarefa',
|
||||
'Edit a sub-task' => 'Editar uma subtarefa',
|
||||
'Remove a sub-task' => 'Remover uma subtarefa',
|
||||
'The time must be a numeric value' => 'O tempo deve ser um valor numérico',
|
||||
'Todo' => 'A fazer',
|
||||
'Todo' => 'À fazer',
|
||||
'In progress' => 'Em andamento',
|
||||
'Sub-task removed successfully.' => 'Sub-tarefa removido com sucesso.',
|
||||
'Unable to remove this sub-task.' => 'Não foi possível remover esta sub-tarefa.',
|
||||
'Sub-task updated successfully.' => 'Sub-tarefa atualizada com sucesso.',
|
||||
'Unable to update your sub-task.' => 'Não foi possível atualizar sua sub-tarefa.',
|
||||
'Unable to create your sub-task.' => 'Não é possível criar sua sub-tarefa.',
|
||||
'Sub-task added successfully.' => 'Sub-tarefa adicionada com sucesso.',
|
||||
'Maximum size: ' => 'O tamanho máximo:',
|
||||
'Sub-task removed successfully.' => 'Subtarefa removida com sucesso.',
|
||||
'Unable to remove this sub-task.' => 'Não foi possível remover esta subtarefa.',
|
||||
'Sub-task updated successfully.' => 'Subtarefa atualizada com sucesso.',
|
||||
'Unable to update your sub-task.' => 'Não foi possível atualizar a sua subtarefa.',
|
||||
'Unable to create your sub-task.' => 'Não é possível criar a sua subtarefa.',
|
||||
'Sub-task added successfully.' => 'Subtarefa adicionada com sucesso.',
|
||||
'Maximum size: ' => 'Tamanho máximo:',
|
||||
'Unable to upload the file.' => 'Não foi possível carregar o arquivo.',
|
||||
'Display another project' => 'Mostrar um outro projeto',
|
||||
'Your GitHub account was successfully linked to your profile.' => 'A sua conta GitHub foi ligada com sucesso ao seu perfil.',
|
||||
'Unable to link your GitHub Account.' => 'Não foi possível vincular sua conta GitHub.',
|
||||
'GitHub authentication failed' => 'Falhou autenticação GitHub',
|
||||
'Your GitHub account is no longer linked to your profile.' => 'A sua conta GitHub já não está ligada ao seu perfil.',
|
||||
'Unable to unlink your GitHub Account.' => 'Não foi possível desvincular sua conta GitHub.',
|
||||
'Login with my GitHub Account' => 'Entrar com minha conta do GitHub',
|
||||
'Link my GitHub Account' => 'Vincular minha conta GitHub',
|
||||
'Unlink my GitHub Account' => 'Desvincular minha conta do GitHub',
|
||||
'Display another project' => 'Exibir outro projeto',
|
||||
'Your GitHub account was successfully linked to your profile.' => 'A sua Conta do GitHub foi associada com sucesso ao seu perfil.',
|
||||
'Unable to link your GitHub Account.' => 'Não foi possível associar sua Conta do GitHub.',
|
||||
'GitHub authentication failed' => 'Autenticação do GitHub falhou',
|
||||
'Your GitHub account is no longer linked to your profile.' => 'A sua Conta do GitHub não está mais associada ao seu perfil.',
|
||||
'Unable to unlink your GitHub Account.' => 'Não foi possível desassociar a sua Conta do GitHub.',
|
||||
'Login with my GitHub Account' => 'Entrar com minha Conta do GitHub',
|
||||
'Link my GitHub Account' => 'Associar à minha Conta do GitHub',
|
||||
'Unlink my GitHub Account' => 'Desassociar a minha Conta do GitHub',
|
||||
'Created by %s' => 'Criado por %s',
|
||||
'Last modified on %B %e, %Y at %k:%M %p' => 'Última modificação em %B %e, %Y às %k: %M %p',
|
||||
'Tasks Export' => 'Tarefas Export',
|
||||
'Tasks exportation for "%s"' => 'Tarefas exportação para "%s"',
|
||||
'Tasks Export' => 'Exportar Tarefas',
|
||||
'Tasks exportation for "%s"' => 'As tarefas foram exportadas para "%s"',
|
||||
'Start Date' => 'Data inicial',
|
||||
'End Date' => 'Data final',
|
||||
'Execute' => 'Executar',
|
||||
'Task Id' => 'Id da Tarefa',
|
||||
'Creator' => 'Criador',
|
||||
'Modification date' => 'Data de modificação',
|
||||
'Completion date' => 'Data de conclusão',
|
||||
'Task Id' => 'ID da Tarefa',
|
||||
'Creator' => 'Criado por',
|
||||
'Modification date' => 'Data da modificação',
|
||||
'Completion date' => 'Data da finalização',
|
||||
'Webhook URL for task creation' => 'Webhook URL para criação de tarefas',
|
||||
'Webhook URL for task modification' => 'Webhook URL para modificação tarefa',
|
||||
'Clone' => 'Clone',
|
||||
'Webhook URL for task modification' => 'Webhook URL para modificação de tarefa',
|
||||
'Clone' => 'Clonar',
|
||||
'Clone Project' => 'Clonar Projeto',
|
||||
'Project cloned successfully.' => 'Projeto clonado com sucesso.',
|
||||
'Unable to clone this project.' => 'Impossível clonar este projeto.',
|
||||
'Unable to clone this project.' => 'Não foi possível clonar este projeto.',
|
||||
'Email notifications' => 'Notificações por email',
|
||||
'Enable email notifications' => 'Habilitar notificações por email',
|
||||
'Task position:' => 'Posição da tarefa:',
|
||||
'The task #%d have been opened.' => 'A tarefa #%d foi aberta.',
|
||||
'The task #%d have been closed.' => 'A tarefa #%d foi encerrada.',
|
||||
'The task #%d have been closed.' => 'A tarefa #%d foi finalizada.',
|
||||
'Sub-task updated' => 'Subtarefa atualizada',
|
||||
'Title:' => 'Título:',
|
||||
'Status:' => 'Status:',
|
||||
|
@ -407,18 +408,18 @@ return array(
|
|||
'Comment updated' => 'Comentário atualizado',
|
||||
'New comment posted by %s' => 'Novo comentário postado por %s',
|
||||
'List of due tasks for the project "%s"' => 'Lista de tarefas pendentes para o projeto "%s"',
|
||||
// '[%s][New attachment] %s (#%d)' => '',
|
||||
// '[%s][New comment] %s (#%d)' => '',
|
||||
// '[%s][Comment updated] %s (#%d)' => '',
|
||||
// '[%s][New subtask] %s (#%d)' => '',
|
||||
// '[%s][Subtask updated] %s (#%d)' => '',
|
||||
// '[%s][New task] %s (#%d)' => '',
|
||||
// '[%s][Task updated] %s (#%d)' => '',
|
||||
// '[%s][Task closed] %s (#%d)' => '',
|
||||
// '[%s][Task opened] %s (#%d)' => '',
|
||||
// '[%s][Due tasks]' => '',
|
||||
'[%s][New attachment] %s (#%d)' => '[%s][Novo anexo] %s (#%d)',
|
||||
'[%s][New comment] %s (#%d)' => '[%s][Novo comentário] %s (#%d)',
|
||||
'[%s][Comment updated] %s (#%d)' => '[%s][Comentário atualizado] %s (#%d)',
|
||||
'[%s][New subtask] %s (#%d)' => '[%s][Nova subtarefa] %s (#%d)',
|
||||
'[%s][Subtask updated] %s (#%d)' => '[%s][Subtarefa atualizada] %s (#%d)',
|
||||
'[%s][New task] %s (#%d)' => '[%s][Nova tarefa] %s (#%d)',
|
||||
'[%s][Task updated] %s (#%d)' => '[%s][Tarefa atualizada] %s (#%d)',
|
||||
'[%s][Task closed] %s (#%d)' => '[%s][Tarefa finalizada] %s (#%d)',
|
||||
'[%s][Task opened] %s (#%d)' => '[%s][Tarefa aberta] %s (#%d)',
|
||||
'[%s][Due tasks]' => '[%s][Tarefas pendentes]',
|
||||
'[Kanboard] Notification' => '[Kanboard] Notificação',
|
||||
'I want to receive notifications only for those projects:' => 'Quero receber notificações somente para estes projetos:',
|
||||
'I want to receive notifications only for those projects:' => 'Quero receber notificações apenas destes projetos:',
|
||||
'view the task on Kanboard' => 'ver a tarefa no Kanboard',
|
||||
'Public access' => 'Acesso público',
|
||||
'Category management' => 'Gerenciamento de categorias',
|
||||
|
@ -429,17 +430,17 @@ return array(
|
|||
'Active projects' => 'Projetos ativos',
|
||||
'Inactive projects' => 'Projetos inativos',
|
||||
'Public access disabled' => 'Acesso público desabilitado',
|
||||
'Do you really want to disable this project: "%s"?' => 'Deseja ralmente desabilitar este projeto: "%s"?',
|
||||
'Do you really want to duplicate this project: "%s"?' => 'Deseja realmente duplicar este projeto: "%s"?',
|
||||
'Do you really want to enable this project: "%s"?' => 'Deseja realmente habilitar este projeto: "%s"?',
|
||||
'Project activation' => 'Avaliação do projeto',
|
||||
'Do you really want to disable this project: "%s"?' => 'Você realmente deseja desabilitar este projeto: "%s"?',
|
||||
'Do you really want to duplicate this project: "%s"?' => 'Você realmente deseja duplicar este projeto: "%s"?',
|
||||
'Do you really want to enable this project: "%s"?' => 'Você realmente deseja habilitar este projeto: "%s"?',
|
||||
'Project activation' => 'Ativação do projeto',
|
||||
'Move the task to another project' => 'Mover a tarefa para outro projeto',
|
||||
'Move to another project' => 'Mover para outro projeto',
|
||||
'Do you really want to duplicate this task?' => 'Deseja realmente duplicar esta tarefa?',
|
||||
'Duplicate a task' => 'Duplicar tarefa',
|
||||
'Do you really want to duplicate this task?' => 'Você realmente deseja duplicar esta tarefa?',
|
||||
'Duplicate a task' => 'Duplicar uma tarefa',
|
||||
'External accounts' => 'Contas externas',
|
||||
'Account type' => 'Tipo de conta',
|
||||
// 'Local' => '',
|
||||
'Local' => 'Local',
|
||||
'Remote' => 'Remoto',
|
||||
'Enabled' => 'Habilitado',
|
||||
'Disabled' => 'Desabilitado',
|
||||
|
@ -447,12 +448,12 @@ return array(
|
|||
'Github account linked' => 'Conta do Github associada',
|
||||
'Username:' => 'Usuário:',
|
||||
'Name:' => 'Nome:',
|
||||
// 'Email:' => '',
|
||||
'Email:' => 'E-mail:',
|
||||
'Default project:' => 'Projeto padrão:',
|
||||
'Notifications:' => 'Notificações:',
|
||||
'Notifications' => 'Notificações',
|
||||
'Group:' => 'Groupo:',
|
||||
'Regular user' => 'Usuário habitual',
|
||||
'Group:' => 'Grupo:',
|
||||
'Regular user' => 'Usuário comum',
|
||||
'Account type:' => 'Tipo de conta:',
|
||||
'Edit profile' => 'Editar perfil',
|
||||
'Change password' => 'Alterar senha',
|
||||
|
@ -463,33 +464,33 @@ return array(
|
|||
'Never connected.' => 'Nunca conectado.',
|
||||
'No account linked.' => 'Nenhuma conta associada.',
|
||||
'Account linked.' => 'Conta associada.',
|
||||
'No external authentication enabled.' => 'Nenhuma autenticação externa permitida.',
|
||||
'No external authentication enabled.' => 'Nenhuma autenticação externa habilitada.',
|
||||
'Password modified successfully.' => 'Senha alterada com sucesso.',
|
||||
'Unable to change the password.' => 'Não foi possível alterar a senha.',
|
||||
'Change category for the task "%s"' => 'Mudar categoria para a tarefa "%s"',
|
||||
'Change category for the task "%s"' => 'Mudar categoria da tarefa "%s"',
|
||||
'Change category' => 'Mudar categoria',
|
||||
// '%s updated the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '',
|
||||
// '%s open the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '',
|
||||
// '%s moved the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to the position #%d in the column "%s"' => '',
|
||||
// '%s moved the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to the column "%s"' => '',
|
||||
// '%s created the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '',
|
||||
// '%s closed the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '',
|
||||
'%s created a subtask for the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s criou uma sub-tarefa para a tarefa <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s updated a subtask for the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s atualizou uma sub-tarefa da tarefa <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s updated the task %s' => '%s atualizou a tarefa %s',
|
||||
'%s opened the task %s' => '%s abriu a tarefa %s',
|
||||
'%s moved the task %s to the position #%d in the column "%s"' => '%s moveu a tarefa %s para a posição #%d na coluna "%s"',
|
||||
'%s moved the task %s to the column "%s"' => '%s moveu a tarefa %s para a coluna "%s"',
|
||||
'%s created the task %s' => '%s criou a tarefa %s',
|
||||
'%s closed the task %s' => '%s finalizou a tarefa %s',
|
||||
'%s created a subtask for the task %s' => '%s criou uma subtarefa para a tarefa %s',
|
||||
'%s updated a subtask for the task %s' => '%s atualizou uma subtarefa da tarefa %s',
|
||||
'Assigned to %s with an estimate of %s/%sh' => 'Designado para %s com tempo estimado de %s/%sh',
|
||||
'Not assigned, estimate of %sh' => 'Não designado, estimado em %sh',
|
||||
'%s updated a comment on the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s atualizou o comentário na tarefa <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s commented the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s comentou a tarefa <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s updated a comment on the task %s' => '%s atualizou o comentário na tarefa %s',
|
||||
'%s commented the task %s' => '%s comentou a tarefa %s',
|
||||
'%s\'s activity' => 'Atividades de%s',
|
||||
'No activity.' => 'Sem atividade.',
|
||||
// 'RSS feed' => '',
|
||||
'%s updated a comment on the task #%d' => '%s atualizou um comentário na tarefa #%d',
|
||||
'%s commented on the task #%d' => '%s comentou na tarefa #%d',
|
||||
'%s updated a subtask for the task #%d' => '%s atualizou uma sub-tarefa para a tarefa #%d',
|
||||
'%s created a subtask for the task #%d' => '%s criou uma sub-tarefa para a tarefa #%d',
|
||||
'RSS feed' => 'Feed RSS',
|
||||
'%s updated a comment on the task #%d' => '%s atualizou um comentário sobre a tarefa #%d',
|
||||
'%s commented on the task #%d' => '%s comentou sobre a tarefa #%d',
|
||||
'%s updated a subtask for the task #%d' => '%s atualizou uma subtarefa para a tarefa #%d',
|
||||
'%s created a subtask for the task #%d' => '%s criou uma subtarefa para a tarefa #%d',
|
||||
'%s updated the task #%d' => '%s atualizou a tarefa #%d',
|
||||
'%s created the task #%d' => '%s criou a tarefa #%d',
|
||||
'%s closed the task #%d' => '%s encerrou a tarefa #%d',
|
||||
'%s closed the task #%d' => '%s finalizou a tarefa #%d',
|
||||
'%s open the task #%d' => '%s abriu a tarefa #%d',
|
||||
'%s moved the task #%d to the column "%s"' => '%s moveu a tarefa #%d para a coluna "%s"',
|
||||
'%s moved the task #%d to the position %d in the column "%s"' => '%s moveu a tarefa #%d para a posição %d na coluna "%s"',
|
||||
|
@ -498,108 +499,153 @@ return array(
|
|||
'Default columns for new projects (Comma-separated)' => 'Colunas padrão para novos projetos (Separado por vírgula)',
|
||||
'Task assignee change' => 'Mudar designação da tarefa',
|
||||
'%s change the assignee of the task #%d to %s' => '%s mudou a designação da tarefa #%d para %s',
|
||||
'%s change the assignee of the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to %s' => '%s mudou a designação da tarefa <a href="?controller=task&action=show&task_id=%d">#%d</a> para %s',
|
||||
// '[%s][Column Change] %s (#%d)' => '',
|
||||
// '[%s][Position Change] %s (#%d)' => '',
|
||||
// '[%s][Assignee Change] %s (#%d)' => '',
|
||||
'New password for the user "%s"' => 'Novo password para o usuário "%s"',
|
||||
'%s changed the assignee of the task %s to %s' => '%s mudou a designação da tarefa %s para %s',
|
||||
'[%s][Column Change] %s (#%d)' => '[%s][Modificou Coluna] %s (#%d)',
|
||||
'[%s][Position Change] %s (#%d)' => '[%s][Modificou Posição] %s (#%d)',
|
||||
'[%s][Assignee Change] %s (#%d)' => '[%s][Modificou Designação] %s (#%d)',
|
||||
'New password for the user "%s"' => 'Nova senha para o usuário "%s"',
|
||||
'Choose an event' => 'Escolher um evento',
|
||||
// 'Github commit received' => '',
|
||||
// 'Github issue opened' => '',
|
||||
// 'Github issue closed' => '',
|
||||
// 'Github issue reopened' => '',
|
||||
// 'Github issue assignee change' => '',
|
||||
// 'Github issue label change' => '',
|
||||
'Create a task from an external provider' => 'Criar uma tarefa a partir de um provedor externo',
|
||||
'Change the assignee based on an external username' => 'Alterar designação com vase em um usuário externo!',
|
||||
'Github commit received' => 'Github commit received',
|
||||
'Github issue opened' => 'Github issue opened',
|
||||
'Github issue closed' => 'Github issue closed',
|
||||
'Github issue reopened' => 'Github issue reopened',
|
||||
'Github issue assignee change' => 'Github issue assignee change',
|
||||
'Github issue label change' => 'Github issue label change',
|
||||
'Create a task from an external provider' => 'Criar uma tarefa por meio de um serviço externo',
|
||||
'Change the assignee based on an external username' => 'Alterar designação com base em um usuário externo',
|
||||
'Change the category based on an external label' => 'Alterar categoria com base em um rótulo externo',
|
||||
'Reference' => 'Referencia',
|
||||
'Reference: %s' => 'Referencia: %s',
|
||||
'Reference' => 'Referência',
|
||||
'Reference: %s' => 'Referência: %s',
|
||||
'Label' => 'Rótulo',
|
||||
'Database' => 'Banco de dados',
|
||||
'About' => 'Sobre',
|
||||
// 'Database driver:' => '',
|
||||
// 'Board settings' => '',
|
||||
// 'URL and token' => '',
|
||||
// 'Webhook settings' => '',
|
||||
// 'URL for task creation:' => '',
|
||||
// 'Reset token' => '',
|
||||
// 'API endpoint:' => '',
|
||||
// 'Refresh interval for private board' => '',
|
||||
// 'Refresh interval for public board' => '',
|
||||
// 'Task highlight period' => '',
|
||||
// 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => '',
|
||||
// 'Frequency in second (60 seconds by default)' => '',
|
||||
// 'Frequency in second (0 to disable this feature, 10 seconds by default)' => '',
|
||||
'Database driver:' => 'Driver do banco de dados:',
|
||||
'Board settings' => 'Configurações do Board',
|
||||
'URL and token' => 'URL e token',
|
||||
'Webhook settings' => 'Configurações do Webhook',
|
||||
'URL for task creation:' => 'URL para a criação da tarefa:',
|
||||
'Reset token' => 'Resetar token',
|
||||
'API endpoint:' => 'API endpoint:',
|
||||
'Refresh interval for private board' => 'Intervalo de atualização para um board privado',
|
||||
'Refresh interval for public board' => 'Intervalo de atualização para um board público',
|
||||
'Task highlight period' => 'Período de Tarefa em destaque',
|
||||
'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => 'Período (em segundos) para considerar que uma tarefa foi modificada recentemente (0 para desativar, 2 dias por padrão)',
|
||||
'Frequency in second (60 seconds by default)' => 'Frequência em segundos (60 segundos por padrão)',
|
||||
'Frequency in second (0 to disable this feature, 10 seconds by default)' => 'Frequência em segundos (0 para desativar este recurso, 10 segundos por padrão)',
|
||||
'Application URL' => 'URL da Aplicação',
|
||||
// 'Example: http://example.kanboard.net/ (used by email notifications)' => '',
|
||||
// 'Token regenerated.' => '',
|
||||
'Example: http://example.kanboard.net/ (used by email notifications)' => 'Exemplo: http://example.kanboard.net/ (utilizado nas notificações por e-mail)',
|
||||
'Token regenerated.' => 'Token ',
|
||||
'Date format' => 'Formato de data',
|
||||
'ISO format is always accepted, example: "%s" and "%s"' => 'O formato ISO é sempre aceito, exemplo: "%s" e "%s"',
|
||||
'New private project' => 'Novo projeto privado',
|
||||
'This project is private' => 'Este projeto é privado',
|
||||
'Type here to create a new sub-task' => 'Digite aqui para criar uma nova sub-tarefa',
|
||||
'Type here to create a new sub-task' => 'Digite aqui para criar uma nova subtarefa',
|
||||
'Add' => 'Adicionar',
|
||||
'Estimated time: %s hours' => 'Tempo estimado: %s horas',
|
||||
'Time spent: %s hours' => 'Tempo gasto: %s horas',
|
||||
'Started on %B %e, %Y' => 'Iniciado em %B %e, %Y',
|
||||
'Start date' => 'Data de início',
|
||||
'Time estimated' => 'Tempo estimado',
|
||||
'There is nothing assigned to you.' => 'Não há nada designado para você.',
|
||||
'There is nothing assigned to you.' => 'Não há nada designado à você.',
|
||||
'My tasks' => 'Minhas tarefas',
|
||||
// 'Activity stream' => '',
|
||||
// 'Dashboard' => '',
|
||||
'Activity stream' => 'Atividades Recentes',
|
||||
'Dashboard' => 'Painel de Controle',
|
||||
'Confirmation' => 'Confirmação',
|
||||
'Allow everybody to access to this project' => 'Permitir que todos acessem este projeto',
|
||||
'Everybody have access to this project.' => 'Todos possuem acesso a este projeto.',
|
||||
// 'Webhooks' => '',
|
||||
// 'API' => '',
|
||||
'Webhooks' => 'Webhooks',
|
||||
'API' => 'API',
|
||||
'Integration' => 'Integração',
|
||||
// 'Github webhook' => '',
|
||||
'Help on Github webhook' => 'Ajuda para o Github webhook',
|
||||
'Create a comment from an external provider' => 'Criar um comentário de um provedor externo',
|
||||
// 'Github issue comment created' => '',
|
||||
'Github webhooks' => 'Github webhooks',
|
||||
'Help on Github webhooks' => 'Ajuda para o Github webhooks',
|
||||
'Create a comment from an external provider' => 'Criar um comentário por meio de um serviço externo',
|
||||
'Github issue comment created' => 'Github issue comment created',
|
||||
'Configure' => 'Configurar',
|
||||
'Project management' => 'Gerenciamento de projetos',
|
||||
'My projects' => 'Meus projetos',
|
||||
'Columns' => 'Colunas',
|
||||
'Task' => 'Tarefas',
|
||||
'Your are not member of any project.' => 'Você não é menmbro de nenhum projeto.',
|
||||
'Your are not member of any project.' => 'Você não é membro de nenhum projeto.',
|
||||
'Percentage' => 'Porcentagem',
|
||||
'Number of tasks' => 'Número de tarefas',
|
||||
'Task distribution' => 'Distribuição de tarefas',
|
||||
'Reportings' => 'Relatórios',
|
||||
// 'Task repartition for "%s"' => '',
|
||||
'Task repartition for "%s"' => 'Redistribuição da tarefa para "%s"',
|
||||
'Analytics' => 'Estatísticas',
|
||||
'Subtask' => 'Sub-tarefa',
|
||||
'My subtasks' => 'Minhas sub-tarefas',
|
||||
'User repartition' => 'Repartição de usuário',
|
||||
'User repartition for "%s"' => 'Repartição de usuário para "%s"',
|
||||
'Clone this project' => 'Clonar o projeto',
|
||||
'Subtask' => 'Subtarefa',
|
||||
'My subtasks' => 'Minhas subtarefas',
|
||||
'User repartition' => 'Redistribuição de usuário',
|
||||
'User repartition for "%s"' => 'Redistribuição de usuário para "%s"',
|
||||
'Clone this project' => 'Clonar este projeto',
|
||||
'Column removed successfully.' => 'Coluna removida com sucesso.',
|
||||
'Edit Project' => 'Editar projeto',
|
||||
// 'Github Issue' => '',
|
||||
'Not enough data to show the graph.' => 'Dados insuficientes para exibir o gráfico.',
|
||||
'Github Issue' => 'Github Issue',
|
||||
'Not enough data to show the graph.' => 'Não há dados suficientes para mostrar o gráfico.',
|
||||
'Previous' => 'Anterior',
|
||||
'The id must be an integer' => 'A ID deve ser um inteiro',
|
||||
'The project id must be an integer' => 'A ID do projeto deve ser um inteiro',
|
||||
'The status must be an integer' => 'O status deve ser um inteiro',
|
||||
'The subtask id is required' => 'A ID da sub-tarefa é requerida',
|
||||
'The subtask id must be an integer' => 'A ID da sub-tarefa deve ser um inteiro',
|
||||
'The task id is required' => 'A ID da tarefa é requerida',
|
||||
'The task id must be an integer' => 'A ID da tarefa deve ser um inteiro',
|
||||
'The user id must be an integer' => 'A ID de usuário deve ser um inteiro',
|
||||
'This value is required' => 'Este valor é requerido',
|
||||
'The id must be an integer' => 'O ID deve ser um número inteiro',
|
||||
'The project id must be an integer' => 'O ID do projeto deve ser um inteiro',
|
||||
'The status must be an integer' => 'O status deve ser um número inteiro',
|
||||
'The subtask id is required' => 'O ID da subtarefa é obrigatório',
|
||||
'The subtask id must be an integer' => 'O ID da subtarefa deve ser um número inteiro',
|
||||
'The task id is required' => 'O ID da tarefa é obrigatório',
|
||||
'The task id must be an integer' => 'O ID da tarefa deve ser um número inteiro',
|
||||
'The user id must be an integer' => 'O ID do usuário deve ser um número inteiro',
|
||||
'This value is required' => 'Este valor é obrigatório',
|
||||
'This value must be numeric' => 'Este valor deve ser numérico',
|
||||
'Unable to create this task.' => 'Não foi possível criar esta tarefa.',
|
||||
// 'Cumulative flow diagram' => '',
|
||||
// 'Cumulative flow diagram for "%s"' => '',
|
||||
// 'Daily project summary' => '',
|
||||
// 'Daily project summary export' => '',
|
||||
// 'Daily project summary export for "%s"' => '',
|
||||
// 'Exports' => '',
|
||||
// 'This export contains the number of tasks per column grouped per day.' => '',
|
||||
'Cumulative flow diagram' => 'Fluxograma cumulativo',
|
||||
'Cumulative flow diagram for "%s"' => 'Fluxograma cumulativo para "%s"',
|
||||
'Daily project summary' => 'Resumo diário do projeto',
|
||||
'Daily project summary export' => 'Exportação diária do resumo do projeto',
|
||||
'Daily project summary export for "%s"' => 'Exportação diária do resumo do projeto para "%s"',
|
||||
'Exports' => 'Exportar',
|
||||
'This export contains the number of tasks per column grouped per day.' => '',
|
||||
'Nothing to preview...' => 'Nada para pré-visualizar...',
|
||||
'Preview' => 'Pré-visualizar',
|
||||
// 'Write' => '',
|
||||
'Write' => 'Escrever',
|
||||
'Active swimlanes' => 'Ativar swimlanes',
|
||||
'Add a new swimlane' => 'Adicionar novo swimlane',
|
||||
'Change default swimlane' => 'Alterar swimlane padrão',
|
||||
'Default swimlane' => 'Swimlane padrão',
|
||||
'Do you really want to remove this swimlane: "%s"?' => 'Você realmente deseja remover este swimlane: "%s"?',
|
||||
'Inactive swimlanes' => 'Desativar swimlanes',
|
||||
'Set project manager' => 'Definir gerente do projeto',
|
||||
'Set project member' => 'Definir membro do projeto',
|
||||
'Remove a swimlane' => 'Remover um swimlane',
|
||||
'Rename' => 'Renomear',
|
||||
'Show default swimlane' => 'Exibir swimlane padrão',
|
||||
'Swimlane modification for the project "%s"' => 'Modificação de swimlane para o projeto "%s"',
|
||||
'Swimlane not found.' => 'Swimlane não encontrado.',
|
||||
'Swimlane removed successfully.' => 'Swimlane removido com sucesso.',
|
||||
'Swimlanes' => 'Swimlanes',
|
||||
'Swimlane updated successfully.' => 'Swimlane atualizado com sucesso.',
|
||||
'The default swimlane have been updated successfully.' => 'O swimlane padrão foi atualizado com sucesso.',
|
||||
'Unable to create your swimlane.' => 'Não foi possível criar o seu swimlane.',
|
||||
'Unable to remove this swimlane.' => 'Não foi possível remover este swimlane.',
|
||||
'Unable to update this swimlane.' => 'Não foi possível atualizar este swimlane.',
|
||||
'Your swimlane have been created successfully.' => 'Seu swimlane foi criado com sucesso.',
|
||||
'Example: "Bug, Feature Request, Improvement"' => 'Exemplo: "Bug, Feature Request, Improvement"',
|
||||
'Default categories for new projects (Comma-separated)' => 'Categorias padrão para novos projetos (Separadas por vírgula)',
|
||||
'Gitlab commit received' => 'Gitlab commit received',
|
||||
'Gitlab issue opened' => 'Gitlab issue opened',
|
||||
'Gitlab issue closed' => 'Gitlab issue closed',
|
||||
'Gitlab webhooks' => 'Gitlab webhooks',
|
||||
'Help on Gitlab webhooks' => 'Ajuda sobre Gitlab webhooks',
|
||||
'Integrations' => 'Integrações',
|
||||
'Integration with third-party services' => 'Integração com serviços de terceiros',
|
||||
'Role for this project' => 'Função para este projeto',
|
||||
'Project manager' => 'Gerente do projeto',
|
||||
'Project member' => 'Membro do projeto',
|
||||
'A project manager can change the settings of the project and have more privileges than a standard user.' => 'Um gerente do projeto pode alterar as configurações do projeto e ter mais privilégios que um usuário padrão.',
|
||||
'Gitlab Issue' => 'Gitlab Issue',
|
||||
'Subtask Id' => 'ID da subtarefa',
|
||||
'Subtasks' => 'Subtarefas',
|
||||
'Subtasks Export' => 'Exportar subtarefas',
|
||||
'Subtasks exportation for "%s"' => 'Subtarefas exportadas para "%s"',
|
||||
'Task Title' => 'Título da Tarefa',
|
||||
'Untitled' => 'Sem título',
|
||||
'Application default' => 'Aplicação padrão',
|
||||
'Language:' => 'Idioma',
|
||||
'Timezone:' => 'Fuso horário',
|
||||
'Next' => 'Próximo',
|
||||
);
|
||||
|
|
|
@ -182,7 +182,7 @@ return array(
|
|||
'Change assignee' => 'Сменить назначенного',
|
||||
'Change assignee for the task "%s"' => 'Сменить назначенного для задачи « %s »',
|
||||
'Timezone' => 'Часовой пояс',
|
||||
'Sorry, I didn\'t found this information in my database!' => 'К сожалению, информация в базе данных не найдена !',
|
||||
'Sorry, I didn\'t find this information in my database!' => 'К сожалению, информация в базе данных не найдена !',
|
||||
'Page not found' => 'Страница не найдена',
|
||||
'Complexity' => 'Сложность',
|
||||
'limit' => 'лимит',
|
||||
|
@ -194,7 +194,7 @@ return array(
|
|||
'Allow this user' => 'Разрешить этого пользователя',
|
||||
'Only those users have access to this project:' => 'Только эти пользователи имеют доступ к проекту :',
|
||||
'Don\'t forget that administrators have access to everything.' => 'Помните, администратор имеет доступ ко всему.',
|
||||
'revoke' => 'отозвать',
|
||||
'Revoke' => 'отозвать',
|
||||
'List of authorized users' => 'Список авторизованных пользователей',
|
||||
'User' => 'Пользователь',
|
||||
'Nobody have access to this project.' => 'Ни у кого нет доступа к этому проекту',
|
||||
|
@ -213,6 +213,7 @@ return array(
|
|||
'Invalid date' => 'Неверная дата',
|
||||
'Must be done before %B %e, %Y' => 'Должно быть сделано до %d/%m/%Y',
|
||||
'%B %e, %Y' => '%d/%m/%Y',
|
||||
// '%b %e, %Y' => '',
|
||||
'Automatic actions' => 'Автоматические действия',
|
||||
'Your automatic action have been created successfully.' => 'Автоматика настроена.',
|
||||
'Unable to create your automatic action.' => 'Не удалось создать автоматизированное действие.',
|
||||
|
@ -468,18 +469,18 @@ return array(
|
|||
'Unable to change the password.' => 'Не удалось сменить пароль.',
|
||||
'Change category for the task "%s"' => 'Сменить категорию для задачи "%s"',
|
||||
'Change category' => 'Смена категории',
|
||||
'%s updated the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s обновил задачу <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s open the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s открыл задачу <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s moved the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to the position #%d in the column "%s"' => '%s перместил задачу <a href="?controller=task&action=show&task_id=%d">#%d</a> на позицию #%d в колонке "%s"',
|
||||
'%s moved the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to the column "%s"' => '%s переместил задачу <a href="?controller=task&action=show&task_id=%d">#%d</a> в колонку "%s"',
|
||||
'%s created the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s создал задачу <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s closed the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s закрыл задачу <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s created a subtask for the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s создал подзадачу для задачи <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s updated a subtask for the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s обновил подзадачу для задачи <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s updated the task %s' => '%s обновил задачу %s',
|
||||
'%s opened the task %s' => '%s открыл задачу %s',
|
||||
'%s moved the task %s to the position #%d in the column "%s"' => '%s перместил задачу %s на позицию #%d в колонке "%s"',
|
||||
'%s moved the task %s to the column "%s"' => '%s переместил задачу %s в колонку "%s"',
|
||||
'%s created the task %s' => '%s создал задачу %s',
|
||||
'%s closed the task %s' => '%s закрыл задачу %s',
|
||||
'%s created a subtask for the task %s' => '%s создал подзадачу для задачи %s',
|
||||
'%s updated a subtask for the task %s' => '%s обновил подзадачу для задачи %s',
|
||||
'Assigned to %s with an estimate of %s/%sh' => 'Назначено %s с окончанием %s/%sh',
|
||||
'Not assigned, estimate of %sh' => 'Не назначено, окончание %sh',
|
||||
'%s updated a comment on the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s обновил комментарий к задаче <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s commented the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s прокомментировал задачу <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s updated a comment on the task %s' => '%s обновил комментарий к задаче %s',
|
||||
'%s commented the task %s' => '%s прокомментировал задачу %s',
|
||||
'%s\'s activity' => '%s активность',
|
||||
'No activity.' => 'Нет активности',
|
||||
'RSS feed' => 'RSS лента',
|
||||
|
@ -498,7 +499,7 @@ return array(
|
|||
'Default columns for new projects (Comma-separated)' => 'Колонки по умолчанию для новых проектов (разделять запятой)',
|
||||
'Task assignee change' => 'Изменен назначенный',
|
||||
'%s change the assignee of the task #%d to %s' => '%s сменил назначенного для задачи #%d на %s',
|
||||
'%s change the assignee of the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to %s' => '%s сменил назначенного для задачи <a href="?controller=task&action=show&task_id=%d">#%d</a> на %s',
|
||||
'%s changed the assignee of the task %s to %s' => '%s сменил назначенного для задачи %s на %s',
|
||||
'[%s][Column Change] %s (#%d)' => '[%s][Изменение колонки] %s (#%d)',
|
||||
'[%s][Position Change] %s (#%d)' => '[%s][Изменение позиции] %s (#%d)',
|
||||
'[%s][Assignee Change] %s (#%d)' => '[%s][Изменение назначеного] %s (#%d)',
|
||||
|
@ -555,8 +556,8 @@ return array(
|
|||
// 'Webhooks' => '',
|
||||
// 'API' => '',
|
||||
// 'Integration' => '',
|
||||
// 'Github webhook' => '',
|
||||
// 'Help on Github webhook' => '',
|
||||
// 'Github webhooks' => '',
|
||||
// 'Help on Github webhooks' => '',
|
||||
// 'Create a comment from an external provider' => '',
|
||||
// 'Github issue comment created' => '',
|
||||
// 'Configure' => '',
|
||||
|
@ -602,4 +603,49 @@ return array(
|
|||
// 'Nothing to preview...' => '',
|
||||
// 'Preview' => '',
|
||||
// 'Write' => '',
|
||||
// 'Active swimlanes' => '',
|
||||
// 'Add a new swimlane' => '',
|
||||
// 'Change default swimlane' => '',
|
||||
// 'Default swimlane' => '',
|
||||
// 'Do you really want to remove this swimlane: "%s"?' => '',
|
||||
// 'Inactive swimlanes' => '',
|
||||
// 'Set project manager' => '',
|
||||
// 'Set project member' => '',
|
||||
// 'Remove a swimlane' => '',
|
||||
// 'Rename' => '',
|
||||
// 'Show default swimlane' => '',
|
||||
// 'Swimlane modification for the project "%s"' => '',
|
||||
// 'Swimlane not found.' => '',
|
||||
// 'Swimlane removed successfully.' => '',
|
||||
// 'Swimlanes' => '',
|
||||
// 'Swimlane updated successfully.' => '',
|
||||
// 'The default swimlane have been updated successfully.' => '',
|
||||
// 'Unable to create your swimlane.' => '',
|
||||
// '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)' => '',
|
||||
// 'Gitlab commit received' => '',
|
||||
// 'Gitlab issue opened' => '',
|
||||
// 'Gitlab issue closed' => '',
|
||||
// 'Gitlab webhooks' => '',
|
||||
// 'Help on Gitlab webhooks' => '',
|
||||
// 'Integrations' => '',
|
||||
// 'Integration with third-party services' => '',
|
||||
// 'Role for this project' => '',
|
||||
// 'Project manager' => '',
|
||||
// 'Project member' => '',
|
||||
// 'A project manager can change the settings of the project and have more privileges than a standard user.' => '',
|
||||
// 'Gitlab Issue' => '',
|
||||
// 'Subtask Id' => '',
|
||||
// 'Subtasks' => '',
|
||||
// 'Subtasks Export' => '',
|
||||
// 'Subtasks exportation for "%s"' => '',
|
||||
// 'Task Title' => '',
|
||||
// 'Untitled' => '',
|
||||
// 'Application default' => '',
|
||||
// 'Language:' => '',
|
||||
// 'Timezone:' => '',
|
||||
// 'Next' => '',
|
||||
);
|
||||
|
|
|
@ -104,7 +104,7 @@ return array(
|
|||
'Open a task' => 'Öppna en uppgift',
|
||||
'Do you really want to open this task: "%s"?' => 'Vill du verkligen öppna denna uppgift: "%s"?',
|
||||
'Back to the board' => 'Tillbaka till tavlan',
|
||||
'Created on %B %e, %Y at %k:%M %p' => 'Skapad %d %B %Y kl %H:%M',
|
||||
'Created on %B %e, %Y at %k:%M %p' => 'Skapad %Y-%m-%d kl %H:%M',
|
||||
'There is nobody assigned' => 'Det finns ingen tilldelad',
|
||||
'Column on the board:' => 'Kolumn på tavlan:',
|
||||
'Status is open' => 'Statusen är öppen',
|
||||
|
@ -166,8 +166,8 @@ return array(
|
|||
'Work in progress' => 'Pågående',
|
||||
'Done' => 'Slutfört',
|
||||
'Application version:' => 'Version:',
|
||||
'Completed on %B %e, %Y at %k:%M %p' => 'Slutfört %d %B %Y kl %H:%M',
|
||||
'%B %e, %Y at %k:%M %p' => '%d %B %Y kl %H:%M',
|
||||
'Completed on %B %e, %Y at %k:%M %p' => 'Slutfört %Y-%m-%d kl %H:%M',
|
||||
'%B %e, %Y at %k:%M %p' => '%Y-%m-%d kl %H:%M',
|
||||
'Date created' => 'Skapat datum',
|
||||
'Date completed' => 'Slutfört datum',
|
||||
'Id' => 'ID',
|
||||
|
@ -182,19 +182,19 @@ return array(
|
|||
'Change assignee' => 'Ändra uppdragsinnehavare',
|
||||
'Change assignee for the task "%s"' => 'Ändra uppdragsinnehavare för uppgiften "%s"',
|
||||
'Timezone' => 'Tidszon',
|
||||
'Sorry, I didn\'t found this information in my database!' => 'Informationen kunde inte hittas i databasen.',
|
||||
'Sorry, I didn\'t find this information in my database!' => 'Informationen kunde inte hittas i databasen.',
|
||||
'Page not found' => 'Sidan hittas inte',
|
||||
'Complexity' => 'Ungefärligt antal timmar',
|
||||
'Complexity' => 'Komplexitet',
|
||||
'limit' => 'max',
|
||||
'Task limit' => 'Uppgiftsbegränsning',
|
||||
// 'Task count' => '',
|
||||
'Task count' => 'Antal uppgifter',
|
||||
'This value must be greater than %d' => 'Värdet måste vara större än %d',
|
||||
'Edit project access list' => 'Ändra projektåtkomst lista',
|
||||
'Edit users access' => 'Användaråtkomst',
|
||||
'Allow this user' => 'Tillåt användare',
|
||||
'Only those users have access to this project:' => 'Bara de användarna har tillgång till detta projekt.',
|
||||
'Don\'t forget that administrators have access to everything.' => 'Glöm inte att administratörerna har rätt att göra allt.',
|
||||
'revoke' => 'Dra tillbaka behörighet',
|
||||
'Revoke' => 'Dra tillbaka behörighet',
|
||||
'List of authorized users' => 'Lista med behöriga användare',
|
||||
'User' => 'Användare',
|
||||
'Nobody have access to this project.' => 'Ingen har tillgång till detta projekt.',
|
||||
|
@ -211,8 +211,9 @@ return array(
|
|||
'Edit this task' => 'Ändra denna uppgift',
|
||||
'Due Date' => 'Måldatum',
|
||||
'Invalid date' => 'Ej tillåtet datum',
|
||||
'Must be done before %B %e, %Y' => 'Måste vara klart innan %B %e, %Y',
|
||||
'%B %e, %Y' => '%d %B %Y',
|
||||
'Must be done before %B %e, %Y' => 'Måste vara klart innan %Y-%m-%d',
|
||||
'%B %e, %Y' => '%Y-%m-%d',
|
||||
'%b %e, %Y' => '%Y-%m-%d',
|
||||
'Automatic actions' => 'Automatiska åtgärder',
|
||||
'Your automatic action have been created successfully.' => 'Din automatiska åtgärd har skapats.',
|
||||
'Unable to create your automatic action.' => 'Kunde inte skapa din automatiska åtgärd.',
|
||||
|
@ -376,7 +377,7 @@ return array(
|
|||
'Link my GitHub Account' => 'Anslut mitt GitHub-konto',
|
||||
'Unlink my GitHub Account' => 'Koppla ifrån mitt GitHub-konto',
|
||||
'Created by %s' => 'Skapad av %s',
|
||||
'Last modified on %B %e, %Y at %k:%M %p' => 'Senaste ändring %B %e, %Y kl %k:%M %p',
|
||||
'Last modified on %B %e, %Y at %k:%M %p' => 'Senaste ändring %Y-%m-%d kl %H:%M',
|
||||
'Tasks Export' => 'Exportera uppgifter',
|
||||
'Tasks exportation for "%s"' => 'Exportera uppgifter för "%s"',
|
||||
'Start Date' => 'Startdatum',
|
||||
|
@ -468,18 +469,18 @@ return array(
|
|||
'Unable to change the password.' => 'Kunde inte byta lösenord.',
|
||||
'Change category for the task "%s"' => 'Byt kategori för uppgiften "%s"',
|
||||
'Change category' => 'Byt kategori',
|
||||
'%s updated the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s uppdaterade uppgiften <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s open the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s öppna uppgiften <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s moved the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to the position #%d in the column "%s"' => '%s flyttade uppgiften <a href="?controller=task&action=show&task_id=%d">#%d</a> till positionen #%d i kolumnen "%s"',
|
||||
'%s moved the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to the column "%s"' => '%s flyttade uppgiften <a href="?controller=task&action=show&task_id=%d">#%d</a> till kolumnen "%s"',
|
||||
'%s created the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s skapade uppgiften <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s closed the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s stängde uppgiften <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s created a subtask for the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s skapade en deluppgift för uppgiften <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s updated a subtask for the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s uppdaterade en deluppgift för uppgiften <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s updated the task %s' => '%s uppdaterade uppgiften %s',
|
||||
'%s opened the task %s' => '%s öppna uppgiften %s',
|
||||
'%s moved the task %s to the position #%d in the column "%s"' => '%s flyttade uppgiften %s till positionen #%d i kolumnen "%s"',
|
||||
'%s moved the task %s to the column "%s"' => '%s flyttade uppgiften %s till kolumnen "%s"',
|
||||
'%s created the task %s' => '%s skapade uppgiften %s',
|
||||
'%s closed the task %s' => '%s stängde uppgiften %s',
|
||||
'%s created a subtask for the task %s' => '%s skapade en deluppgift för uppgiften %s',
|
||||
'%s updated a subtask for the task %s' => '%s uppdaterade en deluppgift för uppgiften %s',
|
||||
'Assigned to %s with an estimate of %s/%sh' => 'Tilldelades %s med en uppskattning på %s/%sh',
|
||||
'Not assigned, estimate of %sh' => 'Inte tilldelade, uppskattat %sh',
|
||||
'%s updated a comment on the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s uppdaterade en kommentar till uppgiften <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s commented the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s kommenterade uppgiften <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s updated a comment on the task %s' => '%s uppdaterade en kommentar till uppgiften %s',
|
||||
'%s commented the task %s' => '%s kommenterade uppgiften %s',
|
||||
'%s\'s activity' => '%s\'s aktivitet',
|
||||
'No activity.' => 'Ingen aktivitet.',
|
||||
'RSS feed' => 'RSS flöde',
|
||||
|
@ -498,7 +499,7 @@ return array(
|
|||
'Default columns for new projects (Comma-separated)' => 'Standardkolumner för nya projekt (kommaseparerade)',
|
||||
'Task assignee change' => 'Ändra tilldelning av uppgiften',
|
||||
'%s change the assignee of the task #%d to %s' => '%s byt tilldelning av uppgiften #%d till %s',
|
||||
'%s change the assignee of the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to %s' => '%s byt tilldelning av uppgiften <a href="?controller=task&action=show&task_id=%d">#%d</a> till %s',
|
||||
'%s changed the assignee of the task %s to %s' => '%s byt tilldelning av uppgiften %s till %s',
|
||||
'[%s][Column Change] %s (#%d)' => '[%s][Byt kolumn] %s (#%d)',
|
||||
'[%s][Position Change] %s (#%d)' => '[%s][Byt position] %s (#%d)',
|
||||
'[%s][Assignee Change] %s (#%d)' => '[%s][Byt tilldelning] %s (#%d)',
|
||||
|
@ -542,64 +543,109 @@ return array(
|
|||
'Add' => 'Lägg till',
|
||||
'Estimated time: %s hours' => 'Uppskattad tid: %s timmar',
|
||||
'Time spent: %s hours' => 'Nedlaggd tid: %s timmar',
|
||||
'Started on %B %e, %Y' => 'Startad den %B %e, %Y',
|
||||
'Started on %B %e, %Y' => 'Startad %Y-%m-%d',
|
||||
'Start date' => 'Startdatum',
|
||||
'Time estimated' => 'Uppskattad tid',
|
||||
'There is nothing assigned to you.' => 'Du har inget tilldelat till dig.',
|
||||
'My tasks' => 'Mina uppgifte',
|
||||
'My tasks' => 'Mina uppgifter',
|
||||
'Activity stream' => 'Aktivitetsström',
|
||||
'Dashboard' => 'Instrumentpanel',
|
||||
'Confirmation' => 'Bekräftelse',
|
||||
// 'Allow everybody to access to this project' => '',
|
||||
// 'Everybody have access to this project.' => '',
|
||||
// 'Webhooks' => '',
|
||||
// 'API' => '',
|
||||
// 'Integration' => '',
|
||||
// 'Github webhook' => '',
|
||||
// 'Help on Github webhook' => '',
|
||||
// 'Create a comment from an external provider' => '',
|
||||
// 'Github issue comment created' => '',
|
||||
// 'Configure' => '',
|
||||
// 'Project management' => '',
|
||||
// 'My projects' => '',
|
||||
// 'Columns' => '',
|
||||
// 'Task' => '',
|
||||
// 'Your are not member of any project.' => '',
|
||||
// 'Percentage' => '',
|
||||
// 'Number of tasks' => '',
|
||||
// 'Task distribution' => '',
|
||||
// 'Reportings' => '',
|
||||
// 'Task repartition for "%s"' => '',
|
||||
// 'Analytics' => '',
|
||||
// 'Subtask' => '',
|
||||
// 'My subtasks' => '',
|
||||
// 'User repartition' => '',
|
||||
// 'User repartition for "%s"' => '',
|
||||
// 'Clone this project' => '',
|
||||
// 'Column removed successfully.' => '',
|
||||
// 'Edit Project' => '',
|
||||
// 'Github Issue' => '',
|
||||
// 'Not enough data to show the graph.' => '',
|
||||
// 'Previous' => '',
|
||||
// 'The id must be an integer' => '',
|
||||
// 'The project id must be an integer' => '',
|
||||
// 'The status must be an integer' => '',
|
||||
// 'The subtask id is required' => '',
|
||||
// 'The subtask id must be an integer' => '',
|
||||
// 'The task id is required' => '',
|
||||
// 'The task id must be an integer' => '',
|
||||
// 'The user id must be an integer' => '',
|
||||
// 'This value is required' => '',
|
||||
// 'This value must be numeric' => '',
|
||||
// 'Unable to create this task.' => '',
|
||||
// 'Cumulative flow diagram' => '',
|
||||
// 'Cumulative flow diagram for "%s"' => '',
|
||||
// 'Daily project summary' => '',
|
||||
// 'Daily project summary export' => '',
|
||||
// 'Daily project summary export for "%s"' => '',
|
||||
// 'Exports' => '',
|
||||
// 'This export contains the number of tasks per column grouped per day.' => '',
|
||||
// 'Nothing to preview...' => '',
|
||||
// 'Preview' => '',
|
||||
// 'Write' => '',
|
||||
'Allow everybody to access to this project' => 'Ge alla tillgång till projektet',
|
||||
'Everybody have access to this project.' => 'Alla har tillgång till projektet',
|
||||
'Webhooks' => 'Webhooks',
|
||||
'API' => 'API',
|
||||
'Integration' => 'Integration',
|
||||
'Github webhooks' => 'Github webhooks',
|
||||
'Help on Github webhooks' => 'Hjälp för Github webhooks',
|
||||
'Create a comment from an external provider' => 'Skapa en kommentar från en extern leverantör',
|
||||
'Github issue comment created' => 'Github frågekommentar skapad',
|
||||
'Configure' => 'Konfigurera',
|
||||
'Project management' => 'Projekthantering',
|
||||
'My projects' => 'Mina projekt',
|
||||
'Columns' => 'Kolumner',
|
||||
'Task' => 'Uppgift',
|
||||
'Your are not member of any project.' => 'Du är inte medlem i något projekt',
|
||||
'Percentage' => 'Procent',
|
||||
'Number of tasks' => 'Antal uppgifter',
|
||||
'Task distribution' => 'Uppgiftsfördelning',
|
||||
'Reportings' => 'Rapportering',
|
||||
'Task repartition for "%s"' => 'Uppgiftsdeltagande för "%s"',
|
||||
'Analytics' => 'Analyser',
|
||||
'Subtask' => 'Deluppgift',
|
||||
'My subtasks' => 'Mina deluppgifter',
|
||||
'User repartition' => 'Användardeltagande',
|
||||
'User repartition for "%s"' => 'Användardeltagande för "%s"',
|
||||
'Clone this project' => 'Klona projektet',
|
||||
'Column removed successfully.' => 'Kolumnen togs bort',
|
||||
'Edit Project' => 'Ändra Projekt',
|
||||
'Github Issue' => 'Github fråga',
|
||||
'Not enough data to show the graph.' => 'Inte tillräckligt med data för att visa graf',
|
||||
'Previous' => 'Föregående',
|
||||
'The id must be an integer' => 'ID måste vara ett heltal',
|
||||
'The project id must be an integer' => 'Projekt-ID måste vara ett heltal',
|
||||
'The status must be an integer' => 'Status måste vara ett heltal',
|
||||
'The subtask id is required' => 'Deluppgifts-ID behövs',
|
||||
'The subtask id must be an integer' => 'Deluppgifts-ID måste vara ett heltal',
|
||||
'The task id is required' => 'Uppgifts-ID behövs',
|
||||
'The task id must be an integer' => 'Uppgifts-ID måste vara ett heltal',
|
||||
'The user id must be an integer' => 'Användar-ID måste vara ett heltal',
|
||||
'This value is required' => 'Värdet behövs',
|
||||
'This value must be numeric' => 'Värdet måste vara numeriskt',
|
||||
'Unable to create this task.' => 'Kunde inte skapa uppgiften.',
|
||||
'Cumulative flow diagram' => 'Diagram med kumulativt flöde',
|
||||
'Cumulative flow diagram for "%s"' => 'Diagram med kumulativt flöde för "%s"',
|
||||
'Daily project summary' => 'Daglig projektsummering',
|
||||
'Daily project summary export' => 'Export av daglig projektsummering',
|
||||
'Daily project summary export for "%s"' => 'Export av daglig projektsummering för "%s"',
|
||||
'Exports' => 'Exporter',
|
||||
'This export contains the number of tasks per column grouped per day.' => 'Denna export innehåller antalet uppgifter per kolumn grupperade per dag.',
|
||||
'Nothing to preview...' => 'Inget att förhandsgrandska...',
|
||||
'Preview' => 'Förhandsgranska',
|
||||
'Write' => 'Skriva',
|
||||
'Active swimlanes' => 'Aktiva swimlanes',
|
||||
'Add a new swimlane' => 'Lägg till en nytt swimlane',
|
||||
'Change default swimlane' => 'Ändra standard swimlane',
|
||||
'Default swimlane' => 'Standard swimlane',
|
||||
'Do you really want to remove this swimlane: "%s"?' => 'Vill du verkligen ta bort denna swimlane: "%s"?',
|
||||
'Inactive swimlanes' => 'Inaktiv swimlane',
|
||||
'Set project manager' => 'Sätt Projektadministratör',
|
||||
'Set project member' => 'Sätt projektmedlem',
|
||||
'Remove a swimlane' => 'Ta bort en swimlane',
|
||||
'Rename' => 'Byt namn',
|
||||
'Show default swimlane' => 'Visa standard swimlane',
|
||||
'Swimlane modification for the project "%s"' => 'Ändra swimlane för projektet "%s"',
|
||||
'Swimlane not found.' => 'Swimlane kunde inte hittas',
|
||||
'Swimlane removed successfully.' => 'Swimlane togs bort',
|
||||
'Swimlanes' => 'Swimlanes',
|
||||
'Swimlane updated successfully.' => 'Swimlane uppdaterad',
|
||||
'The default swimlane have been updated successfully.' => 'Standardswimlane har uppdaterats',
|
||||
'Unable to create your swimlane.' => 'Kunde inte skapa din swimlane',
|
||||
'Unable to remove this swimlane.' => 'Kunde inte ta bort swimlane',
|
||||
'Unable to update this swimlane.' => 'Kunde inte uppdatera swimlane',
|
||||
'Your swimlane have been created successfully.' => 'Din swimlane har skapats',
|
||||
'Example: "Bug, Feature Request, Improvement"' => 'Exempel: "Bug, ny funktionalitet, förbättringar"',
|
||||
'Default categories for new projects (Comma-separated)' => 'Standardkategorier för nya projekt (komma-separerade)',
|
||||
'Gitlab commit received' => 'Gitlab bidrag mottaget',
|
||||
'Gitlab issue opened' => 'Gitlab fråga öppnad',
|
||||
'Gitlab issue closed' => 'Gitlab fråga stängd',
|
||||
'Gitlab webhooks' => 'Gitlab webhooks',
|
||||
'Help on Gitlab webhooks' => 'Hjälp för Gitlab webhooks',
|
||||
'Integrations' => 'Integrationer',
|
||||
'Integration with third-party services' => 'Integration med tjänst från tredjepart',
|
||||
'Role for this project' => 'Roll för detta projekt',
|
||||
'Project manager' => 'Projektadministratör',
|
||||
'Project member' => 'Projektmedlem',
|
||||
'A project manager can change the settings of the project and have more privileges than a standard user.' => 'En projektadministratör kan ändra inställningar för projektet och har mer rättigheter än en standardanvändare.',
|
||||
'Gitlab Issue' => 'Gitlab fråga',
|
||||
'Subtask Id' => 'Deluppgifts-ID',
|
||||
'Subtasks' => 'Deluppgift',
|
||||
'Subtasks Export' => 'Export av deluppgifter',
|
||||
'Subtasks exportation for "%s"' => 'Export av deluppgifter för "%s"',
|
||||
'Task Title' => 'Uppgiftstitel',
|
||||
'Untitled' => 'Titel saknas',
|
||||
'Application default' => 'Applikationsstandard',
|
||||
'Language:' => 'Språk',
|
||||
'Timezone:' => 'Tidszon',
|
||||
'Next' => 'Nästa',
|
||||
);
|
||||
|
|
|
@ -182,7 +182,7 @@ return array(
|
|||
'Change assignee' => 'เปลี่ยนการกำหนด',
|
||||
'Change assignee for the task "%s"' => 'เปลี่ยนการกำหนดสำหรับงาน « %s »',
|
||||
'Timezone' => 'เขตเวลา',
|
||||
'Sorry, I didn\'t found this information in my database!' => 'เสียใจด้วย ไม่สามารถหาข้อมูลในฐานข้อมูลได้',
|
||||
'Sorry, I didn\'t find this information in my database!' => 'เสียใจด้วย ไม่สามารถหาข้อมูลในฐานข้อมูลได้',
|
||||
'Page not found' => 'ไม่พบหน้า',
|
||||
'Complexity' => 'ความซับซ้อน',
|
||||
'limit' => 'จำกัด',
|
||||
|
@ -194,7 +194,7 @@ return array(
|
|||
'Allow this user' => 'อนุญาตผู้ใช้นี้',
|
||||
'Only those users have access to this project:' => 'ผู้ใช้ที่สามารถเข้าถึงโปรเจคนี้:',
|
||||
'Don\'t forget that administrators have access to everything.' => 'อย่าลืมผู้ดูแลระบบสามารถเข้าถึงได้ทุกอย่าง',
|
||||
'revoke' => 'ยกเลิก',
|
||||
'Revoke' => 'ยกเลิก',
|
||||
'List of authorized users' => 'รายชื่อผู้ใช้ที่ได้รับการยืนยัน',
|
||||
'User' => 'ผู้ใช้',
|
||||
// 'Nobody have access to this project.' => '',
|
||||
|
@ -213,6 +213,7 @@ return array(
|
|||
'Invalid date' => 'วันที่ผิด',
|
||||
'Must be done before %B %e, %Y' => 'ต้องทำให้เสร็จก่อน %d/%m/%Y',
|
||||
'%B %e, %Y' => '%d/%m/%Y',
|
||||
// '%b %e, %Y' => '',
|
||||
'Automatic actions' => 'การกระทำอัตโนมัติ',
|
||||
'Your automatic action have been created successfully.' => 'การกระทำอัตโนมัติสร้างเรียบร้อยแล้ว',
|
||||
'Unable to create your automatic action.' => 'ไม่สามารถสร้างการกระทำอัตโนมัติได้',
|
||||
|
@ -468,18 +469,18 @@ return array(
|
|||
'Unable to change the password.' => 'ไม่สามารถเปลี่ยนรหัสผ่านได้',
|
||||
'Change category for the task "%s"' => 'เปลี่ยนกลุ่มสำหรับงาน "%s"',
|
||||
'Change category' => 'เปลี่ยนกลุ่ม',
|
||||
'%s updated the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s ปรับปรุงงานแล้ว <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s open the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s เปิดงานแล้ว <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s moved the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to the position #%d in the column "%s"' => '%s ย้ายงานแล้ว <a href="?controller=task&action=show&task_id=%d">#%d</a> ไปตำแหน่ง #%d ในคอลัมน์ "%s"',
|
||||
'%s moved the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to the column "%s"' => '%s ย้ายงานแล้ว <a href="?controller=task&action=show&task_id=%d">#%d</a> ไปคอลัมน์ "%s"',
|
||||
'%s created the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s สร้างงานแล้ว <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s closed the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s ปิดงานแล้ว <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s created a subtask for the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s สร้างงานย่อยสำหรับงานแล้ว <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s updated a subtask for the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s ปรับปรุงงานย่อยสำหรับงานแล้ว <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s updated the task %s' => '%s ปรับปรุงงานแล้ว %s',
|
||||
'%s opened the task %s' => '%s เปิดงานแล้ว %s',
|
||||
'%s moved the task %s to the position #%d in the column "%s"' => '%s ย้ายงานแล้ว %s ไปตำแหน่ง #%d ในคอลัมน์ "%s"',
|
||||
'%s moved the task %s to the column "%s"' => '%s ย้ายงานแล้ว %s ไปคอลัมน์ "%s"',
|
||||
'%s created the task %s' => '%s สร้างงานแล้ว %s',
|
||||
'%s closed the task %s' => '%s ปิดงานแล้ว %s',
|
||||
'%s created a subtask for the task %s' => '%s สร้างงานย่อยสำหรับงานแล้ว %s',
|
||||
'%s updated a subtask for the task %s' => '%s ปรับปรุงงานย่อยสำหรับงานแล้ว %s',
|
||||
'Assigned to %s with an estimate of %s/%sh' => 'กำหนดให้ %s โดยประมาณแล้ว %s/%sh',
|
||||
'Not assigned, estimate of %sh' => 'ไม่กำหนดแล้ว, ประมาณเวลาที่ใช้ %s ชั่วโมง',
|
||||
'%s updated a comment on the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s ปรับปรุงความคิดเห็นในงานแล้ว <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s commented the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s แสดงความคิดเห็นของงานแล้ว <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s updated a comment on the task %s' => '%s ปรับปรุงความคิดเห็นในงานแล้ว %s',
|
||||
'%s commented the task %s' => '%s แสดงความคิดเห็นของงานแล้ว %s',
|
||||
'%s\'s activity' => 'กิจกรรม %s',
|
||||
'No activity.' => 'ไม่มีกิจกรรม',
|
||||
'RSS feed' => 'RSS feed',
|
||||
|
@ -498,7 +499,7 @@ return array(
|
|||
'Default columns for new projects (Comma-separated)' => 'คอลัมน์เริ่มต้นสำหรับโปรเจคใหม่ (Comma-separated)',
|
||||
'Task assignee change' => 'เปลี่ยนการกำหนดบุคคลของงาน',
|
||||
// '%s change the assignee of the task #%d to %s' => '',
|
||||
// '%s change the assignee of the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to %s' => '',
|
||||
// '%s changed the assignee of the task %s to %s' => '',
|
||||
// '[%s][Column Change] %s (#%d)' => '',
|
||||
// '[%s][Position Change] %s (#%d)' => '',
|
||||
// '[%s][Assignee Change] %s (#%d)' => '',
|
||||
|
@ -555,8 +556,8 @@ return array(
|
|||
// 'Webhooks' => '',
|
||||
// 'API' => '',
|
||||
// 'Integration' => '',
|
||||
// 'Github webhook' => '',
|
||||
// 'Help on Github webhook' => '',
|
||||
// 'Github webhooks' => '',
|
||||
// 'Help on Github webhooks' => '',
|
||||
// 'Create a comment from an external provider' => '',
|
||||
// 'Github issue comment created' => '',
|
||||
// 'Configure' => '',
|
||||
|
@ -602,4 +603,49 @@ return array(
|
|||
// 'Nothing to preview...' => '',
|
||||
// 'Preview' => '',
|
||||
// 'Write' => '',
|
||||
// 'Active swimlanes' => '',
|
||||
// 'Add a new swimlane' => '',
|
||||
// 'Change default swimlane' => '',
|
||||
// 'Default swimlane' => '',
|
||||
// 'Do you really want to remove this swimlane: "%s"?' => '',
|
||||
// 'Inactive swimlanes' => '',
|
||||
// 'Set project manager' => '',
|
||||
// 'Set project member' => '',
|
||||
// 'Remove a swimlane' => '',
|
||||
// 'Rename' => '',
|
||||
// 'Show default swimlane' => '',
|
||||
// 'Swimlane modification for the project "%s"' => '',
|
||||
// 'Swimlane not found.' => '',
|
||||
// 'Swimlane removed successfully.' => '',
|
||||
// 'Swimlanes' => '',
|
||||
// 'Swimlane updated successfully.' => '',
|
||||
// 'The default swimlane have been updated successfully.' => '',
|
||||
// 'Unable to create your swimlane.' => '',
|
||||
// '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)' => '',
|
||||
// 'Gitlab commit received' => '',
|
||||
// 'Gitlab issue opened' => '',
|
||||
// 'Gitlab issue closed' => '',
|
||||
// 'Gitlab webhooks' => '',
|
||||
// 'Help on Gitlab webhooks' => '',
|
||||
// 'Integrations' => '',
|
||||
// 'Integration with third-party services' => '',
|
||||
// 'Role for this project' => '',
|
||||
// 'Project manager' => '',
|
||||
// 'Project member' => '',
|
||||
// 'A project manager can change the settings of the project and have more privileges than a standard user.' => '',
|
||||
// 'Gitlab Issue' => '',
|
||||
// 'Subtask Id' => '',
|
||||
// 'Subtasks' => '',
|
||||
// 'Subtasks Export' => '',
|
||||
// 'Subtasks exportation for "%s"' => '',
|
||||
// 'Task Title' => '',
|
||||
// 'Untitled' => '',
|
||||
// 'Application default' => '',
|
||||
// 'Language:' => '',
|
||||
// 'Timezone:' => '',
|
||||
// 'Next' => '',
|
||||
);
|
||||
|
|
|
@ -24,7 +24,7 @@ return array(
|
|||
'Unassigned' => '未指定',
|
||||
'View this task' => '查看该任务',
|
||||
'Remove user' => '移除用户',
|
||||
'Do you really want to remove this user: "%s"?' => '你确定要移除这个用户吗:"%s"?',
|
||||
'Do you really want to remove this user: "%s"?' => '确定要删除用户"%s"吗?',
|
||||
'New user' => '新建用户',
|
||||
'All users' => '所有用户',
|
||||
'Username' => '用户名',
|
||||
|
@ -63,7 +63,7 @@ return array(
|
|||
'Disable' => '停用',
|
||||
'Enable' => '启用',
|
||||
'New project' => '新建项目',
|
||||
'Do you really want to remove this project: "%s"?' => '你确定要移除该项目吗:"%s"?',
|
||||
'Do you really want to remove this project: "%s"?' => '确定要移除项目"%s"吗?',
|
||||
'Remove project' => '移除项目',
|
||||
'Boards' => '看板',
|
||||
'Edit the board for "%s"' => '为"%s"修改看板',
|
||||
|
@ -78,7 +78,7 @@ return array(
|
|||
'Remove a column' => '移除一个栏目',
|
||||
'Remove a column from a board' => '从看板移除一个栏目',
|
||||
'Unable to remove this column.' => '无法移除该栏目。',
|
||||
'Do you really want to remove this column: "%s"?' => '你确定要移除该栏目:"%s"吗?',
|
||||
'Do you really want to remove this column: "%s"?' => '确定要移除栏目"%s"吗?',
|
||||
'This action will REMOVE ALL TASKS associated to this column!' => '该动作将移除与该栏目相关的所有项目!',
|
||||
'Settings' => '设置',
|
||||
'Application settings' => '应用设置',
|
||||
|
@ -182,19 +182,19 @@ return array(
|
|||
'Change assignee' => '变更负责人',
|
||||
'Change assignee for the task "%s"' => '更改任务"%s"的负责人',
|
||||
'Timezone' => '时区',
|
||||
'Sorry, I didn\'t found this information in my database!' => '抱歉,无法在数据库中找到该信息!',
|
||||
'Sorry, I didn\'t find this information in my database!' => '抱歉,无法在数据库中找到该信息!',
|
||||
'Page not found' => '页面未找到',
|
||||
'Complexity' => '复杂度',
|
||||
'limit' => '限制',
|
||||
'Task limit' => '任务限制',
|
||||
// 'Task count' => '',
|
||||
'Task count' => '任务数',
|
||||
'This value must be greater than %d' => '该数值必须大于%d',
|
||||
'Edit project access list' => '编辑项目存取列表',
|
||||
'Edit users access' => '编辑用户存取权限',
|
||||
'Allow this user' => '允许该用户',
|
||||
'Only those users have access to this project:' => '只有这些用户有该项目的存取权限:',
|
||||
'Don\'t forget that administrators have access to everything.' => '别忘了管理员有一切的权限。',
|
||||
'revoke' => '撤销',
|
||||
'Revoke' => '撤销',
|
||||
'List of authorized users' => '已授权的用户列表',
|
||||
'User' => '用户',
|
||||
'Nobody have access to this project.' => '无用户可以访问此项目.',
|
||||
|
@ -213,6 +213,7 @@ return array(
|
|||
'Invalid date' => '无效日期',
|
||||
'Must be done before %B %e, %Y' => '必须在%Y/%m/%d前完成',
|
||||
'%B %e, %Y' => '%Y/%m/%d',
|
||||
// '%b %e, %Y' => '',
|
||||
'Automatic actions' => '自动动作',
|
||||
'Your automatic action have been created successfully.' => '您的自动动作已成功创建',
|
||||
'Unable to create your automatic action.' => '无法为您创建自动动作。',
|
||||
|
@ -231,7 +232,7 @@ return array(
|
|||
'Next step' => '下一步',
|
||||
'Define action parameters' => '定义动作参数',
|
||||
'Save this action' => '保存该动作',
|
||||
'Do you really want to remove this action: "%s"?' => '确定要移除该动作"%s"吗?',
|
||||
'Do you really want to remove this action: "%s"?' => '确定要移除动作"%s"吗?',
|
||||
'Remove an automatic action' => '移除一个自动动作',
|
||||
'Close the task' => '关闭任务',
|
||||
'Assign the task to a specific user' => '将该任务指派给一个用户',
|
||||
|
@ -285,7 +286,7 @@ return array(
|
|||
'Nothing found.' => '没找到。',
|
||||
'Search in the project "%s"' => '在项目"%s"中查找',
|
||||
'Due date' => '到期时间',
|
||||
'Others formats accepted: %s and %s' => '允许其他格式:%s 和 %s',
|
||||
'Others formats accepted: %s and %s' => '可以使用的其它格式:%s 和 %s',
|
||||
'Description' => '描述',
|
||||
'%d comments' => '%d个评论',
|
||||
'%d comment' => '%d个评论',
|
||||
|
@ -323,7 +324,7 @@ return array(
|
|||
'Category Name' => '分类名称',
|
||||
'Categories for the project "%s"' => '项目"%s"的分类',
|
||||
'Add a new category' => '加入新分类',
|
||||
'Do you really want to remove this category: "%s"?' => '您确定要移除分类"%s"吗?',
|
||||
'Do you really want to remove this category: "%s"?' => '确定要移除分类"%s"吗?',
|
||||
'Filter by category' => '按分类过滤',
|
||||
'All categories' => '所有分类',
|
||||
'No category' => '无分类',
|
||||
|
@ -332,7 +333,7 @@ return array(
|
|||
'Unable to remove this file.' => '无法移除该文件。',
|
||||
'File removed successfully.' => '文件成功移除。',
|
||||
'Attach a document' => '附加文档',
|
||||
'Do you really want to remove this file: "%s"?' => '您确定要移除文件"%s"吗?',
|
||||
'Do you really want to remove this file: "%s"?' => '确定要移除文件"%s"吗?',
|
||||
'open' => '打开',
|
||||
'Attachments' => '附件',
|
||||
'Edit the task' => '修改任务',
|
||||
|
@ -375,7 +376,7 @@ return array(
|
|||
'Login with my GitHub Account' => '用Github账号登录',
|
||||
'Link my GitHub Account' => '链接GitHub账号',
|
||||
'Unlink my GitHub Account' => '取消GitHub账号链接',
|
||||
'Created by %s' => '创建者:',
|
||||
'Created by %s' => '创建者:%s',
|
||||
'Last modified on %B %e, %Y at %k:%M %p' => '最后修改:%Y/%m/%d/ %H:%M',
|
||||
'Tasks Export' => '任务导出',
|
||||
'Tasks exportation for "%s"' => '导出任务"%s"',
|
||||
|
@ -468,20 +469,20 @@ return array(
|
|||
'Unable to change the password.' => '无法修改密码。',
|
||||
'Change category for the task "%s"' => '变更任务 "%s" 的分类',
|
||||
'Change category' => '变更分类',
|
||||
'%s updated the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s 更新了任务 <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s open the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s 开启了任务 <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s moved the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to the position #%d in the column "%s"' => '%s 将任务 <a href="?controller=task&action=show&task_id=%d">#%d</a> 移动到了"%s"的第#%d个位置',
|
||||
'%s moved the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to the column "%s"' => '%s 移动任务 <a href="?controller=task&action=show&task_id=%d">#%d</a> 到栏目 "%s"',
|
||||
'%s created the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s 创建了任务 <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s closed the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s 关闭了任务 <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s created a subtask for the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s 创建了 <a href="?controller=task&action=show&task_id=%d">#%d</a>的子任务',
|
||||
'%s updated a subtask for the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s 更新了 <a href="?controller=task&action=show&task_id=%d">#%d</a>的子任务',
|
||||
'%s updated the task %s' => '%s 更新了任务 %s',
|
||||
'%s opened the task %s' => '%s 开启了任务 %s',
|
||||
'%s moved the task %s to the position #%d in the column "%s"' => '%s 将任务 %s 移动到了"%s"的第#%d个位置',
|
||||
'%s moved the task %s to the column "%s"' => '%s 移动任务 %s 到栏目 "%s"',
|
||||
'%s created the task %s' => '%s 创建了任务 %s',
|
||||
'%s closed the task %s' => '%s 关闭了任务 %s',
|
||||
'%s created a subtask for the task %s' => '%s 创建了 %s的子任务',
|
||||
'%s updated a subtask for the task %s' => '%s 更新了 %s的子任务',
|
||||
'Assigned to %s with an estimate of %s/%sh' => '分配给 %s,预估需要 %s/%s 小时',
|
||||
'Not assigned, estimate of %sh' => '未分配,预估需要 %s 小时',
|
||||
'%s updated a comment on the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s 更新了任务 <a href="?controller=task&action=show&task_id=%d">#%d</a>的评论',
|
||||
'%s commented the task <a href="?controller=task&action=show&task_id=%d">#%d</a>' => '%s 评论了任务 <a href="?controller=task&action=show&task_id=%d">#%d</a>',
|
||||
'%s\'s activity' => '%s的活动',
|
||||
'No activity.' => '无活动',
|
||||
'%s updated a comment on the task %s' => '%s 更新了任务 %s的评论',
|
||||
'%s commented the task %s' => '%s 评论了任务 %s',
|
||||
'%s\'s activity' => '%s的动态',
|
||||
'No activity.' => '无动态',
|
||||
'RSS feed' => 'RSS 链接',
|
||||
'%s updated a comment on the task #%d' => '%s 更新了任务 #%d 的评论',
|
||||
'%s commented on the task #%d' => '%s 评论了任务 #%d',
|
||||
|
@ -493,12 +494,12 @@ return array(
|
|||
'%s open the task #%d' => '%s 开启了任务 #%d',
|
||||
'%s moved the task #%d to the column "%s"' => '%s 将任务 #%d 移动到栏目 "%s"',
|
||||
'%s moved the task #%d to the position %d in the column "%s"' => '%s将任务#%d移动到"%s"的第 %d 列',
|
||||
'Activity' => '活动',
|
||||
'Activity' => '动态',
|
||||
'Default values are "%s"' => '默认值为 "%s"',
|
||||
'Default columns for new projects (Comma-separated)' => '新建项目的默认栏目(用逗号分开)',
|
||||
'Task assignee change' => '任务分配变更',
|
||||
'%s change the assignee of the task #%d to %s' => '%s 将任务 #%d 分配给了 %s',
|
||||
'%s change the assignee of the task <a href="?controller=task&action=show&task_id=%d">#%d</a> to %s' => '%s 将任务 <a href="?controller=task&action=show&task_id=%d">#%d</a> 分配给 %s',
|
||||
'%s changed the assignee of the task %s to %s' => '%s 将任务 %s 分配给 %s',
|
||||
'[%s][Column Change] %s (#%d)' => '[%s][栏目变更] %s (#%d)',
|
||||
'[%s][Position Change] %s (#%d)' => '[%s][位置变更] %s (#%d)',
|
||||
'[%s][Assignee Change] %s (#%d)' => '[%s][任务分配变更] %s (#%d)',
|
||||
|
@ -547,7 +548,7 @@ return array(
|
|||
'Time estimated' => '预计时间',
|
||||
'There is nothing assigned to you.' => '无任务指派给你。',
|
||||
'My tasks' => '我的任务',
|
||||
'Activity stream' => '活动流',
|
||||
'Activity stream' => '动态记录',
|
||||
'Dashboard' => '面板',
|
||||
'Confirmation' => '确认',
|
||||
'Allow everybody to access to this project' => '允许所有人访问此项目',
|
||||
|
@ -555,8 +556,8 @@ return array(
|
|||
'Webhooks' => '网络钩子',
|
||||
'API' => '应用程序接口',
|
||||
'Integration' => '整合',
|
||||
'Github webhook' => 'Github 网络钩子',
|
||||
'Help on Github webhook' => 'Github 网络钩子帮助',
|
||||
'Github webhooks' => 'Github 网络钩子',
|
||||
'Help on Github webhooks' => 'Github 网络钩子帮助',
|
||||
'Create a comment from an external provider' => '从外部创建一个评论',
|
||||
'Github issue comment created' => '已经创建了Github问题评论',
|
||||
'Configure' => '配置',
|
||||
|
@ -602,4 +603,49 @@ return array(
|
|||
'Nothing to preview...' => '没有需要预览的内容',
|
||||
'Preview' => '预览',
|
||||
'Write' => '书写',
|
||||
'Active swimlanes' => '活动泳道',
|
||||
'Add a new swimlane' => '添加新泳道',
|
||||
'Change default swimlane' => '修改默认泳道',
|
||||
'Default swimlane' => '默认泳道',
|
||||
'Do you really want to remove this swimlane: "%s"?' => '确定要删除泳道:"%s"?',
|
||||
'Inactive swimlanes' => '非活动泳道',
|
||||
// 'Set project manager' => '',
|
||||
// 'Set project member' => '',
|
||||
'Remove a swimlane' => '删除泳道',
|
||||
'Rename' => '重命名',
|
||||
'Show default swimlane' => '显示默认泳道',
|
||||
'Swimlane modification for the project "%s"' => '项目"%s"的泳道变更',
|
||||
'Swimlane not found.' => '未找到泳道。',
|
||||
'Swimlane removed successfully.' => '成功删除泳道',
|
||||
'Swimlanes' => '泳道',
|
||||
'Swimlane updated successfully.' => '成功更新了泳道。',
|
||||
'The default swimlane have been updated successfully.' => '成功更新了默认泳道。',
|
||||
'Unable to create your swimlane.' => '无法创建泳道。',
|
||||
'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)' => '',
|
||||
// 'Gitlab commit received' => '',
|
||||
// 'Gitlab issue opened' => '',
|
||||
// 'Gitlab issue closed' => '',
|
||||
// 'Gitlab webhooks' => '',
|
||||
// 'Help on Gitlab webhooks' => '',
|
||||
// 'Integrations' => '',
|
||||
// 'Integration with third-party services' => '',
|
||||
// 'Role for this project' => '',
|
||||
// 'Project manager' => '',
|
||||
// 'Project member' => '',
|
||||
// 'A project manager can change the settings of the project and have more privileges than a standard user.' => '',
|
||||
// 'Gitlab Issue' => '',
|
||||
// 'Subtask Id' => '',
|
||||
// 'Subtasks' => '',
|
||||
// 'Subtasks Export' => '',
|
||||
// 'Subtasks exportation for "%s"' => '',
|
||||
// 'Task Title' => '',
|
||||
// 'Untitled' => '',
|
||||
// 'Application default' => '',
|
||||
// 'Language:' => '',
|
||||
// 'Timezone:' => '',
|
||||
// 'Next' => '',
|
||||
);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
namespace Model;
|
||||
|
||||
/**
|
||||
* Acl model
|
||||
* Access List
|
||||
*
|
||||
* @package model
|
||||
* @author Frederic Guillot
|
||||
|
@ -16,36 +16,59 @@ class Acl extends Base
|
|||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $public_actions = array(
|
||||
private $public_acl = array(
|
||||
'user' => array('login', 'check', 'google', 'github'),
|
||||
'task' => array('readonly'),
|
||||
'board' => array('readonly'),
|
||||
'project' => array('feed'),
|
||||
'webhook' => array('task', 'github'),
|
||||
'webhook' => '*',
|
||||
);
|
||||
|
||||
/**
|
||||
* Controllers and actions allowed for regular users
|
||||
* Controllers and actions for project members
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $user_actions = array(
|
||||
'app' => array('index', 'preview', 'status'),
|
||||
'project' => array('index', 'show', 'exporttasks', 'exportdaily', 'share', 'edit', 'update', 'users', 'remove', 'duplicate', 'disable', 'enable', 'activity', 'search', 'tasks', 'create', 'save'),
|
||||
'board' => array('index', 'show', 'save', 'check', 'changeassignee', 'updateassignee', 'changecategory', 'updatecategory', 'movecolumn', 'edit', 'update', 'add', 'confirm', 'remove', 'subtasks', 'togglesubtask', 'attachments', 'comments', 'description'),
|
||||
'user' => array('edit', 'forbidden', 'logout', 'show', 'external', 'unlinkgoogle', 'unlinkgithub', 'sessions', 'removesession', 'last', 'notifications', 'password'),
|
||||
'comment' => array('create', 'save', 'confirm', 'remove', 'update', 'edit', 'forbidden'),
|
||||
'file' => array('create', 'save', 'download', 'confirm', 'remove', 'open', 'image'),
|
||||
'subtask' => array('create', 'save', 'edit', 'update', 'confirm', 'remove', 'togglestatus'),
|
||||
'task' => array('show', 'create', 'save', 'edit', 'update', 'close', 'open', 'duplicate', 'remove', 'description', 'move', 'copy', 'time'),
|
||||
'category' => array('index', 'save', 'edit', 'update', 'confirm', 'remove'),
|
||||
'action' => array('index', 'event', 'params', 'create', 'confirm', 'remove'),
|
||||
'analytic' => array('tasks', 'users', 'cfd'),
|
||||
private $member_acl = array(
|
||||
'board' => '*',
|
||||
'comment' => '*',
|
||||
'file' => '*',
|
||||
'project' => array('show', 'tasks', 'search', 'activity'),
|
||||
'subtask' => '*',
|
||||
'task' => '*',
|
||||
);
|
||||
|
||||
/**
|
||||
* Return true if the specified controller/action is allowed according to the given acl
|
||||
* Controllers and actions for project managers
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $manager_acl = array(
|
||||
'action' => '*',
|
||||
'analytic' => '*',
|
||||
'board' => array('movecolumn', 'edit', 'update', 'add', 'remove'),
|
||||
'category' => '*',
|
||||
'export' => array('tasks', 'subtasks', 'summary'),
|
||||
'project' => array('edit', 'update', 'share', 'integration', 'users', 'alloweverybody', 'allow', 'setowner', 'revoke', 'duplicate', 'disable', 'enable'),
|
||||
'swimlane' => '*',
|
||||
);
|
||||
|
||||
/**
|
||||
* Controllers and actions for admins
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $admin_acl = array(
|
||||
'user' => array('index', 'create', 'save', 'remove'),
|
||||
'config' => '*',
|
||||
'project' => array('remove'),
|
||||
);
|
||||
|
||||
/**
|
||||
* Return true if the specified controller/action match the given acl
|
||||
*
|
||||
* @access public
|
||||
* @param array $acl Acl list
|
||||
|
@ -53,13 +76,27 @@ class Acl extends Base
|
|||
* @param string $action Action name
|
||||
* @return bool
|
||||
*/
|
||||
public function isAllowedAction(array $acl, $controller, $action)
|
||||
public function matchAcl(array $acl, $controller, $action)
|
||||
{
|
||||
if (isset($acl[$controller])) {
|
||||
return in_array($action, $acl[$controller]);
|
||||
$action = strtolower($action);
|
||||
return isset($acl[$controller]) && $this->hasAction($action, $acl[$controller]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the specified action is inside the list of actions
|
||||
*
|
||||
* @access public
|
||||
* @param string $action Action name
|
||||
* @param mixed $action Actions list
|
||||
* @return bool
|
||||
*/
|
||||
public function hasAction($action, $actions)
|
||||
{
|
||||
if (is_array($actions)) {
|
||||
return in_array($action, $actions);
|
||||
}
|
||||
|
||||
return false;
|
||||
return $actions === '*';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -72,94 +109,90 @@ class Acl extends Base
|
|||
*/
|
||||
public function isPublicAction($controller, $action)
|
||||
{
|
||||
return $this->isAllowedAction($this->public_actions, $controller, $action);
|
||||
return $this->matchAcl($this->public_acl, $controller, $action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the given action is allowed for a regular user
|
||||
* Return true if the given action is for admins
|
||||
*
|
||||
* @access public
|
||||
* @param string $controller Controller name
|
||||
* @param string $action Action name
|
||||
* @return bool
|
||||
*/
|
||||
public function isUserAction($controller, $action)
|
||||
public function isAdminAction($controller, $action)
|
||||
{
|
||||
return $this->isAllowedAction($this->user_actions, $controller, $action);
|
||||
return $this->matchAcl($this->admin_acl, $controller, $action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the logged user is admin
|
||||
* Return true if the given action is for project managers
|
||||
*
|
||||
* @access public
|
||||
* @param string $controller Controller name
|
||||
* @param string $action Action name
|
||||
* @return bool
|
||||
*/
|
||||
public function isAdminUser()
|
||||
public function isManagerAction($controller, $action)
|
||||
{
|
||||
return isset($_SESSION['user']['is_admin']) && $_SESSION['user']['is_admin'] === true;
|
||||
return $this->matchAcl($this->manager_acl, $controller, $action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the logged user is not admin
|
||||
* Return true if the given action is for project members
|
||||
*
|
||||
* @access public
|
||||
* @param string $controller Controller name
|
||||
* @param string $action Action name
|
||||
* @return bool
|
||||
*/
|
||||
public function isRegularUser()
|
||||
public function isMemberAction($controller, $action)
|
||||
{
|
||||
return isset($_SESSION['user']['is_admin']) && $_SESSION['user']['is_admin'] === false;
|
||||
return $this->matchAcl($this->member_acl, $controller, $action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the connected user id
|
||||
*
|
||||
* @access public
|
||||
* @return integer
|
||||
*/
|
||||
public function getUserId()
|
||||
{
|
||||
return isset($_SESSION['user']['id']) ? (int) $_SESSION['user']['id'] : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check is the user is connected
|
||||
* Return true if the visitor is allowed to access to the given page
|
||||
* We suppose the user already authenticated
|
||||
*
|
||||
* @access public
|
||||
* @param string $controller Controller name
|
||||
* @param string $action Action name
|
||||
* @param integer $project_id Project id
|
||||
* @return bool
|
||||
*/
|
||||
public function isLogged()
|
||||
public function isAllowed($controller, $action, $project_id = 0)
|
||||
{
|
||||
return ! empty($_SESSION['user']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check is the user was authenticated with the RememberMe or set the value
|
||||
*
|
||||
* @access public
|
||||
* @param bool $value Set true if the user use the RememberMe
|
||||
* @return bool
|
||||
*/
|
||||
public function isRememberMe($value = null)
|
||||
{
|
||||
if ($value !== null) {
|
||||
$_SESSION['is_remember_me'] = $value;
|
||||
// If you are admin you have access to everything
|
||||
if ($this->userSession->isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return empty($_SESSION['is_remember_me']) ? false : $_SESSION['is_remember_me'];
|
||||
// If you access to an admin action, your are not allowed
|
||||
if ($this->isAdminAction($controller, $action)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check project manager permissions
|
||||
if ($this->isManagerAction($controller, $action)) {
|
||||
return $this->isManagerActionAllowed($project_id);
|
||||
}
|
||||
|
||||
// Check project member permissions
|
||||
if ($this->isMemberAction($controller, $action)) {
|
||||
return $project_id > 0 && $this->projectPermission->isMember($project_id, $this->userSession->getId());
|
||||
}
|
||||
|
||||
// Other applications actions are allowed
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an action is allowed for the logged user
|
||||
*
|
||||
* @access public
|
||||
* @param string $controller Controller name
|
||||
* @param string $action Action name
|
||||
* @return bool
|
||||
*/
|
||||
public function isPageAccessAllowed($controller, $action)
|
||||
public function isManagerActionAllowed($project_id)
|
||||
{
|
||||
return $this->isPublicAction($controller, $action) ||
|
||||
$this->isAdminUser() ||
|
||||
($this->isRegularUser() && $this->isUserAction($controller, $action));
|
||||
if ($this->userSession->isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $project_id > 0 && $this->projectPermission->isManager($project_id, $this->userSession->getId());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
namespace Model;
|
||||
|
||||
use LogicException;
|
||||
use Integration\GitlabWebhook;
|
||||
use Integration\GithubWebhook;
|
||||
use SimpleValidator\Validator;
|
||||
use SimpleValidator\Validators;
|
||||
|
||||
|
@ -80,6 +81,9 @@ class Action extends Base
|
|||
GithubWebhook::EVENT_ISSUE_ASSIGNEE_CHANGE => t('Github issue assignee change'),
|
||||
GithubWebhook::EVENT_ISSUE_LABEL_CHANGE => t('Github issue label change'),
|
||||
GithubWebhook::EVENT_ISSUE_COMMENT => t('Github issue comment created'),
|
||||
GitlabWebhook::EVENT_COMMIT => t('Gitlab commit received'),
|
||||
GitlabWebhook::EVENT_ISSUE_OPENED => t('Gitlab issue opened'),
|
||||
GitlabWebhook::EVENT_ISSUE_CLOSED => t('Gitlab issue closed'),
|
||||
);
|
||||
|
||||
asort($values);
|
||||
|
@ -136,9 +140,17 @@ class Action extends Base
|
|||
public function getAll()
|
||||
{
|
||||
$actions = $this->db->table(self::TABLE)->findAll();
|
||||
$params = $this->db->table(self::TABLE_PARAMS)->findAll();
|
||||
|
||||
foreach ($actions as &$action) {
|
||||
$action['params'] = $this->db->table(self::TABLE_PARAMS)->eq('action_id', $action['id'])->findAll();
|
||||
|
||||
$action['params'] = array();
|
||||
|
||||
foreach ($params as $param) {
|
||||
if ($param['action_id'] === $action['id']) {
|
||||
$action['params'][] = $param;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $actions;
|
||||
|
@ -187,6 +199,7 @@ class Action extends Base
|
|||
*/
|
||||
public function remove($action_id)
|
||||
{
|
||||
// $this->container['fileCache']->remove('proxy_action_getAll');
|
||||
return $this->db->table(self::TABLE)->eq('id', $action_id)->remove();
|
||||
}
|
||||
|
||||
|
@ -230,6 +243,8 @@ class Action extends Base
|
|||
|
||||
$this->db->closeTransaction();
|
||||
|
||||
// $this->container['fileCache']->remove('proxy_action_getAll');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -240,7 +255,10 @@ class Action extends Base
|
|||
*/
|
||||
public function attachEvents()
|
||||
{
|
||||
foreach ($this->getAll() as $action) {
|
||||
//$actions = $this->container['fileCache']->proxy('action', 'getAll');
|
||||
$actions = $this->getAll();
|
||||
|
||||
foreach ($actions as $action) {
|
||||
|
||||
$listener = $this->load($action['action_name'], $action['project_id'], $action['event_name']);
|
||||
|
||||
|
@ -248,7 +266,7 @@ class Action extends Base
|
|||
$listener->setParam($param['name'], $param['value']);
|
||||
}
|
||||
|
||||
$this->event->attach($action['event_name'], $listener);
|
||||
$this->container['dispatcher']->addListener($action['event_name'], array($listener, 'execute'));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -303,6 +321,8 @@ class Action extends Base
|
|||
}
|
||||
}
|
||||
|
||||
// $this->container['fileCache']->remove('proxy_action_getAll');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
namespace Model;
|
||||
|
||||
use Core\Request;
|
||||
use Auth\Database;
|
||||
use SimpleValidator\Validator;
|
||||
use SimpleValidator\Validators;
|
||||
|
||||
|
@ -36,19 +35,12 @@ class Authentication extends Base
|
|||
* Check if the current user is authenticated
|
||||
*
|
||||
* @access public
|
||||
* @param string $controller Controller
|
||||
* @param string $action Action name
|
||||
* @return bool
|
||||
*/
|
||||
public function isAuthenticated($controller, $action)
|
||||
public function isAuthenticated()
|
||||
{
|
||||
// If the action is public we don't need to do any checks
|
||||
if ($this->acl->isPublicAction($controller, $action)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If the user is already logged it's ok
|
||||
if ($this->acl->isLogged()) {
|
||||
if ($this->userSession->isLogged()) {
|
||||
|
||||
// We update each time the RememberMe cookie tokens
|
||||
if ($this->backend('rememberMe')->hasCookie()) {
|
||||
|
@ -118,7 +110,7 @@ class Authentication extends Base
|
|||
if (! empty($values['remember_me'])) {
|
||||
|
||||
$credentials = $this->backend('rememberMe')
|
||||
->create($this->acl->getUserId(), Request::getIpAddress(), Request::getUserAgent());
|
||||
->create($this->userSession->getId(), Request::getIpAddress(), Request::getUserAgent());
|
||||
|
||||
$this->backend('rememberMe')->writeCookie($credentials['token'], $credentials['sequence'], $credentials['expiration']);
|
||||
}
|
||||
|
|
|
@ -2,10 +2,7 @@
|
|||
|
||||
namespace Model;
|
||||
|
||||
use Core\Event;
|
||||
use Core\Tool;
|
||||
use Pimple\Container;
|
||||
use PicoDb\Database;
|
||||
|
||||
/**
|
||||
* Base model class
|
||||
|
@ -13,6 +10,8 @@ use PicoDb\Database;
|
|||
* @package model
|
||||
* @author Frederic Guillot
|
||||
*
|
||||
* @property \Core\Session $session
|
||||
* @property \Core\Template $template
|
||||
* @property \Model\Acl $acl
|
||||
* @property \Model\Action $action
|
||||
* @property \Model\Authentication $authentication
|
||||
|
@ -30,6 +29,7 @@ use PicoDb\Database;
|
|||
* @property \Model\ProjectPermission $projectPermission
|
||||
* @property \Model\SubTask $subTask
|
||||
* @property \Model\SubtaskHistory $subtaskHistory
|
||||
* @property \Model\Swimlane $swimlane
|
||||
* @property \Model\Task $task
|
||||
* @property \Model\TaskCreation $taskCreation
|
||||
* @property \Model\TaskExport $taskExport
|
||||
|
@ -39,6 +39,7 @@ use PicoDb\Database;
|
|||
* @property \Model\TaskValidator $taskValidator
|
||||
* @property \Model\TimeTracking $timeTracking
|
||||
* @property \Model\User $user
|
||||
* @property \Model\UserSession $userSession
|
||||
* @property \Model\Webhook $webhook
|
||||
*/
|
||||
abstract class Base
|
||||
|
@ -51,14 +52,6 @@ abstract class Base
|
|||
*/
|
||||
protected $db;
|
||||
|
||||
/**
|
||||
* Event dispatcher instance
|
||||
*
|
||||
* @access public
|
||||
* @var \Core\Event
|
||||
*/
|
||||
public $event;
|
||||
|
||||
/**
|
||||
* Container instance
|
||||
*
|
||||
|
@ -77,7 +70,6 @@ abstract class Base
|
|||
{
|
||||
$this->container = $container;
|
||||
$this->db = $this->container['db'];
|
||||
$this->event = $this->container['event'];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -89,7 +81,7 @@ abstract class Base
|
|||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
return Tool::loadModel($this->container, $name);
|
||||
return $this->container[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -117,7 +109,7 @@ abstract class Base
|
|||
*
|
||||
* @access public
|
||||
* @param array $values Input array
|
||||
* @param array $keys List of keys to remove
|
||||
* @param string[] $keys List of keys to remove
|
||||
*/
|
||||
public function removeFields(array &$values, array $keys)
|
||||
{
|
||||
|
@ -132,8 +124,8 @@ abstract class Base
|
|||
* Force some fields to be at 0 if empty
|
||||
*
|
||||
* @access public
|
||||
* @param array $values Input array
|
||||
* @param array $keys List of keys
|
||||
* @param array $values Input array
|
||||
* @param string[] $keys List of keys
|
||||
*/
|
||||
public function resetFields(array &$values, array $keys)
|
||||
{
|
||||
|
@ -148,8 +140,8 @@ abstract class Base
|
|||
* Force some fields to be integer
|
||||
*
|
||||
* @access public
|
||||
* @param array $values Input array
|
||||
* @param array $keys List of keys
|
||||
* @param array $values Input array
|
||||
* @param string[] $keys List of keys
|
||||
*/
|
||||
public function convertIntegerFields(array &$values, array $keys)
|
||||
{
|
||||
|
|
|
@ -24,7 +24,7 @@ class Board extends Base
|
|||
* Get Kanboard default columns
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
* @return string[]
|
||||
*/
|
||||
public function getDefaultColumns()
|
||||
{
|
||||
|
@ -227,29 +227,47 @@ class Board extends Base
|
|||
}
|
||||
|
||||
/**
|
||||
* Get all columns and tasks for a given project
|
||||
* Get all tasks sorted by columns and swimlanes
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
* @return array
|
||||
*/
|
||||
public function get($project_id)
|
||||
public function getBoard($project_id)
|
||||
{
|
||||
$swimlanes = $this->swimlane->getSwimlanes($project_id);
|
||||
$columns = $this->getColumns($project_id);
|
||||
$tasks = $this->taskFinder->getTasksOnBoard($project_id);
|
||||
$nb_columns = count($columns);
|
||||
|
||||
foreach ($columns as &$column) {
|
||||
for ($i = 0, $ilen = count($swimlanes); $i < $ilen; $i++) {
|
||||
|
||||
$column['tasks'] = array();
|
||||
$swimlanes[$i]['columns'] = $columns;
|
||||
$swimlanes[$i]['nb_columns'] = $nb_columns;
|
||||
|
||||
foreach ($tasks as &$task) {
|
||||
if ($task['column_id'] == $column['id']) {
|
||||
$column['tasks'][] = $task;
|
||||
}
|
||||
for ($j = 0; $j < $nb_columns; $j++) {
|
||||
$swimlanes[$i]['columns'][$j]['tasks'] = $this->taskFinder->getTasksByColumnAndSwimlane($project_id, $columns[$j]['id'], $swimlanes[$i]['id']);
|
||||
$swimlanes[$i]['columns'][$j]['nb_tasks'] = count($swimlanes[$i]['columns'][$j]['tasks']);
|
||||
}
|
||||
}
|
||||
|
||||
return $columns;
|
||||
return $swimlanes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the total of tasks per column
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id
|
||||
* @return array
|
||||
*/
|
||||
public function getColumnStats($project_id)
|
||||
{
|
||||
return $this->db
|
||||
->table(Task::TABLE)
|
||||
->eq('project_id', $project_id)
|
||||
->eq('is_active', 1)
|
||||
->groupBy('column_id')
|
||||
->listing('column_id', 'COUNT(*) AS total');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Model;
|
||||
|
||||
use Event\CommentEvent;
|
||||
use SimpleValidator\Validator;
|
||||
use SimpleValidator\Validators;
|
||||
|
||||
|
@ -107,7 +108,7 @@ class Comment extends Base
|
|||
$comment_id = $this->persist(self::TABLE, $values);
|
||||
|
||||
if ($comment_id) {
|
||||
$this->event->trigger(self::EVENT_CREATE, array('id' => $comment_id) + $values);
|
||||
$this->container['dispatcher']->dispatch(self::EVENT_CREATE, new CommentEvent(array('id' => $comment_id) + $values));
|
||||
}
|
||||
|
||||
return $comment_id;
|
||||
|
@ -127,7 +128,7 @@ class Comment extends Base
|
|||
->eq('id', $values['id'])
|
||||
->update(array('comment' => $values['comment']));
|
||||
|
||||
$this->event->trigger(self::EVENT_UPDATE, $values);
|
||||
$this->container['dispatcher']->dispatch(self::EVENT_UPDATE, new CommentEvent($values));
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
namespace Model;
|
||||
|
||||
use SimpleValidator\Validator;
|
||||
use SimpleValidator\Validators;
|
||||
use Core\Translator;
|
||||
use Core\Security;
|
||||
use Core\Session;
|
||||
|
@ -27,30 +25,39 @@ class Config extends Base
|
|||
* Get available timezones
|
||||
*
|
||||
* @access public
|
||||
* @param boolean $prepend Prepend a default value
|
||||
* @return array
|
||||
*/
|
||||
public function getTimezones()
|
||||
public function getTimezones($prepend = false)
|
||||
{
|
||||
$timezones = timezone_identifiers_list();
|
||||
return array_combine(array_values($timezones), $timezones);
|
||||
$listing = array_combine(array_values($timezones), $timezones);
|
||||
|
||||
if ($prepend) {
|
||||
return array('' => t('Application default')) + $listing;
|
||||
}
|
||||
|
||||
return $listing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get available languages
|
||||
*
|
||||
* @access public
|
||||
* @param boolean $prepend Prepend a default value
|
||||
* @return array
|
||||
*/
|
||||
public function getLanguages()
|
||||
public function getLanguages($prepend = false)
|
||||
{
|
||||
// Sorted by value
|
||||
return array(
|
||||
$languages = array(
|
||||
'da_DK' => 'Dansk',
|
||||
'de_DE' => 'Deutsch',
|
||||
'en_US' => 'English',
|
||||
'es_ES' => 'Español',
|
||||
'fr_FR' => 'Français',
|
||||
'it_IT' => 'Italiano',
|
||||
'hu_HU' => 'Magyar',
|
||||
'pl_PL' => 'Polski',
|
||||
'pt_BR' => 'Português (Brasil)',
|
||||
'ru_RU' => 'Русский',
|
||||
|
@ -60,6 +67,12 @@ class Config extends Base
|
|||
'ja_JP' => '日本語',
|
||||
'th_TH' => 'ไทย',
|
||||
);
|
||||
|
||||
if ($prepend) {
|
||||
return array('' => t('Application default')) + $languages;
|
||||
}
|
||||
|
||||
return $languages;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -77,12 +90,13 @@ class Config extends Base
|
|||
return $value ?: $default_value;
|
||||
}
|
||||
|
||||
if (! isset($_SESSION['config'][$name])) {
|
||||
$_SESSION['config'] = $this->getAll();
|
||||
// Cache config in session
|
||||
if (! isset($this->session['config'][$name])) {
|
||||
$this->session['config'] = $this->getAll();
|
||||
}
|
||||
|
||||
if (! empty($_SESSION['config'][$name])) {
|
||||
return $_SESSION['config'][$name];
|
||||
if (! empty($this->session['config'][$name])) {
|
||||
return $this->session['config'][$name];
|
||||
}
|
||||
|
||||
return $default_value;
|
||||
|
@ -127,7 +141,7 @@ class Config extends Base
|
|||
*/
|
||||
public function reload()
|
||||
{
|
||||
$_SESSION['config'] = $this->getAll();
|
||||
$this->session['config'] = $this->getAll();
|
||||
$this->setupTranslations();
|
||||
}
|
||||
|
||||
|
@ -138,10 +152,11 @@ class Config extends Base
|
|||
*/
|
||||
public function setupTranslations()
|
||||
{
|
||||
$language = $this->get('application_language', 'en_US');
|
||||
|
||||
if ($language !== 'en_US') {
|
||||
Translator::load($language);
|
||||
if ($this->userSession->isLogged() && ! empty($this->session['user']['language'])) {
|
||||
Translator::load($this->session['user']['language']);
|
||||
}
|
||||
else {
|
||||
Translator::load($this->get('application_language', 'en_US'));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,7 +167,12 @@ class Config extends Base
|
|||
*/
|
||||
public function setupTimezone()
|
||||
{
|
||||
date_default_timezone_set($this->get('application_timezone', 'UTC'));
|
||||
if ($this->userSession->isLogged() && ! empty($this->session['user']['timezone'])) {
|
||||
date_default_timezone_set($this->session['user']['timezone']);
|
||||
}
|
||||
else {
|
||||
date_default_timezone_set($this->get('application_timezone', 'UTC'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -60,7 +60,7 @@ class DateParser extends Base
|
|||
* Return the list of supported date formats (for the parser)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
* @return string[]
|
||||
*/
|
||||
public function getDateFormats()
|
||||
{
|
||||
|
@ -103,7 +103,7 @@ class DateParser extends Base
|
|||
*
|
||||
* @access public
|
||||
* @param array $values Database values
|
||||
* @param array $fields Date fields
|
||||
* @param string[] $fields Date fields
|
||||
* @param string $format Date format
|
||||
*/
|
||||
public function format(array &$values, array $fields, $format = '')
|
||||
|
@ -128,7 +128,7 @@ class DateParser extends Base
|
|||
*
|
||||
* @access public
|
||||
* @param array $values Database values
|
||||
* @param array $fields Date fields
|
||||
* @param string[] $fields Date fields
|
||||
*/
|
||||
public function convert(array &$values, array $fields)
|
||||
{
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace Model;
|
||||
|
||||
use Event\FileEvent;
|
||||
|
||||
/**
|
||||
* File model
|
||||
*
|
||||
|
@ -89,7 +91,10 @@ class File extends Base
|
|||
*/
|
||||
public function create($task_id, $name, $path, $is_image)
|
||||
{
|
||||
$this->event->trigger(self::EVENT_CREATE, array('task_id' => $task_id, 'name' => $name));
|
||||
$this->container['dispatcher']->dispatch(
|
||||
self::EVENT_CREATE,
|
||||
new FileEvent(array('task_id' => $task_id, 'name' => $name))
|
||||
);
|
||||
|
||||
return $this->db->table(self::TABLE)->save(array(
|
||||
'task_id' => $task_id,
|
||||
|
|
|
@ -32,7 +32,7 @@ class LastLogin extends Base
|
|||
* @param integer $user_id User id
|
||||
* @param string $ip IP Address
|
||||
* @param string $user_agent User Agent
|
||||
* @return array
|
||||
* @return boolean
|
||||
*/
|
||||
public function create($auth_type, $user_id, $ip, $user_agent)
|
||||
{
|
||||
|
|
|
@ -3,9 +3,6 @@
|
|||
namespace Model;
|
||||
|
||||
use Core\Session;
|
||||
use Core\Translator;
|
||||
use Core\Template;
|
||||
use Event\NotificationListener;
|
||||
use Swift_Message;
|
||||
use Swift_Mailer;
|
||||
use Swift_TransportException;
|
||||
|
@ -29,8 +26,8 @@ class Notification extends Base
|
|||
* Get a list of people with notifications enabled
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
* @param array $exlude_users List of user_id to exclude
|
||||
* @param integer $project_id Project id
|
||||
* @param array $exclude_users List of user_id to exclude
|
||||
* @return array
|
||||
*/
|
||||
public function getUsersWithNotification($project_id, array $exclude_users = array())
|
||||
|
@ -61,15 +58,15 @@ class Notification extends Base
|
|||
* Get the list of users to send the notification for a given project
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
* @param array $exlude_users List of user_id to exclude
|
||||
* @param integer $project_id Project id
|
||||
* @param array $exclude_users List of user_id to exclude
|
||||
* @return array
|
||||
*/
|
||||
public function getUsersList($project_id, array $exclude_users = array())
|
||||
{
|
||||
// Exclude the connected user
|
||||
if (Session::isOpen()) {
|
||||
$exclude_users[] = $this->acl->getUserId();
|
||||
$exclude_users[] = $this->userSession->getId();
|
||||
}
|
||||
|
||||
$users = $this->getUsersWithNotification($project_id, $exclude_users);
|
||||
|
@ -93,37 +90,6 @@ class Notification extends Base
|
|||
return $users;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach events
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function attachEvents()
|
||||
{
|
||||
$events = array(
|
||||
Task::EVENT_CREATE => 'task_creation',
|
||||
Task::EVENT_UPDATE => 'task_update',
|
||||
Task::EVENT_CLOSE => 'task_close',
|
||||
Task::EVENT_OPEN => 'task_open',
|
||||
Task::EVENT_MOVE_COLUMN => 'task_move_column',
|
||||
Task::EVENT_MOVE_POSITION => 'task_move_position',
|
||||
Task::EVENT_ASSIGNEE_CHANGE => 'task_assignee_change',
|
||||
SubTask::EVENT_CREATE => 'subtask_creation',
|
||||
SubTask::EVENT_UPDATE => 'subtask_update',
|
||||
Comment::EVENT_CREATE => 'comment_creation',
|
||||
Comment::EVENT_UPDATE => 'comment_update',
|
||||
File::EVENT_CREATE => 'file_creation',
|
||||
);
|
||||
|
||||
foreach ($events as $event_name => $template_name) {
|
||||
|
||||
$listener = new NotificationListener($this->container);
|
||||
$listener->setTemplate($template_name);
|
||||
|
||||
$this->event->attach($event_name, $listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the email notifications
|
||||
*
|
||||
|
@ -148,7 +114,7 @@ class Notification extends Base
|
|||
}
|
||||
}
|
||||
catch (Swift_TransportException $e) {
|
||||
$this->container['logger']->addError($e->getMessage());
|
||||
$this->container['logger']->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -217,8 +183,10 @@ class Notification extends Base
|
|||
*/
|
||||
public function getMailContent($template, array $data)
|
||||
{
|
||||
$tpl = new Template;
|
||||
return $tpl->load('notification/'.$template, $data + array('application_url' => $this->config->get('application_url')));
|
||||
return $this->template->render(
|
||||
'notification/'.$template,
|
||||
$data + array('application_url' => $this->config->get('application_url'))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,7 +4,6 @@ namespace Model;
|
|||
|
||||
use SimpleValidator\Validator;
|
||||
use SimpleValidator\Validators;
|
||||
use Event\ProjectModificationDateListener;
|
||||
use Core\Security;
|
||||
|
||||
/**
|
||||
|
@ -52,12 +51,12 @@ class Project extends Base
|
|||
* Get a project by the name
|
||||
*
|
||||
* @access public
|
||||
* @param string $project_name Project name
|
||||
* @param string $name Project name
|
||||
* @return array
|
||||
*/
|
||||
public function getByName($project_name)
|
||||
public function getByName($name)
|
||||
{
|
||||
return $this->db->table(self::TABLE)->eq('name', $project_name)->findOne();
|
||||
return $this->db->table(self::TABLE)->eq('name', $name)->findOne();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -110,7 +109,7 @@ class Project extends Base
|
|||
|
||||
foreach ($projects as $key => $project) {
|
||||
|
||||
if (! $this->projectPermission->isUserAllowed($project['id'], $this->acl->getUserId())) {
|
||||
if (! $this->projectPermission->isUserAllowed($project['id'], $this->userSession->getId())) {
|
||||
unset($projects[$key]);
|
||||
}
|
||||
}
|
||||
|
@ -192,11 +191,12 @@ class Project extends Base
|
|||
public function getStats($project_id)
|
||||
{
|
||||
$stats = array();
|
||||
$columns = $this->board->getColumns($project_id);
|
||||
$stats['nb_active_tasks'] = 0;
|
||||
$columns = $this->board->getColumns($project_id);
|
||||
$column_stats = $this->board->getColumnStats($project_id);
|
||||
|
||||
foreach ($columns as &$column) {
|
||||
$column['nb_active_tasks'] = $this->taskFinder->countByColumnId($project_id, $column['id']);
|
||||
$column['nb_active_tasks'] = isset($column_stats[$column['id']]) ? $column_stats[$column['id']] : 0;
|
||||
$stats['nb_active_tasks'] += $column['nb_active_tasks'];
|
||||
}
|
||||
|
||||
|
@ -228,7 +228,7 @@ class Project extends Base
|
|||
);
|
||||
|
||||
if (! $this->db->table(self::TABLE)->save($values)) {
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $this->db->getConnection()->getLastId();
|
||||
|
@ -296,9 +296,11 @@ class Project extends Base
|
|||
}
|
||||
|
||||
if ($add_user && $user_id) {
|
||||
$this->projectPermission->allowUser($project_id, $user_id);
|
||||
$this->projectPermission->addManager($project_id, $user_id);
|
||||
}
|
||||
|
||||
$this->category->createDefaultCategories($project_id);
|
||||
|
||||
$this->db->closeTransaction();
|
||||
|
||||
return (int) $project_id;
|
||||
|
@ -489,34 +491,4 @@ class Project extends Base
|
|||
$v->getErrors()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach events
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function attachEvents()
|
||||
{
|
||||
$events = array(
|
||||
Task::EVENT_CREATE_UPDATE,
|
||||
Task::EVENT_CLOSE,
|
||||
Task::EVENT_OPEN,
|
||||
Task::EVENT_MOVE_COLUMN,
|
||||
Task::EVENT_MOVE_POSITION,
|
||||
Task::EVENT_ASSIGNEE_CHANGE,
|
||||
GithubWebhook::EVENT_ISSUE_OPENED,
|
||||
GithubWebhook::EVENT_ISSUE_CLOSED,
|
||||
GithubWebhook::EVENT_ISSUE_REOPENED,
|
||||
GithubWebhook::EVENT_ISSUE_ASSIGNEE_CHANGE,
|
||||
GithubWebhook::EVENT_ISSUE_LABEL_CHANGE,
|
||||
GithubWebhook::EVENT_ISSUE_COMMENT,
|
||||
GithubWebhook::EVENT_COMMIT,
|
||||
);
|
||||
|
||||
$listener = new ProjectModificationDateListener($this->container);
|
||||
|
||||
foreach ($events as $event_name) {
|
||||
$this->event->attach($event_name, $listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,6 @@
|
|||
|
||||
namespace Model;
|
||||
|
||||
use Core\Template;
|
||||
use Event\ProjectActivityListener;
|
||||
|
||||
/**
|
||||
* Project activity model
|
||||
*
|
||||
|
@ -25,7 +22,7 @@ class ProjectActivity extends Base
|
|||
*
|
||||
* @var integer
|
||||
*/
|
||||
const MAX_EVENTS = 5000;
|
||||
const MAX_EVENTS = 1000;
|
||||
|
||||
/**
|
||||
* Add a new event for the project
|
||||
|
@ -46,7 +43,7 @@ class ProjectActivity extends Base
|
|||
'creator_id' => $creator_id,
|
||||
'event_name' => $event_name,
|
||||
'date_creation' => time(),
|
||||
'data' => serialize($data),
|
||||
'data' => json_encode($data),
|
||||
);
|
||||
|
||||
$this->cleanup(self::MAX_EVENTS - 1);
|
||||
|
@ -70,13 +67,13 @@ class ProjectActivity extends Base
|
|||
* Get all events for the given projects list
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
* @param integer[] $project_ids Projects id
|
||||
* @param integer $limit Maximum events number
|
||||
* @return array
|
||||
*/
|
||||
public function getProjects(array $projects, $limit = 50)
|
||||
public function getProjects(array $project_ids, $limit = 50)
|
||||
{
|
||||
if (empty($projects)) {
|
||||
if (empty($project_ids)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
|
@ -86,7 +83,7 @@ class ProjectActivity extends Base
|
|||
User::TABLE.'.username AS author_username',
|
||||
User::TABLE.'.name AS author_name'
|
||||
)
|
||||
->in('project_id', $projects)
|
||||
->in('project_id', $project_ids)
|
||||
->join(User::TABLE, 'id', 'creator_id')
|
||||
->desc('id')
|
||||
->limit($limit)
|
||||
|
@ -94,7 +91,7 @@ class ProjectActivity extends Base
|
|||
|
||||
foreach ($events as &$event) {
|
||||
|
||||
$event += unserialize($event['data']);
|
||||
$event += $this->decode($event['data']);
|
||||
unset($event['data']);
|
||||
|
||||
$event['author'] = $event['author_name'] ?: $event['author_username'];
|
||||
|
@ -126,34 +123,6 @@ class ProjectActivity extends Base
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach events to be able to record the history
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function attachEvents()
|
||||
{
|
||||
$events = array(
|
||||
Task::EVENT_ASSIGNEE_CHANGE,
|
||||
Task::EVENT_UPDATE,
|
||||
Task::EVENT_CREATE,
|
||||
Task::EVENT_CLOSE,
|
||||
Task::EVENT_OPEN,
|
||||
Task::EVENT_MOVE_COLUMN,
|
||||
Task::EVENT_MOVE_POSITION,
|
||||
Comment::EVENT_UPDATE,
|
||||
Comment::EVENT_CREATE,
|
||||
SubTask::EVENT_UPDATE,
|
||||
SubTask::EVENT_CREATE,
|
||||
);
|
||||
|
||||
$listener = new ProjectActivityListener($this->container);
|
||||
|
||||
foreach ($events as $event_name) {
|
||||
$this->event->attach($event_name, $listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the event html content
|
||||
*
|
||||
|
@ -163,8 +132,10 @@ class ProjectActivity extends Base
|
|||
*/
|
||||
public function getContent(array $params)
|
||||
{
|
||||
$tpl = new Template;
|
||||
return $tpl->load('event/'.str_replace('.', '_', $params['event_name']), $params);
|
||||
return $this->template->render(
|
||||
'event/'.str_replace('.', '_', $params['event_name']),
|
||||
$params
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -203,4 +174,20 @@ class ProjectActivity extends Base
|
|||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode event data, supports unserialize() and json_decode()
|
||||
*
|
||||
* @access public
|
||||
* @param string $data Serialized data
|
||||
* @return array
|
||||
*/
|
||||
public function decode($data)
|
||||
{
|
||||
if ($data{0} === 'a') {
|
||||
return unserialize($data);
|
||||
}
|
||||
|
||||
return json_decode($data, true) ?: array();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,6 @@
|
|||
|
||||
namespace Model;
|
||||
|
||||
use Core\Template;
|
||||
use Event\ProjectDailySummaryListener;
|
||||
|
||||
/**
|
||||
* Project daily summary
|
||||
*
|
||||
|
@ -157,25 +154,4 @@ class ProjectDailySummary extends Base
|
|||
|
||||
return $metrics;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach events to be able to record the metrics
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function attachEvents()
|
||||
{
|
||||
$events = array(
|
||||
Task::EVENT_CREATE,
|
||||
Task::EVENT_CLOSE,
|
||||
Task::EVENT_OPEN,
|
||||
Task::EVENT_MOVE_COLUMN,
|
||||
);
|
||||
|
||||
$listener = new ProjectDailySummaryListener($this->container);
|
||||
|
||||
foreach ($events as $event_name) {
|
||||
$this->event->attach($event_name, $listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,9 +38,10 @@ class ProjectPaginator extends Base
|
|||
foreach ($projects as &$project) {
|
||||
|
||||
$project['columns'] = $this->board->getColumns($project['id']);
|
||||
$stats = $this->board->getColumnStats($project['id']);
|
||||
|
||||
foreach ($project['columns'] as &$column) {
|
||||
$column['nb_tasks'] = $this->taskFinder->countByColumnId($project['id'], $column['id']);
|
||||
$column['nb_tasks'] = isset($stats[$column['id']]) ? $stats[$column['id']] : 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -85,6 +85,27 @@ class ProjectPermission extends Base
|
|||
return $this->user->prepareList($users);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of owners for a project
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
* @return array
|
||||
*/
|
||||
public function getManagers($project_id)
|
||||
{
|
||||
$users = $this->db
|
||||
->table(self::TABLE)
|
||||
->join(User::TABLE, 'id', 'user_id')
|
||||
->eq('project_id', $project_id)
|
||||
->eq('is_owner', 1)
|
||||
->asc('username')
|
||||
->columns(User::TABLE.'.id', User::TABLE.'.username', User::TABLE.'.name')
|
||||
->findAll();
|
||||
|
||||
return $this->user->prepareList($users);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get allowed and not allowed users for a project
|
||||
*
|
||||
|
@ -97,11 +118,13 @@ class ProjectPermission extends Base
|
|||
$users = array(
|
||||
'allowed' => array(),
|
||||
'not_allowed' => array(),
|
||||
'managers' => array(),
|
||||
);
|
||||
|
||||
$all_users = $this->user->getList();
|
||||
|
||||
$users['allowed'] = $this->getMembers($project_id);
|
||||
$users['managers'] = $this->getManagers($project_id);
|
||||
|
||||
foreach ($all_users as $user_id => $username) {
|
||||
|
||||
|
@ -114,14 +137,14 @@ class ProjectPermission extends Base
|
|||
}
|
||||
|
||||
/**
|
||||
* Allow a specific user for a given project
|
||||
* Add a new project member
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
* @param integer $user_id User id
|
||||
* @return bool
|
||||
*/
|
||||
public function allowUser($project_id, $user_id)
|
||||
public function addMember($project_id, $user_id)
|
||||
{
|
||||
return $this->db
|
||||
->table(self::TABLE)
|
||||
|
@ -129,14 +152,14 @@ class ProjectPermission extends Base
|
|||
}
|
||||
|
||||
/**
|
||||
* Revoke a specific user for a given project
|
||||
* Remove a member
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
* @param integer $user_id User id
|
||||
* @return bool
|
||||
*/
|
||||
public function revokeUser($project_id, $user_id)
|
||||
public function revokeMember($project_id, $user_id)
|
||||
{
|
||||
return $this->db
|
||||
->table(self::TABLE)
|
||||
|
@ -145,6 +168,39 @@ class ProjectPermission extends Base
|
|||
->remove();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a project manager
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
* @param integer $user_id User id
|
||||
* @return bool
|
||||
*/
|
||||
public function addManager($project_id, $user_id)
|
||||
{
|
||||
return $this->db
|
||||
->table(self::TABLE)
|
||||
->save(array('project_id' => $project_id, 'user_id' => $user_id, 'is_owner' => 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the role of a member
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
* @param integer $user_id User id
|
||||
* @param integer $is_owner Is user owner of the project
|
||||
* @return bool
|
||||
*/
|
||||
public function changeRole($project_id, $user_id, $is_owner)
|
||||
{
|
||||
return $this->db
|
||||
->table(self::TABLE)
|
||||
->eq('project_id', $project_id)
|
||||
->eq('user_id', $user_id)
|
||||
->update(array('is_owner' => (int) $is_owner));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a specific user is member of a project
|
||||
*
|
||||
|
@ -159,11 +215,29 @@ class ProjectPermission extends Base
|
|||
return true;
|
||||
}
|
||||
|
||||
return (bool) $this->db
|
||||
return $this->db
|
||||
->table(self::TABLE)
|
||||
->eq('project_id', $project_id)
|
||||
->eq('user_id', $user_id)
|
||||
->count();
|
||||
->count() === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a specific user is manager of a given project
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
* @param integer $user_id User id
|
||||
* @return bool
|
||||
*/
|
||||
public function isManager($project_id, $user_id)
|
||||
{
|
||||
return $this->db
|
||||
->table(self::TABLE)
|
||||
->eq('project_id', $project_id)
|
||||
->eq('user_id', $user_id)
|
||||
->eq('is_owner', 1)
|
||||
->count() === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -188,28 +262,11 @@ class ProjectPermission extends Base
|
|||
*/
|
||||
public function isEverybodyAllowed($project_id)
|
||||
{
|
||||
return (bool) $this->db
|
||||
return $this->db
|
||||
->table(Project::TABLE)
|
||||
->eq('id', $project_id)
|
||||
->eq('is_everybody_allowed', 1)
|
||||
->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a specific user is allowed to manage a project
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
* @param integer $user_id User id
|
||||
* @return bool
|
||||
*/
|
||||
public function adminAllowed($project_id, $user_id)
|
||||
{
|
||||
if ($this->isUserAllowed($project_id, $user_id) && $this->project->isPrivate($project_id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
->count() === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -241,7 +298,11 @@ class ProjectPermission extends Base
|
|||
*/
|
||||
public function getAllowedProjects($user_id)
|
||||
{
|
||||
return $this->filterProjects($this->project->getListByStatus(Project::ACTIVE), $user_id, 'isUserAllowed');
|
||||
if ($this->user->isAdmin($user_id)) {
|
||||
return $this->project->getListByStatus(Project::ACTIVE);
|
||||
}
|
||||
|
||||
return $this->getMemberProjects($user_id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -253,23 +314,39 @@ class ProjectPermission extends Base
|
|||
*/
|
||||
public function getMemberProjects($user_id)
|
||||
{
|
||||
return $this->filterProjects($this->project->getListByStatus(Project::ACTIVE), $user_id, 'isMember');
|
||||
return $this->db
|
||||
->table(Project::TABLE)
|
||||
->eq('user_id', $user_id)
|
||||
->join(self::TABLE, 'project_id', 'id')
|
||||
->listing('projects.id', 'name');
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy user access from a project to another one
|
||||
*
|
||||
* @author Antonio Rabelo
|
||||
* @param integer $project_from Project Template
|
||||
* @return integer $project_to Project that receives the copy
|
||||
* @param integer $project_src Project Template
|
||||
* @return integer $project_dst Project that receives the copy
|
||||
* @return boolean
|
||||
*/
|
||||
public function duplicate($project_from, $project_to)
|
||||
public function duplicate($project_src, $project_dst)
|
||||
{
|
||||
$users = $this->getMembers($project_from);
|
||||
$rows = $this->db
|
||||
->table(self::TABLE)
|
||||
->columns('project_id', 'user_id', 'is_owner')
|
||||
->eq('project_id', $project_src)
|
||||
->findAll();
|
||||
|
||||
foreach ($users as $user_id => $name) {
|
||||
if (! $this->allowUser($project_to, $user_id)) {
|
||||
foreach ($rows as $row) {
|
||||
|
||||
$result = $this->db
|
||||
->table(self::TABLE)
|
||||
->save(array(
|
||||
'project_id' => $project_dst,
|
||||
'user_id' => $row['user_id'],
|
||||
'is_owner' => (int) $row['is_owner'], // (int) for postgres
|
||||
));
|
||||
|
||||
if (! $result) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -291,6 +368,7 @@ class ProjectPermission extends Base
|
|||
new Validators\Integer('project_id', t('This value must be an integer')),
|
||||
new Validators\Required('user_id', t('The user id is required')),
|
||||
new Validators\Integer('user_id', t('This value must be an integer')),
|
||||
new Validators\Integer('is_owner', t('This value must be an integer')),
|
||||
));
|
||||
|
||||
return array(
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Model;
|
||||
|
||||
use Event\SubtaskEvent;
|
||||
use SimpleValidator\Validator;
|
||||
use SimpleValidator\Validators;
|
||||
|
||||
|
@ -57,15 +58,11 @@ class SubTask extends Base
|
|||
*/
|
||||
public function getStatusList()
|
||||
{
|
||||
$status = array(
|
||||
return array(
|
||||
self::STATUS_TODO => t('Todo'),
|
||||
self::STATUS_INPROGRESS => t('In progress'),
|
||||
self::STATUS_DONE => t('Done'),
|
||||
);
|
||||
|
||||
asort($status);
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -146,7 +143,10 @@ class SubTask extends Base
|
|||
$subtask_id = $this->persist(self::TABLE, $values);
|
||||
|
||||
if ($subtask_id) {
|
||||
$this->event->trigger(self::EVENT_CREATE, array('id' => $subtask_id) + $values);
|
||||
$this->container['dispatcher']->dispatch(
|
||||
self::EVENT_CREATE,
|
||||
new SubtaskEvent(array('id' => $subtask_id) + $values)
|
||||
);
|
||||
}
|
||||
|
||||
return $subtask_id;
|
||||
|
@ -165,7 +165,10 @@ class SubTask extends Base
|
|||
$result = $this->db->table(self::TABLE)->eq('id', $values['id'])->save($values);
|
||||
|
||||
if ($result) {
|
||||
$this->event->trigger(self::EVENT_UPDATE, $values);
|
||||
$this->container['dispatcher']->dispatch(
|
||||
self::EVENT_UPDATE,
|
||||
new SubtaskEvent($values)
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
@ -220,6 +223,7 @@ class SubTask extends Base
|
|||
$subtasks = $db->table(SubTask::TABLE)
|
||||
->columns('title', 'time_estimated')
|
||||
->eq('task_id', $src_task_id)
|
||||
->asc('id') // Explicit sorting for postgresql
|
||||
->findAll();
|
||||
|
||||
foreach ($subtasks as &$subtask) {
|
||||
|
|
119
sources/app/Model/SubtaskExport.php
Normal file
119
sources/app/Model/SubtaskExport.php
Normal file
|
@ -0,0 +1,119 @@
|
|||
<?php
|
||||
|
||||
namespace Model;
|
||||
|
||||
/**
|
||||
* Subtask Export
|
||||
*
|
||||
* @package model
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class SubtaskExport extends Base
|
||||
{
|
||||
/**
|
||||
* Subtask statuses
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $subtask_status = array();
|
||||
|
||||
/**
|
||||
* Fetch subtasks and return the prepared CSV
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
* @param mixed $from Start date (timestamp or user formatted date)
|
||||
* @param mixed $to End date (timestamp or user formatted date)
|
||||
* @return array
|
||||
*/
|
||||
public function export($project_id, $from, $to)
|
||||
{
|
||||
$this->subtask_status = $this->subTask->getStatusList();
|
||||
$subtasks = $this->getSubtasks($project_id, $from, $to);
|
||||
$results = array($this->getColumns());
|
||||
|
||||
foreach ($subtasks as $subtask) {
|
||||
$results[] = $this->format($subtask);
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column titles
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getColumns()
|
||||
{
|
||||
return array(
|
||||
e('Subtask Id'),
|
||||
e('Title'),
|
||||
e('Status'),
|
||||
e('Assignee'),
|
||||
e('Time estimated'),
|
||||
e('Time spent'),
|
||||
e('Task Id'),
|
||||
e('Task Title'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the output of a subtask array
|
||||
*
|
||||
* @access public
|
||||
* @param array $subtask Subtask properties
|
||||
* @return array
|
||||
*/
|
||||
public function format(array $subtask)
|
||||
{
|
||||
$values = array();
|
||||
$values[] = $subtask['id'];
|
||||
$values[] = $subtask['title'];
|
||||
$values[] = $this->subtask_status[$subtask['status']];
|
||||
$values[] = $subtask['assignee_name'] ?: $subtask['assignee_username'];
|
||||
$values[] = $subtask['time_estimated'];
|
||||
$values[] = $subtask['time_spent'];
|
||||
$values[] = $subtask['task_id'];
|
||||
$values[] = $subtask['task_title'];
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all subtasks for a given project
|
||||
*
|
||||
* @access public
|
||||
* @param integer $task_id Task id
|
||||
* @param mixed $from Start date (timestamp or user formatted date)
|
||||
* @param mixed $to End date (timestamp or user formatted date)
|
||||
* @return array
|
||||
*/
|
||||
public function getSubtasks($project_id, $from, $to)
|
||||
{
|
||||
if (! is_numeric($from)) {
|
||||
$from = $this->dateParser->resetDateToMidnight($this->dateParser->getTimestamp($from));
|
||||
}
|
||||
|
||||
if (! is_numeric($to)) {
|
||||
$to = $this->dateParser->resetDateToMidnight(strtotime('+1 day', $this->dateParser->getTimestamp($to)));
|
||||
}
|
||||
|
||||
return $this->db->table(SubTask::TABLE)
|
||||
->eq('project_id', $project_id)
|
||||
->columns(
|
||||
SubTask::TABLE.'.*',
|
||||
User::TABLE.'.username AS assignee_username',
|
||||
User::TABLE.'.name AS assignee_name',
|
||||
Task::TABLE.'.title AS task_title'
|
||||
)
|
||||
->gte('date_creation', $from)
|
||||
->lte('date_creation', $to)
|
||||
->join(Task::TABLE, 'id', 'task_id')
|
||||
->join(User::TABLE, 'id', 'user_id')
|
||||
->asc(SubTask::TABLE.'.id')
|
||||
->findAll();
|
||||
}
|
||||
}
|
495
sources/app/Model/Swimlane.php
Normal file
495
sources/app/Model/Swimlane.php
Normal file
|
@ -0,0 +1,495 @@
|
|||
<?php
|
||||
|
||||
namespace Model;
|
||||
|
||||
use SimpleValidator\Validator;
|
||||
use SimpleValidator\Validators;
|
||||
|
||||
/**
|
||||
* Swimlanes
|
||||
*
|
||||
* @package model
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class Swimlane extends Base
|
||||
{
|
||||
/**
|
||||
* SQL table name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const TABLE = 'swimlanes';
|
||||
|
||||
/**
|
||||
* Value for active swimlanes
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
const ACTIVE = 1;
|
||||
|
||||
/**
|
||||
* Value for inactive swimlanes
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
const INACTIVE = 0;
|
||||
|
||||
/**
|
||||
* Get a swimlane by the id
|
||||
*
|
||||
* @access public
|
||||
* @param integer $swimlane_id Swimlane id
|
||||
* @return array
|
||||
*/
|
||||
public function getById($swimlane_id)
|
||||
{
|
||||
return $this->db->table(self::TABLE)->eq('id', $swimlane_id)->findOne();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the swimlane name by the id
|
||||
*
|
||||
* @access public
|
||||
* @param integer $swimlane_id Swimlane id
|
||||
* @return string
|
||||
*/
|
||||
public function getNameById($swimlane_id)
|
||||
{
|
||||
return $this->db->table(self::TABLE)->eq('id', $swimlane_id)->findOneColumn('name') ?: '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a swimlane id by the project and the name
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
* @param string $name Name
|
||||
* @return integer
|
||||
*/
|
||||
public function getIdByName($project_id, $name)
|
||||
{
|
||||
return (int) $this->db->table(self::TABLE)
|
||||
->eq('project_id', $project_id)
|
||||
->eq('name', $name)
|
||||
->findOneColumn('id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default swimlane properties
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
* @return array
|
||||
*/
|
||||
public function getDefault($project_id)
|
||||
{
|
||||
return $this->db->table(Project::TABLE)
|
||||
->eq('id', $project_id)
|
||||
->columns('id', 'default_swimlane', 'show_default_swimlane')
|
||||
->findOne();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all swimlanes for a given project
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
* @return array
|
||||
*/
|
||||
public function getAll($project_id)
|
||||
{
|
||||
return $this->db->table(self::TABLE)
|
||||
->eq('project_id', $project_id)
|
||||
->orderBy('position', 'asc')
|
||||
->findAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of swimlanes by status
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
* @param integer $status Status
|
||||
* @return array
|
||||
*/
|
||||
public function getAllByStatus($project_id, $status = self::ACTIVE)
|
||||
{
|
||||
$query = $this->db->table(self::TABLE)
|
||||
->eq('project_id', $project_id)
|
||||
->eq('is_active', $status);
|
||||
|
||||
if ($status == self::ACTIVE) {
|
||||
$query->asc('position');
|
||||
}
|
||||
else {
|
||||
$query->asc('name');
|
||||
}
|
||||
|
||||
return $query->findAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get active swimlanes
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
* @return array
|
||||
*/
|
||||
public function getSwimlanes($project_id)
|
||||
{
|
||||
$swimlanes = $this->db->table(self::TABLE)
|
||||
->columns('id', 'name')
|
||||
->eq('project_id', $project_id)
|
||||
->eq('is_active', self::ACTIVE)
|
||||
->orderBy('position', 'asc')
|
||||
->findAll();
|
||||
|
||||
$default_swimlane = $this->db->table(Project::TABLE)
|
||||
->eq('id', $project_id)
|
||||
->eq('show_default_swimlane', 1)
|
||||
->findOneColumn('default_swimlane');
|
||||
|
||||
if ($default_swimlane) {
|
||||
array_unshift($swimlanes, array('id' => 0, 'name' => $default_swimlane));
|
||||
}
|
||||
|
||||
return $swimlanes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of all swimlanes
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
* @return array
|
||||
*/
|
||||
public function getSwimlanesList($project_id)
|
||||
{
|
||||
$swimlanes = $this->db->table(self::TABLE)
|
||||
->eq('project_id', $project_id)
|
||||
->orderBy('position', 'asc')
|
||||
->listing('id', 'name');
|
||||
|
||||
$swimlanes[0] = $this->db->table(Project::TABLE)
|
||||
->eq('id', $project_id)
|
||||
->findOneColumn('default_swimlane');
|
||||
|
||||
return $swimlanes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new swimlane
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
public function create($project_id, $name)
|
||||
{
|
||||
return $this->persist(self::TABLE, array(
|
||||
'project_id' => $project_id,
|
||||
'name' => $name,
|
||||
'position' => $this->getLastPosition($project_id),
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename a swimlane
|
||||
*
|
||||
* @access public
|
||||
* @param integer $swimlane_id Swimlane id
|
||||
* @param string $name Swimlane name
|
||||
* @return bool
|
||||
*/
|
||||
public function rename($swimlane_id, $name)
|
||||
{
|
||||
return $this->db->table(self::TABLE)
|
||||
->eq('id', $swimlane_id)
|
||||
->update(array('name' => $name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the default swimlane
|
||||
*
|
||||
* @access public
|
||||
* @param array $values Form values
|
||||
* @return bool
|
||||
*/
|
||||
public function updateDefault(array $values)
|
||||
{
|
||||
return $this->db
|
||||
->table(Project::TABLE)
|
||||
->eq('id', $values['id'])
|
||||
->update(array(
|
||||
'default_swimlane' => $values['default_swimlane'],
|
||||
'show_default_swimlane' => $values['show_default_swimlane'],
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last position of a swimlane
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id
|
||||
* @return integer
|
||||
*/
|
||||
public function getLastPosition($project_id)
|
||||
{
|
||||
return $this->db->table(self::TABLE)
|
||||
->eq('project_id', $project_id)
|
||||
->eq('is_active', 1)
|
||||
->count() + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable a swimlane
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
* @param integer $swimlane_id Swimlane id
|
||||
* @return bool
|
||||
*/
|
||||
public function disable($project_id, $swimlane_id)
|
||||
{
|
||||
$result = $this->db
|
||||
->table(self::TABLE)
|
||||
->eq('id', $swimlane_id)
|
||||
->update(array(
|
||||
'is_active' => self::INACTIVE,
|
||||
'position' => 0,
|
||||
));
|
||||
|
||||
if ($result) {
|
||||
// Re-order positions
|
||||
$this->updatePositions($project_id);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable a swimlane
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
* @param integer $swimlane_id Swimlane id
|
||||
* @return bool
|
||||
*/
|
||||
public function enable($project_id, $swimlane_id)
|
||||
{
|
||||
return $this->db
|
||||
->table(self::TABLE)
|
||||
->eq('id', $swimlane_id)
|
||||
->update(array(
|
||||
'is_active' => self::ACTIVE,
|
||||
'position' => $this->getLastPosition($project_id),
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a swimlane
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
* @param integer $swimlane_id Swimlane id
|
||||
* @return bool
|
||||
*/
|
||||
public function remove($project_id, $swimlane_id)
|
||||
{
|
||||
$this->db->startTransaction();
|
||||
|
||||
// Tasks should not be assigned anymore to this swimlane
|
||||
$this->db->table(Task::TABLE)->eq('swimlane_id', $swimlane_id)->update(array('swimlane_id' => 0));
|
||||
|
||||
if (! $this->db->table(self::TABLE)->eq('id', $swimlane_id)->remove()) {
|
||||
$this->db->cancelTransaction();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Re-order positions
|
||||
$this->updatePositions($project_id);
|
||||
|
||||
$this->db->closeTransaction();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update swimlane positions after disabling or removing a swimlane
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
* @return boolean
|
||||
*/
|
||||
public function updatePositions($project_id)
|
||||
{
|
||||
$position = 0;
|
||||
$swimlanes = $this->db->table(self::TABLE)
|
||||
->eq('project_id', $project_id)
|
||||
->eq('is_active', 1)
|
||||
->asc('position')
|
||||
->findAllByColumn('id');
|
||||
|
||||
if (! $swimlanes) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($swimlanes as $swimlane_id) {
|
||||
$this->db->table(self::TABLE)
|
||||
->eq('id', $swimlane_id)
|
||||
->update(array('position' => ++$position));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move a swimlane down, increment the position value
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
* @param integer $swimlane_id Swimlane id
|
||||
* @return boolean
|
||||
*/
|
||||
public function moveDown($project_id, $swimlane_id)
|
||||
{
|
||||
$swimlanes = $this->db->table(self::TABLE)
|
||||
->eq('project_id', $project_id)
|
||||
->eq('is_active', self::ACTIVE)
|
||||
->asc('position')
|
||||
->listing('id', 'position');
|
||||
|
||||
$positions = array_flip($swimlanes);
|
||||
|
||||
if (isset($swimlanes[$swimlane_id]) && $swimlanes[$swimlane_id] < count($swimlanes)) {
|
||||
|
||||
$position = ++$swimlanes[$swimlane_id];
|
||||
$swimlanes[$positions[$position]]--;
|
||||
|
||||
$this->db->startTransaction();
|
||||
$this->db->table(self::TABLE)->eq('id', $swimlane_id)->update(array('position' => $position));
|
||||
$this->db->table(self::TABLE)->eq('id', $positions[$position])->update(array('position' => $swimlanes[$positions[$position]]));
|
||||
$this->db->closeTransaction();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move a swimlane up, decrement the position value
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
* @param integer $swimlane_id Swimlane id
|
||||
* @return boolean
|
||||
*/
|
||||
public function moveUp($project_id, $swimlane_id)
|
||||
{
|
||||
$swimlanes = $this->db->table(self::TABLE)
|
||||
->eq('project_id', $project_id)
|
||||
->eq('is_active', self::ACTIVE)
|
||||
->asc('position')
|
||||
->listing('id', 'position');
|
||||
|
||||
$positions = array_flip($swimlanes);
|
||||
|
||||
if (isset($swimlanes[$swimlane_id]) && $swimlanes[$swimlane_id] > 1) {
|
||||
|
||||
$position = --$swimlanes[$swimlane_id];
|
||||
$swimlanes[$positions[$position]]++;
|
||||
|
||||
$this->db->startTransaction();
|
||||
$this->db->table(self::TABLE)->eq('id', $swimlane_id)->update(array('position' => $position));
|
||||
$this->db->table(self::TABLE)->eq('id', $positions[$position])->update(array('position' => $swimlanes[$positions[$position]]));
|
||||
$this->db->closeTransaction();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate creation
|
||||
*
|
||||
* @access public
|
||||
* @param array $values Form values
|
||||
* @return array $valid, $errors [0] = Success or not, [1] = List of errors
|
||||
*/
|
||||
public function validateCreation(array $values)
|
||||
{
|
||||
$rules = array(
|
||||
new Validators\Required('project_id', t('The project id is required')),
|
||||
new Validators\Required('name', t('The name is required')),
|
||||
);
|
||||
|
||||
$v = new Validator($values, array_merge($rules, $this->commonValidationRules()));
|
||||
|
||||
return array(
|
||||
$v->execute(),
|
||||
$v->getErrors()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate modification
|
||||
*
|
||||
* @access public
|
||||
* @param array $values Form values
|
||||
* @return array $valid, $errors [0] = Success or not, [1] = List of errors
|
||||
*/
|
||||
public function validateModification(array $values)
|
||||
{
|
||||
$rules = array(
|
||||
new Validators\Required('id', t('The id is required')),
|
||||
new Validators\Required('name', t('The name is required')),
|
||||
);
|
||||
|
||||
$v = new Validator($values, array_merge($rules, $this->commonValidationRules()));
|
||||
|
||||
return array(
|
||||
$v->execute(),
|
||||
$v->getErrors()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate default swimlane modification
|
||||
*
|
||||
* @access public
|
||||
* @param array $values Form values
|
||||
* @return array $valid, $errors [0] = Success or not, [1] = List of errors
|
||||
*/
|
||||
public function validateDefaultModification(array $values)
|
||||
{
|
||||
$rules = array(
|
||||
new Validators\Required('id', t('The id is required')),
|
||||
new Validators\Required('default_swimlane', t('The name is required')),
|
||||
);
|
||||
|
||||
$v = new Validator($values, array_merge($rules, $this->commonValidationRules()));
|
||||
|
||||
return array(
|
||||
$v->execute(),
|
||||
$v->getErrors()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Common validation rules
|
||||
*
|
||||
* @access private
|
||||
* @return array
|
||||
*/
|
||||
private function commonValidationRules()
|
||||
{
|
||||
return array(
|
||||
new Validators\Integer('id', t('The id must be an integer')),
|
||||
new Validators\Integer('project_id', t('The project id must be an integer')),
|
||||
new Validators\MaxLength('name', t('The maximum length is %d characters', 50), 50)
|
||||
);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue