diff options
author | Frederic Guillot <fred@kanboard.net> | 2016-09-08 22:33:16 -0400 |
---|---|---|
committer | Frederic Guillot <fred@kanboard.net> | 2016-09-08 22:33:16 -0400 |
commit | 75470c72428c8d8f278d160369558ab31b137fb1 (patch) | |
tree | 7fcad6cbc661e2762f1dfa5f643a5beac5217a17 /app | |
parent | fedf4ea2de21fcf95fc5aa942cedc7924865f160 (diff) |
Apply column restrictions to the board
Diffstat (limited to 'app')
-rw-r--r-- | app/Controller/BoardAjaxController.php | 12 | ||||
-rw-r--r-- | app/Core/Base.php | 327 | ||||
-rw-r--r-- | app/Core/Helper.php | 1 | ||||
-rw-r--r-- | app/Decorator/ColumnMoveRestrictionCacheDecorator.php | 57 | ||||
-rw-r--r-- | app/Formatter/BoardTaskFormatter.php | 5 | ||||
-rw-r--r-- | app/Helper/BoardHelper.php | 16 | ||||
-rw-r--r-- | app/Model/ColumnMoveRestrictionModel.php | 17 | ||||
-rw-r--r-- | app/ServiceProvider/CacheProvider.php | 8 | ||||
-rw-r--r-- | app/ServiceProvider/ClassProvider.php | 2 | ||||
-rw-r--r-- | app/Template/board/task_private.php | 3 |
10 files changed, 283 insertions, 165 deletions
diff --git a/app/Controller/BoardAjaxController.php b/app/Controller/BoardAjaxController.php index ccd47667..5e771fd6 100644 --- a/app/Controller/BoardAjaxController.php +++ b/app/Controller/BoardAjaxController.php @@ -28,11 +28,21 @@ class BoardAjaxController extends BaseController } $values = $this->request->getJson(); + $canMoveTask = $this->columnMoveRestrictionModel->isAllowed( + $project_id, + $this->helper->user->getProjectUserRole($project_id), + $values['src_column_id'], + $values['dst_column_id'] + ); + + if (! $canMoveTask) { + throw new AccessForbiddenException("You don't have the permission to move this task"); + } $result =$this->taskPositionModel->movePosition( $project_id, $values['task_id'], - $values['column_id'], + $values['dst_column_id'], $values['position'], $values['swimlane_id'] ); diff --git a/app/Core/Base.php b/app/Core/Base.php index 3b7c5e66..747b1917 100644 --- a/app/Core/Base.php +++ b/app/Core/Base.php @@ -10,168 +10,171 @@ use Pimple\Container; * @package core * @author Frederic Guillot * - * @property \Kanboard\Analytic\TaskDistributionAnalytic $taskDistributionAnalytic - * @property \Kanboard\Analytic\UserDistributionAnalytic $userDistributionAnalytic - * @property \Kanboard\Analytic\EstimatedTimeComparisonAnalytic $estimatedTimeComparisonAnalytic - * @property \Kanboard\Analytic\AverageLeadCycleTimeAnalytic $averageLeadCycleTimeAnalytic - * @property \Kanboard\Analytic\AverageTimeSpentColumnAnalytic $averageTimeSpentColumnAnalytic - * @property \Kanboard\Core\Action\ActionManager $actionManager - * @property \Kanboard\Core\ExternalLink\ExternalLinkManager $externalLinkManager - * @property \Kanboard\Core\Cache\MemoryCache $memoryCache - * @property \Kanboard\Core\Cache\BaseCache $cacheDriver - * @property \Kanboard\Core\Event\EventManager $eventManager - * @property \Kanboard\Core\Group\GroupManager $groupManager - * @property \Kanboard\Core\Http\Client $httpClient - * @property \Kanboard\Core\Http\OAuth2 $oauth - * @property \Kanboard\Core\Http\RememberMeCookie $rememberMeCookie - * @property \Kanboard\Core\Http\Request $request - * @property \Kanboard\Core\Http\Response $response - * @property \Kanboard\Core\Http\Router $router - * @property \Kanboard\Core\Http\Route $route - * @property \Kanboard\Core\Queue\QueueManager $queueManager - * @property \Kanboard\Core\Mail\Client $emailClient - * @property \Kanboard\Core\ObjectStorage\ObjectStorageInterface $objectStorage - * @property \Kanboard\Core\Plugin\Hook $hook - * @property \Kanboard\Core\Plugin\Loader $pluginLoader - * @property \Kanboard\Core\Security\AuthenticationManager $authenticationManager - * @property \Kanboard\Core\Security\AccessMap $applicationAccessMap - * @property \Kanboard\Core\Security\AccessMap $projectAccessMap - * @property \Kanboard\Core\Security\AccessMap $apiAccessMap - * @property \Kanboard\Core\Security\AccessMap $apiProjectAccessMap - * @property \Kanboard\Core\Security\Authorization $applicationAuthorization - * @property \Kanboard\Core\Security\Authorization $projectAuthorization - * @property \Kanboard\Core\Security\Authorization $apiAuthorization - * @property \Kanboard\Core\Security\Authorization $apiProjectAuthorization - * @property \Kanboard\Core\Security\Role $role - * @property \Kanboard\Core\Security\Token $token - * @property \Kanboard\Core\Session\FlashMessage $flash - * @property \Kanboard\Core\Session\SessionManager $sessionManager - * @property \Kanboard\Core\Session\SessionStorage $sessionStorage - * @property \Kanboard\Core\User\Avatar\AvatarManager $avatarManager - * @property \Kanboard\Core\User\GroupSync $groupSync - * @property \Kanboard\Core\User\UserProfile $userProfile - * @property \Kanboard\Core\User\UserSync $userSync - * @property \Kanboard\Core\User\UserSession $userSession - * @property \Kanboard\Core\DateParser $dateParser - * @property \Kanboard\Core\Helper $helper - * @property \Kanboard\Core\Paginator $paginator - * @property \Kanboard\Core\Template $template - * @property \Kanboard\Decorator\MetadataCacheDecorator $userMetadataCacheDecorator - * @property \Kanboard\Model\ActionModel $actionModel - * @property \Kanboard\Model\ActionParameterModel $actionParameterModel - * @property \Kanboard\Model\AvatarFileModel $avatarFileModel - * @property \Kanboard\Model\BoardModel $boardModel - * @property \Kanboard\Model\CategoryModel $categoryModel - * @property \Kanboard\Model\ColorModel $colorModel - * @property \Kanboard\Model\ColumnModel $columnModel - * @property \Kanboard\Model\CommentModel $commentModel - * @property \Kanboard\Model\ConfigModel $configModel - * @property \Kanboard\Model\CurrencyModel $currencyModel - * @property \Kanboard\Model\CustomFilterModel $customFilterModel - * @property \Kanboard\Model\TaskFileModel $taskFileModel - * @property \Kanboard\Model\ProjectFileModel $projectFileModel - * @property \Kanboard\Model\GroupModel $groupModel - * @property \Kanboard\Model\GroupMemberModel $groupMemberModel - * @property \Kanboard\Model\LanguageModel $languageModel - * @property \Kanboard\Model\LastLoginModel $lastLoginModel - * @property \Kanboard\Model\LinkModel $linkModel - * @property \Kanboard\Model\NotificationModel $notificationModel - * @property \Kanboard\Model\PasswordResetModel $passwordResetModel - * @property \Kanboard\Model\ProjectModel $projectModel - * @property \Kanboard\Model\ProjectActivityModel $projectActivityModel - * @property \Kanboard\Model\ProjectDuplicationModel $projectDuplicationModel - * @property \Kanboard\Model\ProjectDailyColumnStatsModel $projectDailyColumnStatsModel - * @property \Kanboard\Model\ProjectDailyStatsModel $projectDailyStatsModel - * @property \Kanboard\Model\ProjectMetadataModel $projectMetadataModel - * @property \Kanboard\Model\ProjectPermissionModel $projectPermissionModel - * @property \Kanboard\Model\ProjectUserRoleModel $projectUserRoleModel - * @property \Kanboard\Model\ProjectGroupRoleModel $projectGroupRoleModel - * @property \Kanboard\Model\ProjectNotificationModel $projectNotificationModel - * @property \Kanboard\Model\ProjectNotificationTypeModel $projectNotificationTypeModel - * @property \Kanboard\Model\ProjectTaskDuplicationModel $projectTaskDuplicationModel - * @property \Kanboard\Model\ProjectTaskPriorityModel $projectTaskPriorityModel - * @property \Kanboard\Model\RememberMeSessionModel $rememberMeSessionModel - * @property \Kanboard\Model\SubtaskModel $subtaskModel - * @property \Kanboard\Model\SubtaskPositionModel $subtaskPositionModel - * @property \Kanboard\Model\SubtaskStatusModel $subtaskStatusModel - * @property \Kanboard\Model\SubtaskTaskConversionModel $subtaskTaskConversionModel - * @property \Kanboard\Model\SubtaskTimeTrackingModel $subtaskTimeTrackingModel - * @property \Kanboard\Model\SwimlaneModel $swimlaneModel - * @property \Kanboard\Model\TagDuplicationModel $tagDuplicationModel - * @property \Kanboard\Model\TagModel $tagModel - * @property \Kanboard\Model\TaskModel $taskModel - * @property \Kanboard\Model\TaskAnalyticModel $taskAnalyticModel - * @property \Kanboard\Model\TaskCreationModel $taskCreationModel - * @property \Kanboard\Model\TaskDuplicationModel $taskDuplicationModel - * @property \Kanboard\Model\TaskProjectDuplicationModel $taskProjectDuplicationModel - * @property \Kanboard\Model\TaskProjectMoveModel $taskProjectMoveModel - * @property \Kanboard\Model\TaskRecurrenceModel $taskRecurrenceModel - * @property \Kanboard\Model\TaskExternalLinkModel $taskExternalLinkModel - * @property \Kanboard\Model\TaskFinderModel $taskFinderModel - * @property \Kanboard\Model\TaskLinkModel $taskLinkModel - * @property \Kanboard\Model\TaskModificationModel $taskModificationModel - * @property \Kanboard\Model\TaskPositionModel $taskPositionModel - * @property \Kanboard\Model\TaskStatusModel $taskStatusModel - * @property \Kanboard\Model\TaskTagModel $taskTagModel - * @property \Kanboard\Model\TaskMetadataModel $taskMetadataModel - * @property \Kanboard\Model\TimezoneModel $timezoneModel - * @property \Kanboard\Model\TransitionModel $transitionModel - * @property \Kanboard\Model\UserModel $userModel - * @property \Kanboard\Model\UserLockingModel $userLockingModel - * @property \Kanboard\Model\UserMentionModel $userMentionModel - * @property \Kanboard\Model\UserNotificationModel $userNotificationModel - * @property \Kanboard\Model\UserNotificationTypeModel $userNotificationTypeModel - * @property \Kanboard\Model\UserNotificationFilterModel $userNotificationFilterModel - * @property \Kanboard\Model\UserUnreadNotificationModel $userUnreadNotificationModel - * @property \Kanboard\Model\UserMetadataModel $userMetadataModel - * @property \Kanboard\Pagination\TaskPagination $taskPagination - * @property \Kanboard\Pagination\SubtaskPagination $subtaskPagination - * @property \Kanboard\Pagination\ProjectPagination $projectPagination - * @property \Kanboard\Pagination\UserPagination $userPagination - * @property \Kanboard\Validator\ActionValidator $actionValidator - * @property \Kanboard\Validator\AuthValidator $authValidator - * @property \Kanboard\Validator\ColumnValidator $columnValidator - * @property \Kanboard\Validator\CategoryValidator $categoryValidator - * @property \Kanboard\Validator\CommentValidator $commentValidator - * @property \Kanboard\Validator\CurrencyValidator $currencyValidator - * @property \Kanboard\Validator\CustomFilterValidator $customFilterValidator - * @property \Kanboard\Validator\ExternalLinkValidator $externalLinkValidator - * @property \Kanboard\Validator\GroupValidator $groupValidator - * @property \Kanboard\Validator\LinkValidator $linkValidator - * @property \Kanboard\Validator\PasswordResetValidator $passwordResetValidator - * @property \Kanboard\Validator\ProjectValidator $projectValidator - * @property \Kanboard\Validator\SubtaskValidator $subtaskValidator - * @property \Kanboard\Validator\SwimlaneValidator $swimlaneValidator - * @property \Kanboard\Validator\TagValidator $tagValidator - * @property \Kanboard\Validator\TaskLinkValidator $taskLinkValidator - * @property \Kanboard\Validator\TaskValidator $taskValidator - * @property \Kanboard\Validator\UserValidator $userValidator - * @property \Kanboard\Import\TaskImport $taskImport - * @property \Kanboard\Import\UserImport $userImport - * @property \Kanboard\Export\SubtaskExport $subtaskExport - * @property \Kanboard\Export\TaskExport $taskExport - * @property \Kanboard\Export\TransitionExport $transitionExport - * @property \Kanboard\Core\Filter\QueryBuilder $projectGroupRoleQuery - * @property \Kanboard\Core\Filter\QueryBuilder $projectUserRoleQuery - * @property \Kanboard\Core\Filter\QueryBuilder $projectActivityQuery - * @property \Kanboard\Core\Filter\QueryBuilder $userQuery - * @property \Kanboard\Core\Filter\QueryBuilder $projectQuery - * @property \Kanboard\Core\Filter\QueryBuilder $taskQuery - * @property \Kanboard\Core\Filter\LexerBuilder $taskLexer - * @property \Kanboard\Core\Filter\LexerBuilder $projectActivityLexer - * @property \Kanboard\Job\CommentEventJob $commentEventJob - * @property \Kanboard\Job\SubtaskEventJob $subtaskEventJob - * @property \Kanboard\Job\TaskEventJob $taskEventJob - * @property \Kanboard\Job\TaskFileEventJob $taskFileEventJob - * @property \Kanboard\Job\TaskLinkEventJob $taskLinkEventJob - * @property \Kanboard\Job\ProjectFileEventJob $projectFileEventJob - * @property \Kanboard\Job\NotificationJob $notificationJob - * @property \Kanboard\Job\ProjectMetricJob $projectMetricJob - * @property \Psr\Log\LoggerInterface $logger - * @property \PicoDb\Database $db - * @property \Symfony\Component\EventDispatcher\EventDispatcher $dispatcher - * @property \Symfony\Component\Console\Application $cli - * @property \JsonRPC\Server $api + * @property \Kanboard\Analytic\TaskDistributionAnalytic $taskDistributionAnalytic + * @property \Kanboard\Analytic\UserDistributionAnalytic $userDistributionAnalytic + * @property \Kanboard\Analytic\EstimatedTimeComparisonAnalytic $estimatedTimeComparisonAnalytic + * @property \Kanboard\Analytic\AverageLeadCycleTimeAnalytic $averageLeadCycleTimeAnalytic + * @property \Kanboard\Analytic\AverageTimeSpentColumnAnalytic $averageTimeSpentColumnAnalytic + * @property \Kanboard\Core\Action\ActionManager $actionManager + * @property \Kanboard\Core\ExternalLink\ExternalLinkManager $externalLinkManager + * @property \Kanboard\Core\Cache\MemoryCache $memoryCache + * @property \Kanboard\Core\Cache\BaseCache $cacheDriver + * @property \Kanboard\Core\Event\EventManager $eventManager + * @property \Kanboard\Core\Group\GroupManager $groupManager + * @property \Kanboard\Core\Http\Client $httpClient + * @property \Kanboard\Core\Http\OAuth2 $oauth + * @property \Kanboard\Core\Http\RememberMeCookie $rememberMeCookie + * @property \Kanboard\Core\Http\Request $request + * @property \Kanboard\Core\Http\Response $response + * @property \Kanboard\Core\Http\Router $router + * @property \Kanboard\Core\Http\Route $route + * @property \Kanboard\Core\Queue\QueueManager $queueManager + * @property \Kanboard\Core\Mail\Client $emailClient + * @property \Kanboard\Core\ObjectStorage\ObjectStorageInterface $objectStorage + * @property \Kanboard\Core\Plugin\Hook $hook + * @property \Kanboard\Core\Plugin\Loader $pluginLoader + * @property \Kanboard\Core\Security\AuthenticationManager $authenticationManager + * @property \Kanboard\Core\Security\AccessMap $applicationAccessMap + * @property \Kanboard\Core\Security\AccessMap $projectAccessMap + * @property \Kanboard\Core\Security\AccessMap $apiAccessMap + * @property \Kanboard\Core\Security\AccessMap $apiProjectAccessMap + * @property \Kanboard\Core\Security\Authorization $applicationAuthorization + * @property \Kanboard\Core\Security\Authorization $projectAuthorization + * @property \Kanboard\Core\Security\Authorization $apiAuthorization + * @property \Kanboard\Core\Security\Authorization $apiProjectAuthorization + * @property \Kanboard\Core\Security\Role $role + * @property \Kanboard\Core\Security\Token $token + * @property \Kanboard\Core\Session\FlashMessage $flash + * @property \Kanboard\Core\Session\SessionManager $sessionManager + * @property \Kanboard\Core\Session\SessionStorage $sessionStorage + * @property \Kanboard\Core\User\Avatar\AvatarManager $avatarManager + * @property \Kanboard\Core\User\GroupSync $groupSync + * @property \Kanboard\Core\User\UserProfile $userProfile + * @property \Kanboard\Core\User\UserSync $userSync + * @property \Kanboard\Core\User\UserSession $userSession + * @property \Kanboard\Core\DateParser $dateParser + * @property \Kanboard\Core\Helper $helper + * @property \Kanboard\Core\Paginator $paginator + * @property \Kanboard\Core\Template $template + * @property \Kanboard\Decorator\MetadataCacheDecorator $userMetadataCacheDecorator + * @property \Kanboard\Decorator\ColumnMoveRestrictionCacheDecorator $columnMoveRestrictionCacheDecorator + * @property \Kanboard\Model\ActionModel $actionModel + * @property \Kanboard\Model\ActionParameterModel $actionParameterModel + * @property \Kanboard\Model\AvatarFileModel $avatarFileModel + * @property \Kanboard\Model\BoardModel $boardModel + * @property \Kanboard\Model\CategoryModel $categoryModel + * @property \Kanboard\Model\ColorModel $colorModel + * @property \Kanboard\Model\ColumnModel $columnModel + * @property \Kanboard\Model\ColumnMoveRestrictionModel $columnMoveRestrictionModel + * @property \Kanboard\Model\CommentModel $commentModel + * @property \Kanboard\Model\ConfigModel $configModel + * @property \Kanboard\Model\CurrencyModel $currencyModel + * @property \Kanboard\Model\CustomFilterModel $customFilterModel + * @property \Kanboard\Model\TaskFileModel $taskFileModel + * @property \Kanboard\Model\ProjectFileModel $projectFileModel + * @property \Kanboard\Model\GroupModel $groupModel + * @property \Kanboard\Model\GroupMemberModel $groupMemberModel + * @property \Kanboard\Model\LanguageModel $languageModel + * @property \Kanboard\Model\LastLoginModel $lastLoginModel + * @property \Kanboard\Model\LinkModel $linkModel + * @property \Kanboard\Model\NotificationModel $notificationModel + * @property \Kanboard\Model\PasswordResetModel $passwordResetModel + * @property \Kanboard\Model\ProjectModel $projectModel + * @property \Kanboard\Model\ProjectActivityModel $projectActivityModel + * @property \Kanboard\Model\ProjectDuplicationModel $projectDuplicationModel + * @property \Kanboard\Model\ProjectDailyColumnStatsModel $projectDailyColumnStatsModel + * @property \Kanboard\Model\ProjectDailyStatsModel $projectDailyStatsModel + * @property \Kanboard\Model\ProjectMetadataModel $projectMetadataModel + * @property \Kanboard\Model\ProjectPermissionModel $projectPermissionModel + * @property \Kanboard\Model\ProjectUserRoleModel $projectUserRoleModel + * @property \Kanboard\Model\ProjectGroupRoleModel $projectGroupRoleModel + * @property \Kanboard\Model\ProjectNotificationModel $projectNotificationModel + * @property \Kanboard\Model\ProjectNotificationTypeModel $projectNotificationTypeModel + * @property \Kanboard\Model\ProjectRoleModel $projectRoleModel + * @property \Kanboard\Model\ProjectTaskDuplicationModel $projectTaskDuplicationModel + * @property \Kanboard\Model\ProjectTaskPriorityModel $projectTaskPriorityModel + * @property \Kanboard\Model\RememberMeSessionModel $rememberMeSessionModel + * @property \Kanboard\Model\SubtaskModel $subtaskModel + * @property \Kanboard\Model\SubtaskPositionModel $subtaskPositionModel + * @property \Kanboard\Model\SubtaskStatusModel $subtaskStatusModel + * @property \Kanboard\Model\SubtaskTaskConversionModel $subtaskTaskConversionModel + * @property \Kanboard\Model\SubtaskTimeTrackingModel $subtaskTimeTrackingModel + * @property \Kanboard\Model\SwimlaneModel $swimlaneModel + * @property \Kanboard\Model\TagDuplicationModel $tagDuplicationModel + * @property \Kanboard\Model\TagModel $tagModel + * @property \Kanboard\Model\TaskModel $taskModel + * @property \Kanboard\Model\TaskAnalyticModel $taskAnalyticModel + * @property \Kanboard\Model\TaskCreationModel $taskCreationModel + * @property \Kanboard\Model\TaskDuplicationModel $taskDuplicationModel + * @property \Kanboard\Model\TaskProjectDuplicationModel $taskProjectDuplicationModel + * @property \Kanboard\Model\TaskProjectMoveModel $taskProjectMoveModel + * @property \Kanboard\Model\TaskRecurrenceModel $taskRecurrenceModel + * @property \Kanboard\Model\TaskExternalLinkModel $taskExternalLinkModel + * @property \Kanboard\Model\TaskFinderModel $taskFinderModel + * @property \Kanboard\Model\TaskLinkModel $taskLinkModel + * @property \Kanboard\Model\TaskModificationModel $taskModificationModel + * @property \Kanboard\Model\TaskPositionModel $taskPositionModel + * @property \Kanboard\Model\TaskStatusModel $taskStatusModel + * @property \Kanboard\Model\TaskTagModel $taskTagModel + * @property \Kanboard\Model\TaskMetadataModel $taskMetadataModel + * @property \Kanboard\Model\TimezoneModel $timezoneModel + * @property \Kanboard\Model\TransitionModel $transitionModel + * @property \Kanboard\Model\UserModel $userModel + * @property \Kanboard\Model\UserLockingModel $userLockingModel + * @property \Kanboard\Model\UserMentionModel $userMentionModel + * @property \Kanboard\Model\UserNotificationModel $userNotificationModel + * @property \Kanboard\Model\UserNotificationTypeModel $userNotificationTypeModel + * @property \Kanboard\Model\UserNotificationFilterModel $userNotificationFilterModel + * @property \Kanboard\Model\UserUnreadNotificationModel $userUnreadNotificationModel + * @property \Kanboard\Model\UserMetadataModel $userMetadataModel + * @property \Kanboard\Pagination\TaskPagination $taskPagination + * @property \Kanboard\Pagination\SubtaskPagination $subtaskPagination + * @property \Kanboard\Pagination\ProjectPagination $projectPagination + * @property \Kanboard\Pagination\UserPagination $userPagination + * @property \Kanboard\Validator\ActionValidator $actionValidator + * @property \Kanboard\Validator\AuthValidator $authValidator + * @property \Kanboard\Validator\ColumnValidator $columnValidator + * @property \Kanboard\Validator\CategoryValidator $categoryValidator + * @property \Kanboard\Validator\CommentValidator $commentValidator + * @property \Kanboard\Validator\CurrencyValidator $currencyValidator + * @property \Kanboard\Validator\CustomFilterValidator $customFilterValidator + * @property \Kanboard\Validator\ExternalLinkValidator $externalLinkValidator + * @property \Kanboard\Validator\GroupValidator $groupValidator + * @property \Kanboard\Validator\LinkValidator $linkValidator + * @property \Kanboard\Validator\PasswordResetValidator $passwordResetValidator + * @property \Kanboard\Validator\ProjectValidator $projectValidator + * @property \Kanboard\Validator\SubtaskValidator $subtaskValidator + * @property \Kanboard\Validator\SwimlaneValidator $swimlaneValidator + * @property \Kanboard\Validator\TagValidator $tagValidator + * @property \Kanboard\Validator\TaskLinkValidator $taskLinkValidator + * @property \Kanboard\Validator\TaskValidator $taskValidator + * @property \Kanboard\Validator\UserValidator $userValidator + * @property \Kanboard\Import\TaskImport $taskImport + * @property \Kanboard\Import\UserImport $userImport + * @property \Kanboard\Export\SubtaskExport $subtaskExport + * @property \Kanboard\Export\TaskExport $taskExport + * @property \Kanboard\Export\TransitionExport $transitionExport + * @property \Kanboard\Core\Filter\QueryBuilder $projectGroupRoleQuery + * @property \Kanboard\Core\Filter\QueryBuilder $projectUserRoleQuery + * @property \Kanboard\Core\Filter\QueryBuilder $projectActivityQuery + * @property \Kanboard\Core\Filter\QueryBuilder $userQuery + * @property \Kanboard\Core\Filter\QueryBuilder $projectQuery + * @property \Kanboard\Core\Filter\QueryBuilder $taskQuery + * @property \Kanboard\Core\Filter\LexerBuilder $taskLexer + * @property \Kanboard\Core\Filter\LexerBuilder $projectActivityLexer + * @property \Kanboard\Job\CommentEventJob $commentEventJob + * @property \Kanboard\Job\SubtaskEventJob $subtaskEventJob + * @property \Kanboard\Job\TaskEventJob $taskEventJob + * @property \Kanboard\Job\TaskFileEventJob $taskFileEventJob + * @property \Kanboard\Job\TaskLinkEventJob $taskLinkEventJob + * @property \Kanboard\Job\ProjectFileEventJob $projectFileEventJob + * @property \Kanboard\Job\NotificationJob $notificationJob + * @property \Kanboard\Job\ProjectMetricJob $projectMetricJob + * @property \Psr\Log\LoggerInterface $logger + * @property \PicoDb\Database $db + * @property \Symfony\Component\EventDispatcher\EventDispatcher $dispatcher + * @property \Symfony\Component\Console\Application $cli + * @property \JsonRPC\Server $api */ abstract class Base { diff --git a/app/Core/Helper.php b/app/Core/Helper.php index 43151be8..c98b3c5e 100644 --- a/app/Core/Helper.php +++ b/app/Core/Helper.php @@ -12,6 +12,7 @@ use Pimple\Container; * * @property \Kanboard\Helper\AppHelper $app * @property \Kanboard\Helper\AssetHelper $asset + * @property \Kanboard\Helper\BoardHelper $board * @property \Kanboard\Helper\CalendarHelper $calendar * @property \Kanboard\Helper\DateHelper $dt * @property \Kanboard\Helper\FileHelper $file diff --git a/app/Decorator/ColumnMoveRestrictionCacheDecorator.php b/app/Decorator/ColumnMoveRestrictionCacheDecorator.php new file mode 100644 index 00000000..331bdebb --- /dev/null +++ b/app/Decorator/ColumnMoveRestrictionCacheDecorator.php @@ -0,0 +1,57 @@ +<?php + +namespace Kanboard\Decorator; + +use Kanboard\Core\Cache\CacheInterface; +use Kanboard\Model\ColumnMoveRestrictionModel; + +/** + * Class ColumnMoveRestrictionCacheDecorator + * + * @package Kanboard\Decorator + * @author Frederic Guillot + */ +class ColumnMoveRestrictionCacheDecorator +{ + protected $cachePrefix = 'column_move_restriction:'; + + /** + * @var CacheInterface + */ + protected $cache; + + /** + * @var ColumnMoveRestrictionModel + */ + protected $columnMoveRestrictionModel; + + /** + * ColumnMoveRestrictionDecorator constructor. + * + * @param CacheInterface $cache + * @param ColumnMoveRestrictionModel $columnMoveRestrictionModel + */ + public function __construct(CacheInterface $cache, ColumnMoveRestrictionModel $columnMoveRestrictionModel) + { + $this->cache = $cache; + $this->columnMoveRestrictionModel = $columnMoveRestrictionModel; + } + + /** + * Proxy method to get column Ids + * @param int $project_id + * @return array|mixed + */ + public function getAllSrcColumns($project_id) + { + $key = $this->cachePrefix.$project_id; + $columnIds = $this->cache->get($key); + + if ($columnIds === null) { + $columnIds = $this->columnMoveRestrictionModel->getAllSrcColumns($project_id); + $this->cache->set($key, $columnIds); + } + + return $columnIds; + } +} diff --git a/app/Formatter/BoardTaskFormatter.php b/app/Formatter/BoardTaskFormatter.php index 3bf171b1..5956ae35 100644 --- a/app/Formatter/BoardTaskFormatter.php +++ b/app/Formatter/BoardTaskFormatter.php @@ -79,6 +79,11 @@ class BoardTaskFormatter extends BaseFormatter implements FormatterInterface { $tasks = array_values(array_filter($this->tasks, array($this, 'filterTasks'))); array_merge_relation($tasks, $this->tags, 'tags', 'id'); + + foreach ($tasks as &$task) { + $task['is_draggable'] = $this->helper->board->isDraggable($task); + } + return $tasks; } diff --git a/app/Helper/BoardHelper.php b/app/Helper/BoardHelper.php index f5df3db2..c3d28dc4 100644 --- a/app/Helper/BoardHelper.php +++ b/app/Helper/BoardHelper.php @@ -24,4 +24,20 @@ class BoardHelper extends Base { return $this->userMetadataCacheDecorator->get(UserMetadataModel::KEY_BOARD_COLLAPSED.$project_id, 0) == 1; } + + /** + * Return true if the task can be moved by the connected user + * + * @param array $task + * @return bool + */ + public function isDraggable(array $task) + { + if ($task['is_active'] == 1 && $this->helper->user->hasProjectAccess('BoardViewController', 'save', $task['project_id'])) { + $srcColumnIds = $this->columnMoveRestrictionCacheDecorator->getAllSrcColumns($task['project_id']); + return ! isset($srcColumnIds[$task['column_id']]); + } + + return false; + } } diff --git a/app/Model/ColumnMoveRestrictionModel.php b/app/Model/ColumnMoveRestrictionModel.php index fa44edd1..63e739bf 100644 --- a/app/Model/ColumnMoveRestrictionModel.php +++ b/app/Model/ColumnMoveRestrictionModel.php @@ -42,7 +42,8 @@ class ColumnMoveRestrictionModel extends Base */ public function getAll($project_id) { - return $this->db->table(self::TABLE) + return $this->db + ->table(self::TABLE) ->columns( 'restriction_id', 'src_column_id', @@ -59,6 +60,20 @@ class ColumnMoveRestrictionModel extends Base } /** + * Get all source column Ids + * + * @param int $project_id + * @return array + */ + public function getAllSrcColumns($project_id) + { + return $this->db + ->hashtable(self::TABLE) + ->eq(self::TABLE.'.project_id', $project_id) + ->getAll('src_column_id', 'src_column_id'); + } + + /** * Create a new column restriction * * @param int $project_id diff --git a/app/ServiceProvider/CacheProvider.php b/app/ServiceProvider/CacheProvider.php index fac44d53..90d63f81 100644 --- a/app/ServiceProvider/CacheProvider.php +++ b/app/ServiceProvider/CacheProvider.php @@ -4,6 +4,7 @@ namespace Kanboard\ServiceProvider; use Kanboard\Core\Cache\FileCache; use Kanboard\Core\Cache\MemoryCache; +use Kanboard\Decorator\ColumnMoveRestrictionCacheDecorator; use Kanboard\Decorator\MetadataCacheDecorator; use Pimple\Container; use Pimple\ServiceProviderInterface; @@ -46,6 +47,13 @@ class CacheProvider implements ServiceProviderInterface ); }; + $container['columnMoveRestrictionCacheDecorator'] = function($c) { + return new ColumnMoveRestrictionCacheDecorator( + $c['memoryCache'], + $c['columnMoveRestrictionModel'] + ); + }; + return $container; } } diff --git a/app/ServiceProvider/ClassProvider.php b/app/ServiceProvider/ClassProvider.php index d837500a..e79ffcee 100644 --- a/app/ServiceProvider/ClassProvider.php +++ b/app/ServiceProvider/ClassProvider.php @@ -34,6 +34,7 @@ class ClassProvider implements ServiceProviderInterface 'CategoryModel', 'ColorModel', 'ColumnModel', + 'ColumnMoveRestrictionModel', 'CommentModel', 'ConfigModel', 'CurrencyModel', @@ -55,6 +56,7 @@ class ClassProvider implements ServiceProviderInterface 'ProjectNotificationModel', 'ProjectMetadataModel', 'ProjectGroupRoleModel', + 'ProjectRoleModel', 'ProjectTaskDuplicationModel', 'ProjectTaskPriorityModel', 'ProjectUserRoleModel', diff --git a/app/Template/board/task_private.php b/app/Template/board/task_private.php index 94b396a6..01da46db 100644 --- a/app/Template/board/task_private.php +++ b/app/Template/board/task_private.php @@ -1,6 +1,7 @@ <div class=" task-board - <?= $task['is_active'] == 1 ? ($this->user->hasProjectAccess('BoardViewController', 'save', $task['project_id']) ? 'draggable-item ' : '').'task-board-status-open '.($task['date_modification'] > (time() - $board_highlight_period) ? 'task-board-recent' : '') : 'task-board-status-closed' ?> + <?= $task['is_draggable'] ? 'draggable-item ' : '' ?> + <?= $task['is_active'] == 1 ? 'task-board-status-open '.($task['date_modification'] > (time() - $board_highlight_period) ? 'task-board-recent' : '') : 'task-board-status-closed' ?> color-<?= $task['color_id'] ?>" data-task-id="<?= $task['id'] ?>" data-column-id="<?= $task['column_id'] ?>" |