Apply column restrictions to the board
This commit is contained in:
parent
fedf4ea2de
commit
75470c7242
|
|
@ -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']
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
@ -58,6 +59,20 @@ class ColumnMoveRestrictionModel extends Base
|
|||
->findAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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'] ?>"
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -34,7 +34,7 @@ Kanboard.BoardDragAndDrop.prototype.dragAndDrop = function() {
|
|||
|
||||
if (newColumnId != taskColumnId || newSwimlaneId != taskSwimlaneId || newPosition != taskPosition) {
|
||||
self.changeTaskState(taskId);
|
||||
self.save(taskId, newColumnId, newPosition, newSwimlaneId);
|
||||
self.save(taskId, taskColumnId, newColumnId, newPosition, newSwimlaneId);
|
||||
}
|
||||
},
|
||||
start: function(event, ui) {
|
||||
|
|
@ -62,7 +62,7 @@ Kanboard.BoardDragAndDrop.prototype.changeTaskState = function(taskId) {
|
|||
task.find('.task-board-saving-icon').show();
|
||||
};
|
||||
|
||||
Kanboard.BoardDragAndDrop.prototype.save = function(taskId, columnId, position, swimlaneId) {
|
||||
Kanboard.BoardDragAndDrop.prototype.save = function(taskId, srcColumnId, dstColumnId, position, swimlaneId) {
|
||||
var self = this;
|
||||
self.app.showLoadingIcon();
|
||||
self.savingInProgress = true;
|
||||
|
|
@ -75,7 +75,8 @@ Kanboard.BoardDragAndDrop.prototype.save = function(taskId, columnId, position,
|
|||
processData: false,
|
||||
data: JSON.stringify({
|
||||
"task_id": taskId,
|
||||
"column_id": columnId,
|
||||
"src_column_id": srcColumnId,
|
||||
"dst_column_id": dstColumnId,
|
||||
"swimlane_id": swimlaneId,
|
||||
"position": position
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -123,6 +123,7 @@ class BoardFormatterTest extends Base
|
|||
$this->assertSame(0, $board[2]['columns'][3]['nb_tasks']);
|
||||
|
||||
$this->assertEquals('Task 8', $board[2]['columns'][2]['tasks'][0]['title']);
|
||||
$this->assertArrayHasKey('is_draggable', $board[2]['columns'][2]['tasks'][0]);
|
||||
}
|
||||
|
||||
public function testFormatWithoutDefaultSwimlane()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,94 @@
|
|||
<?php
|
||||
|
||||
use Kanboard\Core\Security\Role;
|
||||
use Kanboard\Helper\BoardHelper;
|
||||
use Kanboard\Model\ColumnMoveRestrictionModel;
|
||||
use Kanboard\Model\ProjectModel;
|
||||
use Kanboard\Model\ProjectRoleModel;
|
||||
use Kanboard\Model\ProjectUserRoleModel;
|
||||
use Kanboard\Model\TaskCreationModel;
|
||||
use Kanboard\Model\TaskFinderModel;
|
||||
use Kanboard\Model\TaskStatusModel;
|
||||
use Kanboard\Model\UserModel;
|
||||
|
||||
require_once __DIR__.'/../Base.php';
|
||||
|
||||
class BoardHelperTest extends Base
|
||||
{
|
||||
public function testIsDraggableWithProjectMember()
|
||||
{
|
||||
$boardHelper = new BoardHelper($this->container);
|
||||
$projectModel = new ProjectModel($this->container);
|
||||
$taskCreationModel = new TaskCreationModel($this->container);
|
||||
$taskFinderModel = new TaskFinderModel($this->container);
|
||||
$projectUserRole = new ProjectUserRoleModel($this->container);
|
||||
$userModel = new UserModel($this->container);
|
||||
|
||||
$this->container['sessionStorage']->user = array(
|
||||
'id' => 2,
|
||||
'role' => Role::APP_USER,
|
||||
);
|
||||
|
||||
$this->assertEquals(2, $userModel->create(array('username' => 'user')));
|
||||
$this->assertEquals(1, $projectModel->create(array('name' => 'Test')));
|
||||
$this->assertTrue($projectUserRole->addUser(1, 2, Role::PROJECT_MEMBER));
|
||||
$this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test')));
|
||||
|
||||
$task = $taskFinderModel->getById(1);
|
||||
$this->assertTrue($boardHelper->isDraggable($task));
|
||||
}
|
||||
|
||||
public function testIsDraggableWithClosedTask()
|
||||
{
|
||||
$boardHelper = new BoardHelper($this->container);
|
||||
$projectModel = new ProjectModel($this->container);
|
||||
$taskCreationModel = new TaskCreationModel($this->container);
|
||||
$taskFinderModel = new TaskFinderModel($this->container);
|
||||
$taskStatusModel = new TaskStatusModel($this->container);
|
||||
$projectUserRole = new ProjectUserRoleModel($this->container);
|
||||
$userModel = new UserModel($this->container);
|
||||
|
||||
$this->container['sessionStorage']->user = array(
|
||||
'id' => 2,
|
||||
'role' => Role::APP_USER,
|
||||
);
|
||||
|
||||
$this->assertEquals(2, $userModel->create(array('username' => 'user')));
|
||||
$this->assertEquals(1, $projectModel->create(array('name' => 'Test')));
|
||||
$this->assertTrue($projectUserRole->addUser(1, 2, Role::PROJECT_MEMBER));
|
||||
$this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test')));
|
||||
$this->assertTrue($taskStatusModel->close(1));
|
||||
|
||||
$task = $taskFinderModel->getById(1);
|
||||
$this->assertFalse($boardHelper->isDraggable($task));
|
||||
}
|
||||
|
||||
public function testIsDraggableWithColumnRestrictions()
|
||||
{
|
||||
$boardHelper = new BoardHelper($this->container);
|
||||
$projectModel = new ProjectModel($this->container);
|
||||
$taskCreationModel = new TaskCreationModel($this->container);
|
||||
$taskFinderModel = new TaskFinderModel($this->container);
|
||||
$projectUserRole = new ProjectUserRoleModel($this->container);
|
||||
$userModel = new UserModel($this->container);
|
||||
$projectRoleModel = new ProjectRoleModel($this->container);
|
||||
$columnMoveRestrictionModel = new ColumnMoveRestrictionModel($this->container);
|
||||
|
||||
$this->container['sessionStorage']->user = array(
|
||||
'id' => 2,
|
||||
'role' => Role::APP_USER,
|
||||
);
|
||||
|
||||
$this->assertEquals(2, $userModel->create(array('username' => 'user')));
|
||||
$this->assertEquals(1, $projectModel->create(array('name' => 'Test')));
|
||||
|
||||
$this->assertEquals(1, $projectRoleModel->create(1, 'Custom Role'));
|
||||
$this->assertEquals(1, $columnMoveRestrictionModel->create(1, 1, 2, 3));
|
||||
|
||||
$this->assertTrue($projectUserRole->addUser(1, 2, 'Custom Role'));
|
||||
$this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test', 'column_id' => 2)));
|
||||
|
||||
$task = $taskFinderModel->getById(1);
|
||||
$this->assertFalse($boardHelper->isDraggable($task));
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue