From 0826b1079876337f79d174d5287ad67d55dafa6c Mon Sep 17 00:00:00 2001 From: mbugeia Date: Mon, 26 Oct 2015 14:48:27 +0100 Subject: [PATCH] Update sources to v1.0.20 --- sources/ChangeLog | 27 ++ sources/app/Action/Base.php | 6 +- sources/app/Action/CommentCreation.php | 8 +- .../app/Action/TaskAssignCategoryColor.php | 4 +- .../app/Action/TaskAssignCategoryLabel.php | 4 +- .../app/Action/TaskAssignColorCategory.php | 4 +- sources/app/Action/TaskAssignColorColumn.php | 4 +- sources/app/Action/TaskAssignColorLink.php | 4 +- sources/app/Action/TaskAssignColorUser.php | 4 +- sources/app/Action/TaskAssignCurrentUser.php | 4 +- sources/app/Action/TaskAssignSpecificUser.php | 4 +- sources/app/Action/TaskAssignUser.php | 6 +- sources/app/Action/TaskClose.php | 10 +- sources/app/Action/TaskCreation.php | 8 +- .../Action/TaskDuplicateAnotherProject.php | 4 +- sources/app/Action/TaskEmail.php | 5 +- .../app/Action/TaskLogMoveAnotherColumn.php | 7 +- sources/app/Action/TaskMoveAnotherProject.php | 4 +- sources/app/Action/TaskMoveColumnAssigned.php | 4 +- .../Action/TaskMoveColumnCategoryChange.php | 4 +- .../app/Action/TaskMoveColumnUnAssigned.php | 4 +- sources/app/Action/TaskOpen.php | 6 +- sources/app/Action/TaskUpdateStartDate.php | 4 +- sources/app/Api/Action.php | 13 +- sources/app/Api/App.php | 4 +- sources/app/Api/Auth.php | 8 +- sources/app/Api/Base.php | 8 +- sources/app/Api/Board.php | 2 +- sources/app/Api/Category.php | 8 +- sources/app/Api/Comment.php | 8 +- sources/app/Api/File.php | 10 +- sources/app/Api/Link.php | 8 +- sources/app/Api/Me.php | 7 +- sources/app/Api/Project.php | 6 +- sources/app/Api/ProjectPermission.php | 4 +- sources/app/Api/Subtask.php | 8 +- sources/app/Api/Swimlane.php | 4 +- sources/app/Api/Task.php | 8 +- sources/app/Api/TaskLink.php | 4 +- sources/app/Api/User.php | 10 +- sources/app/Auth/Base.php | 34 -- sources/app/Auth/Database.php | 7 +- sources/app/Auth/Github.php | 9 +- sources/app/Auth/Gitlab.php | 9 +- sources/app/Auth/Google.php | 9 +- sources/app/Auth/Ldap.php | 28 +- sources/app/Auth/RememberMe.php | 11 +- sources/app/Auth/ReverseProxy.php | 16 +- sources/app/Console/Base.php | 25 +- sources/app/Console/LocaleComparator.php | 5 +- sources/app/Console/LocaleSync.php | 8 +- .../Console/ProjectDailyColumnStatsExport.php | 6 +- .../Console/ProjectDailyStatsCalculation.php | 4 +- sources/app/Console/SubtaskExport.php | 6 +- sources/app/Console/TaskExport.php | 6 +- .../app/Console/TaskOverdueNotification.php | 2 +- sources/app/Console/TransitionExport.php | 6 +- sources/app/Controller/Action.php | 8 +- sources/app/Controller/Activity.php | 2 +- sources/app/Controller/Analytic.php | 2 +- sources/app/Controller/App.php | 16 +- sources/app/Controller/Auth.php | 3 +- sources/app/Controller/Base.php | 20 +- sources/app/Controller/Board.php | 17 +- sources/app/Controller/Calendar.php | 11 +- sources/app/Controller/Category.php | 10 +- sources/app/Controller/Column.php | 13 +- sources/app/Controller/Comment.php | 28 +- sources/app/Controller/Config.php | 8 +- sources/app/Controller/Currency.php | 9 +- sources/app/Controller/Customfilter.php | 12 +- sources/app/Controller/Doc.php | 4 +- sources/app/Controller/Export.php | 2 +- sources/app/Controller/Feed.php | 2 +- sources/app/Controller/File.php | 43 +- sources/app/Controller/Gantt.php | 14 +- sources/app/Controller/Ical.php | 7 +- sources/app/Controller/Link.php | 12 +- sources/app/Controller/Listing.php | 4 +- sources/app/Controller/Oauth.php | 14 +- sources/app/Controller/Project.php | 81 ++-- sources/app/Controller/Projectuser.php | 9 +- sources/app/Controller/Search.php | 5 +- sources/app/Controller/Subtask.php | 16 +- sources/app/Controller/Swimlane.php | 17 +- sources/app/Controller/Task.php | 5 +- sources/app/Controller/Taskcreation.php | 9 +- sources/app/Controller/Taskduplication.php | 13 +- sources/app/Controller/Tasklink.php | 9 +- sources/app/Controller/Taskmodification.php | 38 +- sources/app/Controller/Taskstatus.php | 3 +- sources/app/Controller/Timer.php | 5 +- sources/app/Controller/Twofactor.php | 12 +- sources/app/Controller/User.php | 60 ++- sources/app/Controller/Webhook.php | 37 +- sources/app/Controller/Webnotification.php | 39 -- sources/app/Core/Base.php | 162 +++---- sources/app/Core/Cache/Base.php | 2 +- sources/app/Core/Cache/CacheInterface.php | 2 +- sources/app/Core/Cache/MemoryCache.php | 2 +- sources/app/Core/EmailClient.php | 49 -- sources/app/Core/Helper.php | 4 +- sources/app/Core/HttpClient.php | 5 +- sources/app/Core/Lexer.php | 5 +- sources/app/Core/Markdown.php | 5 +- sources/app/Core/NotificationInterface.php | 22 - sources/app/Core/OAuth2.php | 3 +- .../app/Core/ObjectStorage/FileStorage.php | 4 +- .../ObjectStorage/ObjectStorageException.php | 2 +- .../ObjectStorage/ObjectStorageInterface.php | 2 +- sources/app/Core/Paginator.php | 8 +- sources/app/Core/Plugin/Base.php | 8 +- sources/app/Core/Plugin/Hook.php | 2 +- sources/app/Core/Plugin/Loader.php | 19 +- sources/app/Core/Request.php | 21 +- sources/app/Core/Response.php | 8 +- sources/app/Core/Router.php | 24 +- sources/app/Core/Security.php | 7 +- sources/app/Core/Session.php | 2 +- sources/app/Core/Template.php | 10 +- sources/app/Core/Tool.php | 39 +- sources/app/Core/Translator.php | 5 +- sources/app/Event/AuthEvent.php | 2 +- sources/app/Event/CommentEvent.php | 2 +- sources/app/Event/FileEvent.php | 2 +- sources/app/Event/GenericEvent.php | 2 +- sources/app/Event/SubtaskEvent.php | 2 +- sources/app/Event/TaskEvent.php | 2 +- sources/app/Event/TaskLinkEvent.php | 2 +- sources/app/Formatter/FormatterInterface.php | 2 +- .../app/Formatter/ProjectGanttFormatter.php | 8 +- .../TaskFilterAutoCompleteFormatter.php | 6 +- .../app/Formatter/TaskFilterCalendarEvent.php | 4 +- .../Formatter/TaskFilterCalendarFormatter.php | 2 +- .../Formatter/TaskFilterGanttFormatter.php | 4 +- .../TaskFilterICalendarFormatter.php | 4 +- sources/app/Helper/App.php | 7 +- sources/app/Helper/Asset.php | 4 +- sources/app/Helper/Board.php | 4 +- sources/app/Helper/Dt.php | 10 +- sources/app/Helper/File.php | 8 +- sources/app/Helper/Form.php | 33 +- sources/app/Helper/Hook.php | 4 +- sources/app/Helper/Subtask.php | 5 +- sources/app/Helper/Task.php | 4 +- sources/app/Helper/Text.php | 6 +- sources/app/Helper/Url.php | 8 +- sources/app/Helper/User.php | 6 +- sources/app/Integration/BitbucketWebhook.php | 11 +- sources/app/Integration/GithubWebhook.php | 13 +- sources/app/Integration/GitlabWebhook.php | 8 +- sources/app/Integration/HipchatWebhook.php | 94 ---- sources/app/Integration/Jabber.php | 129 ----- sources/app/Integration/Mailgun.php | 95 ---- sources/app/Integration/Postmark.php | 94 ---- sources/app/Integration/Sendgrid.php | 98 ---- sources/app/Integration/SlackWebhook.php | 127 ----- sources/app/Integration/Smtp.php | 71 --- sources/app/Library/password.php | 409 ++++++++-------- sources/app/Locale/cs_CZ/translations.php | 64 +-- sources/app/Locale/da_DK/translations.php | 64 +-- sources/app/Locale/de_DE/translations.php | 64 +-- sources/app/Locale/es_ES/translations.php | 64 +-- sources/app/Locale/fi_FI/translations.php | 64 +-- sources/app/Locale/fr_FR/translations.php | 66 +-- sources/app/Locale/hu_HU/translations.php | 64 +-- sources/app/Locale/id_ID/translations.php | 64 +-- sources/app/Locale/it_IT/translations.php | 64 +-- sources/app/Locale/ja_JP/translations.php | 64 +-- sources/app/Locale/nb_NO/translations.php | 66 +-- sources/app/Locale/nl_NL/translations.php | 64 +-- sources/app/Locale/pl_PL/translations.php | 64 +-- sources/app/Locale/pt_BR/translations.php | 234 ++++----- sources/app/Locale/pt_PT/translations.php | 64 +-- sources/app/Locale/ru_RU/translations.php | 64 +-- .../app/Locale/sr_Latn_RS/translations.php | 64 +-- sources/app/Locale/sv_SE/translations.php | 64 +-- sources/app/Locale/th_TH/translations.php | 64 +-- sources/app/Locale/tr_TR/translations.php | 64 +-- sources/app/Locale/zh_CN/translations.php | 64 +-- sources/app/Model/Acl.php | 7 +- sources/app/Model/Action.php | 16 +- sources/app/Model/Authentication.php | 22 +- sources/app/Model/Base.php | 8 +- sources/app/Model/Board.php | 13 +- sources/app/Model/Category.php | 4 +- sources/app/Model/Color.php | 5 +- sources/app/Model/Comment.php | 9 +- sources/app/Model/Config.php | 76 +-- sources/app/Model/Currency.php | 2 +- sources/app/Model/CustomFilter.php | 5 +- sources/app/Model/DateParser.php | 241 ---------- sources/app/Model/EmailNotification.php | 123 ----- sources/app/Model/File.php | 23 +- sources/app/Model/LastLogin.php | 3 +- sources/app/Model/Link.php | 3 +- sources/app/Model/Notification.php | 269 +++++------ sources/app/Model/NotificationFilter.php | 199 -------- sources/app/Model/NotificationType.php | 114 +++-- sources/app/Model/OverdueNotification.php | 10 +- sources/app/Model/Project.php | 4 +- sources/app/Model/ProjectActivity.php | 58 +-- sources/app/Model/ProjectAnalytic.php | 4 +- sources/app/Model/ProjectDailyColumnStats.php | 8 +- sources/app/Model/ProjectDailyStats.php | 6 +- sources/app/Model/ProjectDuplication.php | 2 +- sources/app/Model/ProjectIntegration.php | 66 --- sources/app/Model/ProjectPermission.php | 7 +- sources/app/Model/Subtask.php | 14 +- sources/app/Model/SubtaskExport.php | 2 +- sources/app/Model/SubtaskTimeTracking.php | 3 +- sources/app/Model/Swimlane.php | 9 +- sources/app/Model/Task.php | 2 +- sources/app/Model/TaskAnalytic.php | 3 +- sources/app/Model/TaskCreation.php | 5 +- sources/app/Model/TaskDuplication.php | 7 +- sources/app/Model/TaskExport.php | 2 +- sources/app/Model/TaskFilter.php | 22 +- sources/app/Model/TaskFinder.php | 2 +- sources/app/Model/TaskLink.php | 5 +- sources/app/Model/TaskModification.php | 7 +- sources/app/Model/TaskPermission.php | 5 +- sources/app/Model/TaskPosition.php | 16 +- sources/app/Model/TaskStatus.php | 4 +- sources/app/Model/TaskValidator.php | 3 +- sources/app/Model/Transition.php | 2 +- sources/app/Model/User.php | 31 +- sources/app/Model/UserSession.php | 26 +- sources/app/Model/WebNotification.php | 156 ------ sources/app/Model/Webhook.php | 36 -- sources/app/Schema/Mysql.php | 233 +++++---- sources/app/Schema/Postgres.php | 224 +++++---- sources/app/Schema/Sqlite.php | 254 ++++++---- sources/app/ServiceProvider/ClassProvider.php | 70 ++- .../app/ServiceProvider/DatabaseProvider.php | 14 +- .../EventDispatcherProvider.php | 24 +- .../app/ServiceProvider/LoggingProvider.php | 2 +- sources/app/Subscriber/AuthSubscriber.php | 8 +- .../app/Subscriber/BootstrapSubscriber.php | 4 +- .../app/Subscriber/NotificationSubscriber.php | 34 +- .../Subscriber/ProjectActivitySubscriber.php | 75 --- .../ProjectDailySummarySubscriber.php | 8 +- .../ProjectModificationDateSubscriber.php | 8 +- .../Subscriber/RecurringTaskSubscriber.php | 12 +- .../SubtaskTimeTrackingSubscriber.php | 12 +- .../Subscriber/TaskMovedDateSubscriber.php | 8 +- .../app/Subscriber/TransitionSubscriber.php | 10 +- sources/app/Subscriber/WebhookSubscriber.php | 45 -- sources/app/Template/app/filters_helper.php | 2 +- sources/app/Template/app/notifications.php | 4 +- sources/app/Template/auth/index.php | 4 + .../app/Template/board/table_container.php | 2 +- sources/app/Template/board/task_footer.php | 6 +- sources/app/Template/board/tooltip_files.php | 2 +- .../app/Template/board/tooltip_tasklinks.php | 2 +- sources/app/Template/config/integrations.php | 74 +-- sources/app/Template/config/plugins.php | 2 +- sources/app/Template/custom_filter/add.php | 2 + sources/app/Template/custom_filter/edit.php | 4 +- sources/app/Template/custom_filter/index.php | 10 +- sources/app/Template/header.php | 2 +- sources/app/Template/listing/show.php | 2 +- sources/app/Template/project/filters.php | 2 +- sources/app/Template/project/integrations.php | 74 +-- sources/app/Template/project/sidebar.php | 10 +- sources/app/Template/search/results.php | 2 +- sources/app/Template/swimlane/index.php | 56 +-- sources/app/Template/task/changes.php | 10 +- sources/app/Template/task/comments.php | 22 +- sources/app/Template/task/details.php | 2 +- sources/app/Template/task/recurring_info.php | 4 +- .../task_modification/edit_recurrence.php | 4 +- sources/app/Template/user/index.php | 3 +- sources/app/Template/user/last.php | 2 +- sources/app/Template/user/sessions.php | 2 +- sources/app/Template/user/sidebar.php | 3 + sources/app/check_setup.php | 10 +- sources/app/common.php | 9 +- sources/app/constants.php | 16 +- sources/app/functions.php | 13 +- sources/assets/css/app.css | 2 +- sources/assets/css/print.css | 2 +- sources/assets/css/src/board.css | 2 +- sources/assets/css/src/comment.css | 14 + sources/assets/img/hipchat-icon.png | Bin 1373 -> 0 bytes sources/assets/img/jabber-icon.png | Bin 1275 -> 0 bytes sources/assets/img/mailgun-icon.png | Bin 632 -> 0 bytes sources/assets/img/postmark-icon.png | Bin 474 -> 0 bytes sources/assets/img/sendgrid-icon.png | Bin 600 -> 0 bytes sources/assets/js/app.js | 11 +- sources/assets/js/src/App.js | 3 + sources/assets/js/src/Board.js | 5 +- sources/assets/js/src/Popover.js | 2 +- sources/assets/js/src/Search.js | 7 +- sources/assets/js/vendor/jquery-1.11.1.min.js | 4 - sources/config.default.php | 13 +- sources/doc/api-json-rpc.markdown | 42 +- sources/doc/coding-standards.markdown | 2 +- sources/doc/config.markdown | 4 +- sources/doc/email-configuration.markdown | 61 +-- sources/doc/fr/notifications.markdown | 11 +- sources/doc/hipchat.markdown | 38 -- sources/doc/index.markdown | 6 - sources/doc/jabber.markdown | 34 -- sources/doc/mailgun.markdown | 28 -- sources/doc/notifications.markdown | 9 +- sources/doc/plugins.markdown | 428 +---------------- sources/doc/postmark.markdown | 29 -- sources/doc/sendgrid.markdown | 24 - sources/doc/slack.markdown | 38 -- sources/favicon.ico | Bin 0 -> 13094 bytes sources/index.php | 9 +- sources/jsonrpc.php | 54 ++- sources/kanboard | 24 +- sources/plugins/.gitignore | 2 +- sources/vendor/autoload.php | 2 +- .../christian-riesen/base32/src/Base32.php | 146 ++---- sources/vendor/composer/autoload_classmap.php | 453 +++++++++--------- .../vendor/composer/autoload_namespaces.php | 1 - sources/vendor/composer/autoload_psr4.php | 3 +- sources/vendor/composer/autoload_real.php | 10 +- sources/vendor/composer/installed.json | 52 +- .../vendor/gregwar/captcha/CaptchaBuilder.php | 8 +- .../vendor/symfony/console/Application.php | 10 +- .../symfony/console/Helper/DialogHelper.php | 2 +- .../symfony/console/Helper/ProcessHelper.php | 9 + .../symfony/console/Helper/ProgressBar.php | 7 +- .../symfony/console/Helper/QuestionHelper.php | 5 + .../vendor/symfony/console/Helper/Table.php | 4 +- .../symfony/console/Output/ConsoleOutput.php | 5 + .../console/Output/OutputInterface.php | 2 +- .../symfony/console/Output/StreamOutput.php | 2 +- .../symfony/console/Tests/ApplicationTest.php | 8 +- .../Tests/Fixtures/application_asxml1.txt | 212 ++++---- .../Tests/Fixtures/application_asxml2.txt | 62 +-- .../Tests/Helper/LegacyProgressHelperTest.php | 13 + .../console/Tests/Helper/ProgressBarTest.php | 11 + .../ContainerAwareEventDispatcher.php | 19 +- .../event-dispatcher/EventDispatcher.php | 36 +- .../Tests/AbstractEventDispatcherTest.php | 1 + 340 files changed, 3500 insertions(+), 5868 deletions(-) delete mode 100644 sources/app/Auth/Base.php delete mode 100644 sources/app/Controller/Webnotification.php delete mode 100644 sources/app/Core/EmailClient.php delete mode 100644 sources/app/Core/NotificationInterface.php delete mode 100644 sources/app/Integration/HipchatWebhook.php delete mode 100644 sources/app/Integration/Jabber.php delete mode 100644 sources/app/Integration/Mailgun.php delete mode 100644 sources/app/Integration/Postmark.php delete mode 100644 sources/app/Integration/Sendgrid.php delete mode 100644 sources/app/Integration/SlackWebhook.php delete mode 100644 sources/app/Integration/Smtp.php delete mode 100644 sources/app/Model/DateParser.php delete mode 100644 sources/app/Model/EmailNotification.php delete mode 100644 sources/app/Model/NotificationFilter.php delete mode 100644 sources/app/Model/ProjectIntegration.php mode change 100755 => 100644 sources/app/Model/TaskDuplication.php delete mode 100644 sources/app/Model/WebNotification.php delete mode 100644 sources/app/Model/Webhook.php delete mode 100644 sources/app/Subscriber/ProjectActivitySubscriber.php delete mode 100644 sources/app/Subscriber/WebhookSubscriber.php delete mode 100644 sources/assets/img/hipchat-icon.png delete mode 100644 sources/assets/img/jabber-icon.png delete mode 100644 sources/assets/img/mailgun-icon.png delete mode 100644 sources/assets/img/postmark-icon.png delete mode 100644 sources/assets/img/sendgrid-icon.png delete mode 100644 sources/assets/js/vendor/jquery-1.11.1.min.js delete mode 100644 sources/doc/hipchat.markdown delete mode 100644 sources/doc/jabber.markdown delete mode 100644 sources/doc/mailgun.markdown delete mode 100644 sources/doc/postmark.markdown delete mode 100644 sources/doc/sendgrid.markdown delete mode 100644 sources/doc/slack.markdown create mode 100644 sources/favicon.ico diff --git a/sources/ChangeLog b/sources/ChangeLog index 6b9f551..87bb379 100644 --- a/sources/ChangeLog +++ b/sources/ChangeLog @@ -1,3 +1,30 @@ +Version 1.0.20 +-------------- + +Breaking changes: + +- Add namespace Kanboard (update your plugins) +- Move Mailgun, Sendgrid, Postmark, Slack, Hipchat and Jabber to plugins +- ReverseProxy authentication check for each request that the username match the user session + +New features: + +* Add CSV import for users and tasks +* Add Task, User and Project metadata for plugin creators + +Improvements: + +* Allow to change comments sorting +* Add the possibility to append or not custom filters +* Make mail transports pluggable +* Do not show scroll-bars when a column is collapsed on Windows systems +* Regenerate thumbnails if missing + +Bug fixes: + +* People should not see any tasks during a search when they are not associated to a project +* Avoid to disable the default swimlane during renaming when there is no other activated swimlane + Version 1.0.19 -------------- diff --git a/sources/app/Action/Base.php b/sources/app/Action/Base.php index c8ff02a..4d2d6da 100644 --- a/sources/app/Action/Base.php +++ b/sources/app/Action/Base.php @@ -1,8 +1,8 @@ user->getById($this->getParam('user_id')); if (! empty($user['email'])) { - $task = $this->taskFinder->getDetails($data['task_id']); $this->emailClient->send( diff --git a/sources/app/Action/TaskLogMoveAnotherColumn.php b/sources/app/Action/TaskLogMoveAnotherColumn.php index 621e8e6..a699c4a 100644 --- a/sources/app/Action/TaskLogMoveAnotherColumn.php +++ b/sources/app/Action/TaskLogMoveAnotherColumn.php @@ -1,9 +1,8 @@ userSession->isLogged()) { return false; } - + $column = $this->board->getColumn($data['column_id']); return (bool) $this->comment->create(array( diff --git a/sources/app/Action/TaskMoveAnotherProject.php b/sources/app/Action/TaskMoveAnotherProject.php index ee21299..476e203 100644 --- a/sources/app/Action/TaskMoveAnotherProject.php +++ b/sources/app/Action/TaskMoveAnotherProject.php @@ -1,8 +1,8 @@ action->getAllByProject($project_id); foreach ($actions as $index => $action) { - $params = array(); - foreach($action['params'] as $param) { + foreach ($action['params'] as $param) { $params[$param['name']] = $param['value']; } @@ -57,7 +56,7 @@ class Action extends \Core\Base 'params' => $params, ); - list($valid,) = $this->action->validateCreation($values); + list($valid, ) = $this->action->validateCreation($values); if (! $valid) { return false; @@ -80,14 +79,14 @@ class Action extends \Core\Base $required_params = $action->getActionRequiredParameters(); // Check missing parameters - foreach($required_params as $param => $value) { + foreach ($required_params as $param => $value) { if (! isset($params[$param])) { return false; } } // Check extra parameters - foreach($params as $param => $value) { + foreach ($params as $param => $value) { if (! isset($required_params[$param])) { return false; } diff --git a/sources/app/Api/App.php b/sources/app/Api/App.php index 9b3ceb9..d082bcf 100644 --- a/sources/app/Api/App.php +++ b/sources/app/Api/App.php @@ -1,6 +1,6 @@ authentication->hasCaptcha($username) && $this->authentication->authenticate($username, $password)) { $this->checkProcedurePermission(true, $method); $this->userSession->refresh($this->user->getByUsername($username)); - } - else if ($username === 'jsonrpc' && $password === $this->config->get('api_token')) { + } elseif ($username === 'jsonrpc' && $password === $this->config->get('api_token')) { $this->checkProcedurePermission(false, $method); - } - else { + } else { throw new AuthenticationFailure('Wrong credentials'); } } diff --git a/sources/app/Api/Base.php b/sources/app/Api/Base.php index 0287e0e..0959817 100644 --- a/sources/app/Api/Base.php +++ b/sources/app/Api/Base.php @@ -1,8 +1,7 @@ $name, ); - list($valid,) = $this->category->validateCreation($values); + list($valid, ) = $this->category->validateCreation($values); return $valid ? $this->category->create($values) : false; } @@ -43,7 +43,7 @@ class Category extends \Core\Base 'name' => $name, ); - list($valid,) = $this->category->validateModification($values); + list($valid, ) = $this->category->validateModification($values); return $valid && $this->category->update($values); } } diff --git a/sources/app/Api/Comment.php b/sources/app/Api/Comment.php index e40968b..26b632e 100644 --- a/sources/app/Api/Comment.php +++ b/sources/app/Api/Comment.php @@ -1,6 +1,6 @@ $content, ); - list($valid,) = $this->comment->validateCreation($values); + list($valid, ) = $this->comment->validateCreation($values); return $valid ? $this->comment->create($values) : false; } @@ -45,7 +45,7 @@ class Comment extends \Core\Base 'comment' => $content, ); - list($valid,) = $this->comment->validateModification($values); + list($valid, ) = $this->comment->validateModification($values); return $valid && $this->comment->update($values); } } diff --git a/sources/app/Api/File.php b/sources/app/Api/File.php index ad736ad..be415ec 100644 --- a/sources/app/Api/File.php +++ b/sources/app/Api/File.php @@ -1,8 +1,8 @@ file->getById($file_id); if (! empty($file)) { return base64_encode($this->objectStorage->get($file['path'])); } - } - catch (ObjectStorageException $e) { + } catch (ObjectStorageException $e) { $this->logger->error($e->getMessage()); } diff --git a/sources/app/Api/Link.php b/sources/app/Api/Link.php index d883013..d4df18f 100644 --- a/sources/app/Api/Link.php +++ b/sources/app/Api/Link.php @@ -1,6 +1,6 @@ $opposite_label, ); - list($valid,) = $this->link->validateCreation($values); + list($valid, ) = $this->link->validateCreation($values); return $valid ? $this->link->create($label, $opposite_label) : false; } @@ -93,7 +93,7 @@ class Link extends \Core\Base 'label' => $label, ); - list($valid,) = $this->link->validateModification($values); + list($valid, ) = $this->link->validateModification($values); return $valid && $this->link->update($values); } diff --git a/sources/app/Api/Me.php b/sources/app/Api/Me.php index e761155..2c332a8 100644 --- a/sources/app/Api/Me.php +++ b/sources/app/Api/Me.php @@ -1,9 +1,8 @@ 1, ); - list($valid,) = $this->project->validateCreation($values); + list($valid, ) = $this->project->validateCreation($values); return $valid ? $this->project->create($values, $this->userSession->getId(), true) : false; } diff --git a/sources/app/Api/Project.php b/sources/app/Api/Project.php index 8ed382c..f934432 100644 --- a/sources/app/Api/Project.php +++ b/sources/app/Api/Project.php @@ -1,6 +1,6 @@ $description ); - list($valid,) = $this->project->validateCreation($values); + list($valid, ) = $this->project->validateCreation($values); return $valid ? $this->project->create($values) : false; } @@ -81,7 +81,7 @@ class Project extends Base 'description' => $description ); - list($valid,) = $this->project->validateModification($values); + list($valid, ) = $this->project->validateModification($values); return $valid && $this->project->update($values); } } diff --git a/sources/app/Api/ProjectPermission.php b/sources/app/Api/ProjectPermission.php index 7dd2dec..8032339 100644 --- a/sources/app/Api/ProjectPermission.php +++ b/sources/app/Api/ProjectPermission.php @@ -1,6 +1,6 @@ $status, ); - list($valid,) = $this->subtask->validateCreation($values); + list($valid, ) = $this->subtask->validateCreation($values); return $valid ? $this->subtask->create($values) : false; } @@ -58,7 +58,7 @@ class Subtask extends \Core\Base } } - list($valid,) = $this->subtask->validateApiModification($values); + list($valid, ) = $this->subtask->validateApiModification($values); return $valid && $this->subtask->update($values); } } diff --git a/sources/app/Api/Swimlane.php b/sources/app/Api/Swimlane.php index 13838d7..84c699a 100644 --- a/sources/app/Api/Swimlane.php +++ b/sources/app/Api/Swimlane.php @@ -1,6 +1,6 @@ taskFinder->getOverdueTasks(); } - + public function getOverdueTasksByProject($project_id) { $this->checkProjectPermission($project_id); @@ -91,7 +91,7 @@ class Task extends Base 'reference' => $reference, ); - list($valid,) = $this->taskValidator->validateCreation($values); + list($valid, ) = $this->taskValidator->validateCreation($values); return $valid ? $this->taskCreation->create($values) : false; } diff --git a/sources/app/Api/TaskLink.php b/sources/app/Api/TaskLink.php index 6b23d05..47d70d1 100644 --- a/sources/app/Api/TaskLink.php +++ b/sources/app/Api/TaskLink.php @@ -1,6 +1,6 @@ $is_project_admin, ); - list($valid,) = $this->user->validateCreation($values); + list($valid, ) = $this->user->validateCreation($values); return $valid ? $this->user->create($values) : false; } @@ -81,7 +81,7 @@ class User extends \Core\Base } } - list($valid,) = $this->user->validateApiModification($values); + list($valid, ) = $this->user->validateApiModification($values); return $valid && $this->user->update($values); } } diff --git a/sources/app/Auth/Base.php b/sources/app/Auth/Base.php deleted file mode 100644 index ebf6681..0000000 --- a/sources/app/Auth/Base.php +++ /dev/null @@ -1,34 +0,0 @@ -container = $container; - $this->db = $this->container['db']; - } -} diff --git a/sources/app/Auth/Database.php b/sources/app/Auth/Database.php index e69f18a..91b17a5 100644 --- a/sources/app/Auth/Database.php +++ b/sources/app/Auth/Database.php @@ -1,9 +1,10 @@ findUser($username, $password); if (is_array($result)) { - $user = $this->user->getByUsername($username); if (! empty($user)) { @@ -226,14 +226,12 @@ class Ldap extends Base if ($user['is_ldap_user'] == 0) { return false; } - } - else { + } else { // We create automatically a new user if ($this->isLdapAccountCreationEnabled() && $this->user->create($result) !== false) { $user = $this->user->getByUsername($username); - } - else { + } else { return false; } } @@ -319,12 +317,10 @@ class Ldap extends Base if ($this->getLdapBindType() === 'user') { $ldap_username = sprintf($this->getLdapUsername(), $username); $ldap_password = $password; - } - else if ($this->getLdapBindType() === 'proxy') { + } elseif ($this->getLdapBindType() === 'proxy') { $ldap_username = $this->getLdapUsername(); $ldap_password = $this->getLdapPassword(); - } - else { + } else { $ldap_username = null; $ldap_password = null; } @@ -486,11 +482,9 @@ class Ldap extends Base { if (! empty($username) && ! empty($email)) { return '(&('.$this->getLdapUserPattern($username).')('.$this->getLdapAccountEmail().'='.$email.'))'; - } - else if (! empty($username)) { + } elseif (! empty($username)) { return $this->getLdapUserPattern($username); - } - else if (! empty($email)) { + } elseif (! empty($email)) { return '('.$this->getLdapAccountEmail().'='.$email.')'; } @@ -508,7 +502,7 @@ class Ldap extends Base */ private function getEntry(array $entries, $key, $default = '') { - return isset($entries[0][$key][0]) ? $entries[0][$key][0] : $default; + return isset($entries[0][$key][0]) ? $entries[0][$key][0] : $default; } /** @@ -522,6 +516,6 @@ class Ldap extends Base */ private function getEntries(array $entries, $key, $default = array()) { - return isset($entries[0][$key]) ? $entries[0][$key] : $default; + return isset($entries[0][$key]) ? $entries[0][$key] : $default; } } diff --git a/sources/app/Auth/RememberMe.php b/sources/app/Auth/RememberMe.php index 54e6042..0290e36 100644 --- a/sources/app/Auth/RememberMe.php +++ b/sources/app/Auth/RememberMe.php @@ -1,10 +1,11 @@ readCookie(); if ($credentials !== false) { - $record = $this->find($credentials['token'], $credentials['sequence']); if ($record) { @@ -144,7 +144,6 @@ class RememberMe extends Base $credentials = $this->readCookie(); if ($credentials !== false) { - $this->deleteCookie(); $this->db diff --git a/sources/app/Auth/ReverseProxy.php b/sources/app/Auth/ReverseProxy.php index 7818254..1910ad3 100644 --- a/sources/app/Auth/ReverseProxy.php +++ b/sources/app/Auth/ReverseProxy.php @@ -1,8 +1,9 @@ rewind(); while ($it->valid()) { - if (! $it->isDot() && substr($it->key(), -4) === '.php') { $strings = array_merge($strings, $this->search($it->key())); } @@ -72,7 +71,7 @@ class LocaleComparator extends Base $strings = array_merge($strings, $matches[1]); } - array_walk($strings, function(&$value) { + array_walk($strings, function (&$value) { $value = trim($value, "'"); $value = str_replace("\'", "'", $value); }); diff --git a/sources/app/Console/LocaleSync.php b/sources/app/Console/LocaleSync.php index ab95651..d62b40b 100644 --- a/sources/app/Console/LocaleSync.php +++ b/sources/app/Console/LocaleSync.php @@ -1,6 +1,6 @@ isDot() && $fileInfo->isDir() && $fileInfo->getFilename() !== self::REF_LOCALE) { - $filename = 'app/Locale/'.$fileInfo->getFilename().'/translations.php'; echo $fileInfo->getFilename().' ('.$filename.')'.PHP_EOL; @@ -42,11 +40,9 @@ class LocaleSync extends Base $output .= 'return array('.PHP_EOL; foreach ($reference as $key => $value) { - if (! empty($outdated[$key])) { $output .= " '".str_replace("'", "\'", $key)."' => '".str_replace("'", "\'", $outdated[$key])."',\n"; - } - else { + } else { $output .= " // '".str_replace("'", "\'", $key)."' => '',\n"; } } diff --git a/sources/app/Console/ProjectDailyColumnStatsExport.php b/sources/app/Console/ProjectDailyColumnStatsExport.php index b983066..2513fbf 100644 --- a/sources/app/Console/ProjectDailyColumnStatsExport.php +++ b/sources/app/Console/ProjectDailyColumnStatsExport.php @@ -1,8 +1,8 @@ action->validateCreation($values); + list($valid, ) = $this->action->validateCreation($values); if ($valid) { - if ($this->action->create($values) !== false) { $this->session->flash(t('Your automatic action have been created successfully.')); - } - else { + } else { $this->session->flashError(t('Unable to create your automatic action.')); } } diff --git a/sources/app/Controller/Activity.php b/sources/app/Controller/Activity.php index 234e4be..24327c2 100644 --- a/sources/app/Controller/Activity.php +++ b/sources/app/Controller/Activity.php @@ -1,6 +1,6 @@ response->html($this->layout('app/notifications', array( 'title' => t('My notifications'), - 'notifications' => $this->webNotification->getAll($user['id']), + 'notifications' => $this->userUnreadNotification->getAll($user['id']), 'user' => $user, ))); } @@ -227,17 +227,21 @@ class App extends Base public function autocomplete() { $search = $this->request->getStringParam('term'); + $projects = $this->projectPermission->getActiveMemberProjectIds($this->userSession->getId()); + + if (empty($projects)) { + $this->response->json(array()); + } $filter = $this->taskFilterAutoCompleteFormatter ->create() - ->filterByProjects($this->projectPermission->getActiveMemberProjectIds($this->userSession->getId())) + ->filterByProjects($projects) ->excludeTasks(array($this->request->getIntegerParam('exclude_task_id'))); // Search by task id or by title if (ctype_digit($search)) { $filter->filterById($search); - } - else { + } else { $filter->filterByTitle($search); } diff --git a/sources/app/Controller/Auth.php b/sources/app/Controller/Auth.php index bb1154e..95ad8d9 100644 --- a/sources/app/Controller/Auth.php +++ b/sources/app/Controller/Auth.php @@ -1,6 +1,6 @@ authentication->validateForm($values); if ($valid) { - if (! empty($this->session['login_redirect']) && ! filter_var($this->session['login_redirect'], FILTER_VALIDATE_URL)) { $redirect = $this->session['login_redirect']; unset($this->session['login_redirect']); diff --git a/sources/app/Controller/Base.php b/sources/app/Controller/Base.php index e0fd59c..a955b12 100644 --- a/sources/app/Controller/Base.php +++ b/sources/app/Controller/Base.php @@ -1,14 +1,11 @@ container['db']->getLogMessages() as $message) { $this->container['logger']->debug($message); } @@ -123,7 +119,6 @@ abstract class Base extends \Core\Base public function handleAuthentication() { if (! $this->authentication->isAuthenticated()) { - if ($this->request->isAjax()) { $this->response->text('Not Authorized', 401); } @@ -143,7 +138,6 @@ abstract class Base extends \Core\Base $ignore = ($controller === 'twofactor' && in_array($action, array('code', 'check'))) || ($controller === 'auth' && $action === 'logout'); if ($ignore === false && $this->userSession->has2FA() && ! $this->userSession->check2FA()) { - if ($this->request->isAjax()) { $this->response->text('Not Authorized', 401); } diff --git a/sources/app/Controller/Board.php b/sources/app/Controller/Board.php index 840db05..2d75db8 100644 --- a/sources/app/Controller/Board.php +++ b/sources/app/Controller/Board.php @@ -1,6 +1,6 @@ getTask(); $this->response->html($this->template->render('board/tooltip_comments', array( - 'comments' => $this->comment->getAll($task['id']) + 'comments' => $this->comment->getAll($task['id'], $this->userSession->getCommentSorting()) ))); } @@ -239,12 +239,11 @@ class Board extends Base { $values = $this->request->getValues(); - list($valid,) = $this->taskValidator->validateAssigneeModification($values); + list($valid, ) = $this->taskValidator->validateAssigneeModification($values); if ($valid && $this->taskModification->update($values)) { $this->session->flash(t('Task updated successfully.')); - } - else { + } else { $this->session->flashError(t('Unable to update your task.')); } @@ -277,12 +276,11 @@ class Board extends Base { $values = $this->request->getValues(); - list($valid,) = $this->taskValidator->validateCategoryModification($values); + list($valid, ) = $this->taskValidator->validateCategoryModification($values); if ($valid && $this->taskModification->update($values)) { $this->session->flash(t('Task updated successfully.')); - } - else { + } else { $this->session->flashError(t('Unable to update your task.')); } @@ -365,8 +363,7 @@ class Board extends Base if ($this->request->isAjax()) { $this->response->html($this->renderBoard($project_id)); - } - else { + } else { $this->response->redirect($this->helper->url->to('board', 'show', array('project_id' => $project_id))); } } diff --git a/sources/app/Controller/Calendar.php b/sources/app/Controller/Calendar.php index 7050e54..67a402d 100644 --- a/sources/app/Controller/Calendar.php +++ b/sources/app/Controller/Calendar.php @@ -1,8 +1,8 @@ config->get('calendar_project_tasks', 'date_started') === 'date_creation') { $events = $filter->copy()->filterByCreationDateRange($start, $end)->setColumns('date_creation', 'date_completed')->format(); - } - else { + } else { $events = $filter->copy()->filterByStartDateRange($start, $end)->setColumns('date_started', 'date_completed')->format(); } @@ -79,8 +78,7 @@ class Calendar extends Base // Tasks if ($this->config->get('calendar_user_tasks', 'date_started') === 'date_creation') { $events = array_merge($events, $filter->copy()->filterByCreationDateRange($start, $end)->setColumns('date_creation', 'date_completed')->format()); - } - else { + } else { $events = array_merge($events, $filter->copy()->filterByStartDateRange($start, $end)->setColumns('date_started', 'date_completed')->format()); } @@ -106,7 +104,6 @@ class Calendar extends Base public function save() { if ($this->request->isAjax() && $this->request->isPost()) { - $values = $this->request->getJson(); $this->taskModification->update(array( diff --git a/sources/app/Controller/Category.php b/sources/app/Controller/Category.php index e8d83f2..4aefd9f 100644 --- a/sources/app/Controller/Category.php +++ b/sources/app/Controller/Category.php @@ -1,6 +1,6 @@ category->validateCreation($values); if ($valid) { - if ($this->category->create($values)) { $this->session->flash(t('Your category have been created successfully.')); $this->response->redirect($this->helper->url->to('category', 'index', array('project_id' => $project['id']))); - } - else { + } else { $this->session->flashError(t('Unable to create your category.')); } } @@ -104,12 +102,10 @@ class Category extends Base list($valid, $errors) = $this->category->validateModification($values); if ($valid) { - if ($this->category->update($values)) { $this->session->flash(t('Your category have been updated successfully.')); $this->response->redirect($this->helper->url->to('category', 'index', array('project_id' => $project['id']))); - } - else { + } else { $this->session->flashError(t('Unable to update your category.')); } } diff --git a/sources/app/Controller/Column.php b/sources/app/Controller/Column.php index 89c495a..d28fb29 100644 --- a/sources/app/Controller/Column.php +++ b/sources/app/Controller/Column.php @@ -1,6 +1,6 @@ board->validateCreation($data); if ($valid) { - if ($this->board->addColumn($project['id'], $data['title'], $data['task_limit'], $data['description'])) { $this->session->flash(t('Board updated successfully.')); $this->response->redirect($this->helper->url->to('column', 'index', array('project_id' => $project['id']))); - } - else { + } else { $this->session->flashError(t('Unable to update this board.')); } } @@ -99,12 +97,10 @@ class Column extends Base list($valid, $errors) = $this->board->validateModification($values); if ($valid) { - if ($this->board->updateColumn($values['id'], $values['title'], $values['task_limit'], $values['description'])) { $this->session->flash(t('Board updated successfully.')); $this->response->redirect($this->helper->url->to('column', 'index', array('project_id' => $project['id']))); - } - else { + } else { $this->session->flashError(t('Unable to update this board.')); } } @@ -160,8 +156,7 @@ class Column extends Base if (! empty($column) && $this->board->removeColumn($column['id'])) { $this->session->flash(t('Column removed successfully.')); - } - else { + } else { $this->session->flashError(t('Unable to remove this column.')); } diff --git a/sources/app/Controller/Comment.php b/sources/app/Controller/Comment.php index 81fd721..d6cbbf1 100644 --- a/sources/app/Controller/Comment.php +++ b/sources/app/Controller/Comment.php @@ -1,6 +1,6 @@ comment->validateCreation($values); if ($valid) { - if ($this->comment->create($values)) { $this->session->flash(t('Comment added successfully.')); - } - else { + } else { $this->session->flashError(t('Unable to create your comment.')); } @@ -132,11 +130,9 @@ class Comment extends Base list($valid, $errors) = $this->comment->validateModification($values); if ($valid) { - if ($this->comment->update($values)) { $this->session->flash(t('Comment updated successfully.')); - } - else { + } else { $this->session->flashError(t('Unable to update your comment.')); } @@ -176,11 +172,25 @@ class Comment extends Base if ($this->comment->remove($comment['id'])) { $this->session->flash(t('Comment removed successfully.')); - } - else { + } else { $this->session->flashError(t('Unable to remove this comment.')); } $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), 'comments')); } + + /** + * Toggle comment sorting + * + * @access public + */ + public function toggleSorting() + { + $task = $this->getTask(); + + $order = $this->userSession->getCommentSorting() === 'ASC' ? 'DESC' : 'ASC'; + $this->userSession->setCommentSorting($order); + + $this->response->redirect($this->helper->url->href('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'comments')); + } } diff --git a/sources/app/Controller/Config.php b/sources/app/Controller/Config.php index 1ae390c..47b844e 100644 --- a/sources/app/Controller/Config.php +++ b/sources/app/Controller/Config.php @@ -1,6 +1,6 @@ request->isPost()) { - $values = $this->request->getValues(); switch ($redirect) { @@ -45,7 +44,7 @@ class Config extends Base $values += array('subtask_restriction' => 0, 'subtask_time_tracking' => 0, 'cfd_include_closed_tasks' => 0); break; case 'integrations': - $values += array('integration_slack_webhook' => 0, 'integration_hipchat' => 0, 'integration_gravatar' => 0, 'integration_jabber' => 0); + $values += array('integration_gravatar' => 0); break; case 'calendar': $values += array('calendar_user_subtasks_time_tracking' => 0); @@ -55,8 +54,7 @@ class Config extends Base if ($this->config->save($values)) { $this->config->reload(); $this->session->flash(t('Settings saved successfully.')); - } - else { + } else { $this->session->flashError(t('Unable to save your settings.')); } diff --git a/sources/app/Controller/Currency.php b/sources/app/Controller/Currency.php index 10fb90d..9d6b024 100644 --- a/sources/app/Controller/Currency.php +++ b/sources/app/Controller/Currency.php @@ -1,6 +1,6 @@ currency->validate($values); if ($valid) { - if ($this->currency->create($values['currency'], $values['rate'])) { $this->session->flash(t('The currency rate have been added successfully.')); $this->response->redirect($this->helper->url->to('currency', 'index')); - } - else { + } else { $this->session->flashError(t('Unable to add this currency rate.')); } } @@ -79,8 +77,7 @@ class Currency extends Base if ($this->config->save($values)) { $this->config->reload(); $this->session->flash(t('Settings saved successfully.')); - } - else { + } else { $this->session->flashError(t('Unable to save your settings.')); } diff --git a/sources/app/Controller/Customfilter.php b/sources/app/Controller/Customfilter.php index c403cb4..a152c66 100644 --- a/sources/app/Controller/Customfilter.php +++ b/sources/app/Controller/Customfilter.php @@ -1,6 +1,6 @@ customFilter->create($values)) { $this->session->flash(t('Your custom filter have been created successfully.')); $this->response->redirect($this->helper->url->to('customfilter', 'index', array('project_id' => $project['id']))); - } - else { + } else { $this->session->flashError(t('Unable to create your custom filter.')); } } @@ -116,14 +115,17 @@ class Customfilter extends Base $values += array('is_shared' => 0); } + if (! isset($values['append'])) { + $values += array('append' => 0); + } + list($valid, $errors) = $this->customFilter->validateModification($values); if ($valid) { if ($this->customFilter->update($values)) { $this->session->flash(t('Your custom filter have been updated successfully.')); $this->response->redirect($this->helper->url->to('customfilter', 'index', array('project_id' => $project['id']))); - } - else { + } else { $this->session->flashError(t('Unable to update custom filter.')); } } diff --git a/sources/app/Controller/Doc.php b/sources/app/Controller/Doc.php index f9f0a67..3241304 100644 --- a/sources/app/Controller/Doc.php +++ b/sources/app/Controller/Doc.php @@ -1,6 +1,6 @@ helper->url; $data = file_get_contents($filename); - list($title,) = explode("\n", $data, 2); + list($title, ) = explode("\n", $data, 2); $replaceUrl = function (array $matches) use ($url) { return '('.$url->to('doc', 'show', array('file' => str_replace('.markdown', '', $matches[1]))).')'; diff --git a/sources/app/Controller/Export.php b/sources/app/Controller/Export.php index 8b558c0..cdedcb8 100644 --- a/sources/app/Controller/Export.php +++ b/sources/app/Controller/Export.php @@ -1,6 +1,6 @@ getTask(); if ($this->request->isPost() && $this->file->uploadScreenshot($task['project_id'], $task['id'], $this->request->getValue('screenshot')) !== false) { - $this->session->flash(t('Screenshot uploaded successfully.')); if ($this->request->getStringParam('redirect') === 'board') { @@ -77,7 +76,6 @@ class File extends Base public function download() { try { - $task = $this->getTask(); $file = $this->file->getById($this->request->getIntegerParam('file_id')); @@ -87,8 +85,7 @@ class File extends Base $this->response->forceDownload($file['name']); $this->objectStorage->output($file['path']); - } - catch (ObjectStorageException $e) { + } catch (ObjectStorageException $e) { $this->logger->error($e->getMessage()); } } @@ -112,50 +109,48 @@ class File extends Base } /** - * Return the file content (work only for images) + * Display image * * @access public */ public function image() { try { - $task = $this->getTask(); $file = $this->file->getById($this->request->getIntegerParam('file_id')); - if ($file['task_id'] != $task['id']) { - $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']))); + if ($file['task_id'] == $task['id']) { + $this->response->contentType($this->file->getImageMimeType($file['name'])); + $this->objectStorage->output($file['path']); } - - $this->response->contentType($this->file->getImageMimeType($file['name'])); - $this->objectStorage->output($file['path']); - } - catch (ObjectStorageException $e) { + } catch (ObjectStorageException $e) { $this->logger->error($e->getMessage()); } } /** - * Return image thumbnails + * Display image thumbnails * * @access public */ public function thumbnail() { - try { + $this->response->contentType('image/jpeg'); + try { $task = $this->getTask(); $file = $this->file->getById($this->request->getIntegerParam('file_id')); - if ($file['task_id'] != $task['id']) { - $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']))); + if ($file['task_id'] == $task['id']) { + $this->objectStorage->output($this->file->getThumbnailPath($file['path'])); } - - $this->response->contentType('image/jpeg'); - $this->objectStorage->output($this->file->getThumbnailPath($file['path'])); - } - catch (ObjectStorageException $e) { + } catch (ObjectStorageException $e) { $this->logger->error($e->getMessage()); + + // Try to generate thumbnail on the fly for images uploaded before Kanboard < 1.0.19 + $data = $this->objectStorage->get($file['path']); + $this->file->generateThumbnailFromData($file['path'], $data); + $this->objectStorage->output($this->file->getThumbnailPath($file['path'])); } } diff --git a/sources/app/Controller/Gantt.php b/sources/app/Controller/Gantt.php index 879ab37..24d94f0 100644 --- a/sources/app/Controller/Gantt.php +++ b/sources/app/Controller/Gantt.php @@ -1,8 +1,8 @@ userSession->isAdmin()) { $project_ids = $this->project->getAllIds(); - } - else { + } else { $project_ids = $this->projectPermission->getMemberProjectIds($this->userSession->getId()); } @@ -62,8 +61,7 @@ class Gantt extends Base if ($sorting === 'date') { $filter->getQuery()->asc(TaskModel::TABLE.'.date_started')->asc(TaskModel::TABLE.'.date_creation'); - } - else { + } else { $filter->getQuery()->asc('column_position')->asc(TaskModel::TABLE.'.position'); } @@ -134,14 +132,12 @@ class Gantt extends Base list($valid, $errors) = $this->taskValidator->validateCreation($values); if ($valid) { - $task_id = $this->taskCreation->create($values); if ($task_id !== false) { $this->session->flash(t('Task created successfully.')); $this->response->redirect($this->helper->url->to('gantt', 'project', array('project_id' => $project['id']))); - } - else { + } else { $this->session->flashError(t('Unable to create your task.')); } } diff --git a/sources/app/Controller/Ical.php b/sources/app/Controller/Ical.php index e89b7e3..f8e9e25 100644 --- a/sources/app/Controller/Ical.php +++ b/sources/app/Controller/Ical.php @@ -1,8 +1,8 @@ setColumns('date_creation', 'date_completed') ->setCalendar($calendar) ->addDateTimeEvents(); - } - else { + } else { $filter ->copy() ->filterByStartDateRange($start, $end) diff --git a/sources/app/Controller/Link.php b/sources/app/Controller/Link.php index 482e415..0eb3d67 100644 --- a/sources/app/Controller/Link.php +++ b/sources/app/Controller/Link.php @@ -1,6 +1,6 @@ link->validateCreation($values); if ($valid) { - if ($this->link->create($values['label'], $values['opposite_label']) !== false) { $this->session->flash(t('Link added successfully.')); $this->response->redirect($this->helper->url->to('link', 'index')); - } - else { + } else { $this->session->flashError(t('Unable to create your link.')); } } @@ -116,8 +114,7 @@ class Link extends Base if ($this->link->update($values)) { $this->session->flash(t('Link updated successfully.')); $this->response->redirect($this->helper->url->to('link', 'index')); - } - else { + } else { $this->session->flashError(t('Unable to update your link.')); } } @@ -152,8 +149,7 @@ class Link extends Base if ($this->link->remove($link['id'])) { $this->session->flash(t('Link removed successfully.')); - } - else { + } else { $this->session->flashError(t('Unable to remove this link.')); } diff --git a/sources/app/Controller/Listing.php b/sources/app/Controller/Listing.php index 2c197e3..b9c851f 100644 --- a/sources/app/Controller/Listing.php +++ b/sources/app/Controller/Listing.php @@ -1,8 +1,8 @@ authentication->backend($backend)->unlink($this->userSession->getId())) { $this->session->flash(t('Your external account is not linked anymore to your profile.')); - } - else { + } else { $this->session->flashError(t('Unable to unlink your external account.')); } @@ -71,8 +70,7 @@ class Oauth extends Base if (! empty($code)) { $this->step2($backend, $code); - } - else { + } else { $this->response->redirect($this->authentication->backend($backend)->getService()->getAuthorizationUrl()); } } @@ -102,8 +100,7 @@ class Oauth extends Base { if (empty($profile)) { $this->session->flashError(t('External authentication failed')); - } - else { + } else { $this->session->flash(t('Your external account is linked to your profile successfully.')); $this->authentication->backend($backend)->updateUser($this->userSession->getId(), $profile); } @@ -120,8 +117,7 @@ class Oauth extends Base { if (! empty($profile) && $this->authentication->backend($backend)->authenticate($profile['id'])) { $this->response->redirect($this->helper->url->to('app', 'index')); - } - else { + } else { $this->response->html($this->template->layout('auth/index', array( 'errors' => array('login' => t('External authentication failed')), 'values' => array(), diff --git a/sources/app/Controller/Project.php b/sources/app/Controller/Project.php index 3e3e47c..f30d70e 100644 --- a/sources/app/Controller/Project.php +++ b/sources/app/Controller/Project.php @@ -1,6 +1,6 @@ userSession->isAdmin()) { $project_ids = $this->project->getAllIds(); - } - else { + } else { $project_ids = $this->projectPermission->getMemberProjectIds($this->userSession->getId()); } @@ -68,13 +67,11 @@ class Project extends Base $switch = $this->request->getStringParam('switch'); if ($switch === 'enable' || $switch === 'disable') { - $this->checkCSRFParam(); if ($this->project->{$switch.'PublicAccess'}($project['id'])) { $this->session->flash(t('Project updated successfully.')); - } - else { + } else { $this->session->flashError(t('Unable to update this project.')); } @@ -92,28 +89,49 @@ class Project extends Base * * @access public */ - public function integration() + public function integrations() { $project = $this->getProject(); if ($this->request->isPost()) { - $params = $this->request->getValues(); - $params += array('hipchat' => 0, 'slack' => 0, 'jabber' => 0); - $this->projectIntegration->saveParameters($project['id'], $params); + $this->projectMetadata->save($project['id'], $this->request->getValues()); + $this->session->flash(t('Project updated successfully.')); + $this->response->redirect($this->helper->url->to('project', 'integrations', array('project_id' => $project['id']))); } - $values = $this->projectIntegration->getParameters($project['id']); - $values += array('hipchat_api_url' => 'https://api.hipchat.com'); - $this->response->html($this->projectLayout('project/integrations', array( 'project' => $project, 'title' => t('Integrations'), 'webhook_token' => $this->config->get('webhook_token'), - 'values' => $values, + 'values' => $this->projectMetadata->getAll($project['id']), 'errors' => array(), ))); } + /** + * Display project notifications + * + * @access public + */ + public function notifications() + { + $project = $this->getProject(); + + if ($this->request->isPost()) { + $values = $this->request->getValues(); + $this->projectNotification->saveSettings($project['id'], $values); + $this->session->flash(t('Project updated successfully.')); + $this->response->redirect($this->helper->url->to('project', 'notifications', array('project_id' => $project['id']))); + } + + $this->response->html($this->projectLayout('project/notifications', array( + 'notifications' => $this->projectNotification->readSettings($project['id']), + 'types' => $this->projectNotificationType->getTypes(), + 'project' => $project, + 'title' => t('Notifications'), + ))); + } + /** * Display a form to edit a project * @@ -145,8 +163,7 @@ class Project extends Base if (! $this->helper->user->isProjectAdministrationAllowed($project['id'])) { unset($values['is_private']); } - } - else if ($project['is_private'] == 1 && ! isset($values['is_private'])) { + } elseif ($project['is_private'] == 1 && ! isset($values['is_private'])) { if ($this->helper->user->isProjectAdministrationAllowed($project['id'])) { $values += array('is_private' => 0); } @@ -155,12 +172,10 @@ class Project extends Base list($valid, $errors) = $this->project->validateModification($values); if ($valid) { - if ($this->project->update($values)) { $this->session->flash(t('Project updated successfully.')); $this->response->redirect($this->helper->url->to('project', 'edit', array('project_id' => $project['id']))); - } - else { + } else { $this->session->flashError(t('Unable to update this project.')); } } @@ -193,14 +208,12 @@ class Project extends Base { $project = $this->getProject(); $values = $this->request->getValues() + array('is_everybody_allowed' => 0); - list($valid,) = $this->projectPermission->validateProjectModification($values); + list($valid, ) = $this->projectPermission->validateProjectModification($values); if ($valid) { - if ($this->project->update($values)) { $this->session->flash(t('Project updated successfully.')); - } - else { + } else { $this->session->flashError(t('Unable to update this project.')); } } @@ -216,14 +229,12 @@ class Project extends Base public function allow() { $values = $this->request->getValues(); - list($valid,) = $this->projectPermission->validateUserModification($values); + list($valid, ) = $this->projectPermission->validateUserModification($values); if ($valid) { - if ($this->projectPermission->addMember($values['project_id'], $values['user_id'])) { $this->session->flash(t('Project updated successfully.')); - } - else { + } else { $this->session->flashError(t('Unable to update this project.')); } } @@ -246,14 +257,12 @@ class Project extends Base 'is_owner' => $this->request->getIntegerParam('is_owner'), ); - list($valid,) = $this->projectPermission->validateUserModification($values); + 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 { + } else { $this->session->flashError(t('Unable to update this project.')); } } @@ -275,14 +284,12 @@ class Project extends Base 'user_id' => $this->request->getIntegerParam('user_id'), ); - list($valid,) = $this->projectPermission->validateUserModification($values); + list($valid, ) = $this->projectPermission->validateUserModification($values); if ($valid) { - if ($this->projectPermission->revokeMember($values['project_id'], $values['user_id'])) { $this->session->flash(t('Project updated successfully.')); - } - else { + } else { $this->session->flashError(t('Unable to update this project.')); } } @@ -300,7 +307,6 @@ class Project extends Base $project = $this->getProject(); if ($this->request->getStringParam('remove') === 'yes') { - $this->checkCSRFParam(); if ($this->project->remove($project['id'])) { @@ -356,7 +362,6 @@ class Project extends Base $project = $this->getProject(); if ($this->request->getStringParam('disable') === 'yes') { - $this->checkCSRFParam(); if ($this->project->disable($project['id'])) { @@ -384,7 +389,6 @@ class Project extends Base $project = $this->getProject(); if ($this->request->getStringParam('enable') === 'yes') { - $this->checkCSRFParam(); if ($this->project->enable($project['id'])) { @@ -431,7 +435,6 @@ class Project extends Base list($valid, $errors) = $this->project->validateCreation($values); if ($valid) { - $project_id = $this->project->create($values, $this->userSession->getId(), true); if ($project_id > 0) { diff --git a/sources/app/Controller/Projectuser.php b/sources/app/Controller/Projectuser.php index 4456ce3..18829b3 100644 --- a/sources/app/Controller/Projectuser.php +++ b/sources/app/Controller/Projectuser.php @@ -1,9 +1,9 @@ userSession->isAdmin()) { $project_ids = $this->project->getAllIds(); - } - else { + } else { $project_ids = $this->projectPermission->getMemberProjectIds($this->userSession->getId()); } diff --git a/sources/app/Controller/Search.php b/sources/app/Controller/Search.php index f6dc7a3..0aff907 100644 --- a/sources/app/Controller/Search.php +++ b/sources/app/Controller/Search.php @@ -1,6 +1,6 @@ setOrder('tasks.id') ->setDirection('DESC'); - if ($search !== '') { - + if ($search !== '' && ! empty($projects)) { $query = $this ->taskFilter ->search($search) diff --git a/sources/app/Controller/Subtask.php b/sources/app/Controller/Subtask.php index 338918f..4ef3e74 100644 --- a/sources/app/Controller/Subtask.php +++ b/sources/app/Controller/Subtask.php @@ -1,8 +1,8 @@ subtask->validateCreation($values); if ($valid) { - if ($this->subtask->create($values)) { $this->session->flash(t('Sub-task added successfully.')); - } - else { + } else { $this->session->flashError(t('Unable to create your sub-task.')); } @@ -118,11 +116,9 @@ class Subtask extends Base list($valid, $errors) = $this->subtask->validateModification($values); if ($valid) { - if ($this->subtask->update($values)) { $this->session->flash(t('Sub-task updated successfully.')); - } - else { + } else { $this->session->flashError(t('Unable to update your sub-task.')); } @@ -161,8 +157,7 @@ class Subtask extends Base if ($this->subtask->remove($subtask['id'])) { $this->session->flash(t('Sub-task removed successfully.')); - } - else { + } else { $this->session->flashError(t('Unable to remove this sub-task.')); } @@ -183,7 +178,6 @@ class Subtask extends Base $this->subtask->toggleStatus($subtask['id']); if ($redirect === 'board') { - $this->session['has_subtask_inprogress'] = $this->subtask->hasSubtaskInProgress($this->userSession->getId()); $this->response->html($this->template->render('board/tooltip_subtasks', array( diff --git a/sources/app/Controller/Swimlane.php b/sources/app/Controller/Swimlane.php index f92e9fe..0b29f59 100644 --- a/sources/app/Controller/Swimlane.php +++ b/sources/app/Controller/Swimlane.php @@ -1,8 +1,8 @@ swimlane->validateCreation($values); if ($valid) { - if ($this->swimlane->create($values)) { $this->session->flash(t('Your swimlane have been created successfully.')); $this->response->redirect($this->helper->url->to('swimlane', 'index', array('project_id' => $project['id']))); - } - else { + } else { $this->session->flashError(t('Unable to create your swimlane.')); } } @@ -86,15 +84,13 @@ class Swimlane extends Base $project = $this->getProject(); $values = $this->request->getValues() + array('show_default_swimlane' => 0); - list($valid,) = $this->swimlane->validateDefaultModification($values); + 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($this->helper->url->to('swimlane', 'index', array('project_id' => $project['id']))); - } - else { + } else { $this->session->flashError(t('Unable to update this swimlane.')); } } @@ -136,8 +132,7 @@ class Swimlane extends Base if ($this->swimlane->update($values)) { $this->session->flash(t('Swimlane updated successfully.')); $this->response->redirect($this->helper->url->to('swimlane', 'index', array('project_id' => $project['id']))); - } - else { + } else { $this->session->flashError(t('Unable to update this swimlane.')); } } diff --git a/sources/app/Controller/Task.php b/sources/app/Controller/Task.php index 0770fcd..894802d 100644 --- a/sources/app/Controller/Task.php +++ b/sources/app/Controller/Task.php @@ -1,6 +1,6 @@ $this->project->getById($task['project_id']), 'files' => $this->file->getAllDocuments($task['id']), 'images' => $this->file->getAllImages($task['id']), - 'comments' => $this->comment->getAll($task['id']), + 'comments' => $this->comment->getAll($task['id'], $this->userSession->getCommentSorting()), 'subtasks' => $subtasks, 'links' => $this->taskLink->getAllGroupedByLabel($task['id']), 'task' => $task, @@ -156,7 +156,6 @@ class Task extends Base } if ($this->request->getStringParam('confirmation') === 'yes') { - $this->checkCSRFParam(); if ($this->task->remove($task['id'])) { diff --git a/sources/app/Controller/Taskcreation.php b/sources/app/Controller/Taskcreation.php index b9e9a33..e47cd1b 100644 --- a/sources/app/Controller/Taskcreation.php +++ b/sources/app/Controller/Taskcreation.php @@ -1,6 +1,6 @@ swimlane->getList($project['id'], false, true); if (empty($values)) { - $values = array( 'swimlane_id' => $this->request->getIntegerParam('swimlane_id', key($swimlanes_list)), 'column_id' => $this->request->getIntegerParam('column_id'), @@ -62,8 +61,7 @@ class Taskcreation extends Base if ($valid && $this->taskCreation->create($values)) { $this->session->flash(t('Task created successfully.')); $this->afterSave($project, $values); - } - else { + } else { $this->session->flashError(t('Unable to create your task.')); } @@ -79,8 +77,7 @@ class Taskcreation extends Base if (! $this->request->isAjax()) { $this->response->redirect($this->helper->url->to('taskcreation', 'create', $values)); } - } - else { + } else { $this->response->redirect($this->helper->url->to('board', 'show', array('project_id' => $project['id']))); } } diff --git a/sources/app/Controller/Taskduplication.php b/sources/app/Controller/Taskduplication.php index 8d329ca..79f498f 100644 --- a/sources/app/Controller/Taskduplication.php +++ b/sources/app/Controller/Taskduplication.php @@ -1,6 +1,6 @@ getTask(); if ($this->request->getStringParam('confirmation') === 'yes') { - $this->checkCSRFParam(); $task_id = $this->taskDuplication->duplicate($task['id']); @@ -48,9 +47,8 @@ class Taskduplication extends Base $task = $this->getTask(); if ($this->request->isPost()) { - $values = $this->request->getValues(); - list($valid,) = $this->taskValidator->validateProjectModification($values); + list($valid, ) = $this->taskValidator->validateProjectModification($values); if ($valid && $this->taskDuplication->moveToProject($task['id'], $values['project_id'], @@ -58,7 +56,6 @@ class Taskduplication extends Base $values['column_id'], $values['category_id'], $values['owner_id'])) { - $this->session->flash(t('Task updated successfully.')); $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $values['project_id'], 'task_id' => $task['id']))); } @@ -79,9 +76,8 @@ class Taskduplication extends Base $task = $this->getTask(); if ($this->request->isPost()) { - $values = $this->request->getValues(); - list($valid,) = $this->taskValidator->validateProjectModification($values); + list($valid, ) = $this->taskValidator->validateProjectModification($values); if ($valid) { $task_id = $this->taskDuplication->duplicateToProject( @@ -125,8 +121,7 @@ class Taskduplication extends Base $values = $this->taskDuplication->checkDestinationProjectValues($task); $values['project_id'] = $dst_project_id; - } - else { + } else { $swimlanes_list = array(); $columns_list = array(); $categories_list = array(); diff --git a/sources/app/Controller/Tasklink.php b/sources/app/Controller/Tasklink.php index dd07680..587769e 100644 --- a/sources/app/Controller/Tasklink.php +++ b/sources/app/Controller/Tasklink.php @@ -1,6 +1,6 @@ taskLink->validateCreation($values); if ($valid) { - if ($this->taskLink->create($values['task_id'], $values['opposite_task_id'], $values['link_id'])) { $this->session->flash(t('Link added successfully.')); @@ -129,7 +128,6 @@ class Tasklink extends Base list($valid, $errors) = $this->taskLink->validateModification($values); if ($valid) { - if ($this->taskLink->update($values['id'], $values['task_id'], $values['opposite_task_id'], $values['link_id'])) { $this->session->flash(t('Link updated successfully.')); $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])).'#links'); @@ -162,15 +160,14 @@ class Tasklink extends Base * * @access public */ - public function remove() + public function remove() { $this->checkCSRFParam(); $task = $this->getTask(); if ($this->taskLink->remove($this->request->getIntegerParam('link_id'))) { $this->session->flash(t('Link removed successfully.')); - } - else { + } else { $this->session->flashError(t('Unable to remove this link.')); } diff --git a/sources/app/Controller/Taskmodification.php b/sources/app/Controller/Taskmodification.php index 638af59..b1105dc 100644 --- a/sources/app/Controller/Taskmodification.php +++ b/sources/app/Controller/Taskmodification.php @@ -1,6 +1,6 @@ getTask(); $values = $this->request->getValues(); - list($valid,) = $this->taskValidator->validateTimeModification($values); + list($valid, ) = $this->taskValidator->validateTimeModification($values); if ($valid && $this->taskModification->update($values)) { $this->session->flash(t('Task updated successfully.')); - } - else { + } else { $this->session->flashError(t('Unable to update your task.')); } @@ -55,29 +54,24 @@ class Taskmodification extends Base $ajax = $this->request->isAjax() || $this->request->getIntegerParam('ajax'); if ($this->request->isPost()) { - $values = $this->request->getValues(); list($valid, $errors) = $this->taskValidator->validateDescriptionCreation($values); if ($valid) { - if ($this->taskModification->update($values)) { $this->session->flash(t('Task updated successfully.')); - } - else { + } else { $this->session->flashError(t('Unable to update your task.')); } if ($ajax) { $this->response->redirect($this->helper->url->to('board', 'show', array('project_id' => $task['project_id']))); - } - else { + } else { $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id']))); } } - } - else { + } else { $values = $task; $errors = array(); } @@ -91,8 +85,7 @@ class Taskmodification extends Base if ($ajax) { $this->response->html($this->template->render('task_modification/edit_description', $params)); - } - else { + } else { $this->response->html($this->taskLayout('task_modification/edit_description', $params)); } } @@ -127,8 +120,7 @@ class Taskmodification extends Base if ($ajax) { $html = $this->template->render('task_modification/edit_task', $params); - } - else { + } else { $html = $this->taskLayout('task_modification/edit_task', $params); } @@ -152,12 +144,10 @@ class Taskmodification extends Base if ($this->request->isAjax()) { $this->response->redirect($this->helper->url->to('board', 'show', array('project_id' => $task['project_id']))); - } - else { + } else { $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id']))); } - } - else { + } else { $this->session->flashError(t('Unable to update your task.')); $this->edit($values, $errors); } @@ -173,24 +163,20 @@ class Taskmodification extends Base $task = $this->getTask(); if ($this->request->isPost()) { - $values = $this->request->getValues(); list($valid, $errors) = $this->taskValidator->validateEditRecurrence($values); if ($valid) { - if ($this->taskModification->update($values)) { $this->session->flash(t('Task updated successfully.')); - } - else { + } else { $this->session->flashError(t('Unable to update your task.')); } $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id']))); } - } - else { + } else { $values = $task; $errors = array(); } diff --git a/sources/app/Controller/Taskstatus.php b/sources/app/Controller/Taskstatus.php index 1768b77..c0421ea 100644 --- a/sources/app/Controller/Taskstatus.php +++ b/sources/app/Controller/Taskstatus.php @@ -1,6 +1,6 @@ request->getStringParam('confirmation') === 'yes') { - $this->checkCSRFParam(); if ($this->taskStatus->$method($task['id'])) { diff --git a/sources/app/Controller/Timer.php b/sources/app/Controller/Timer.php index 2a4531b..0267fcd 100644 --- a/sources/app/Controller/Timer.php +++ b/sources/app/Controller/Timer.php @@ -1,6 +1,6 @@ subtaskTimeTracking->logStartTime($subtask_id, $this->userSession->getId()); - } - else if ($timer === 'stop') { + } elseif ($timer === 'stop') { $this->subtaskTimeTracking->logEndTime($subtask_id, $this->userSession->getId()); $this->subtaskTimeTracking->updateTaskTimeTracking($task_id); } diff --git a/sources/app/Controller/Twofactor.php b/sources/app/Controller/Twofactor.php index a8b0351..179241f 100644 --- a/sources/app/Controller/Twofactor.php +++ b/sources/app/Controller/Twofactor.php @@ -1,6 +1,6 @@ 1, 'twofactor_secret' => GoogleAuthenticator::generateRandom(), )); - } - else { + } else { $this->user->update(array( 'id' => $user['id'], 'twofactor_activated' => 0, @@ -94,8 +93,7 @@ class Twofactor extends User if (! empty($values['code']) && $otp->checkTotp(Base32::decode($user['twofactor_secret']), $values['code'])) { $this->session->flash(t('The two factor authentication code is valid.')); - } - else { + } else { $this->session->flashError(t('The two factor authentication code is not valid.')); } @@ -119,8 +117,7 @@ class Twofactor extends User $this->session['2fa_validated'] = true; $this->session->flash(t('The two factor authentication code is valid.')); $this->response->redirect($this->helper->url->to('app', 'index')); - } - else { + } else { $this->session->flashError(t('The two factor authentication code is not valid.')); $this->response->redirect($this->helper->url->to('twofactor', 'code')); } @@ -148,7 +145,6 @@ class Twofactor extends User $user = $this->getUser(); if ($this->request->getStringParam('disable') === 'yes') { - $this->checkCSRFParam(); $this->user->update(array( diff --git a/sources/app/Controller/User.php b/sources/app/Controller/User.php index 0b39619..b5f4ede 100644 --- a/sources/app/Controller/User.php +++ b/sources/app/Controller/User.php @@ -1,8 +1,8 @@ user->validateCreation($values); if ($valid) { - $project_id = empty($values['project_id']) ? 0 : $values['project_id']; unset($values['project_id']); @@ -96,13 +95,12 @@ class User extends Base $this->projectPermission->addMember($project_id, $user_id); if (! empty($values['notifications_enabled'])) { - $this->notificationType->saveUserSelectedTypes($user_id, array(NotificationType::TYPE_EMAIL)); + $this->userNotificationType->saveSelectedTypes($user_id, array(NotificationType::TYPE_EMAIL)); } $this->session->flash(t('User created successfully.')); $this->response->redirect($this->helper->url->to('user', 'show', array('user_id' => $user_id))); - } - else { + } else { $this->session->flashError(t('Unable to create your user.')); $values['project_id'] = $project_id; } @@ -201,20 +199,42 @@ class User extends Base if ($this->request->isPost()) { $values = $this->request->getValues(); - $this->notification->saveSettings($user['id'], $values); + $this->userNotification->saveSettings($user['id'], $values); $this->session->flash(t('User updated successfully.')); $this->response->redirect($this->helper->url->to('user', 'notifications', array('user_id' => $user['id']))); } $this->response->html($this->layout('user/notifications', array( 'projects' => $this->projectPermission->getMemberProjects($user['id']), - 'notifications' => $this->notification->readSettings($user['id']), - 'types' => $this->notificationType->getTypes(), - 'filters' => $this->notificationFilter->getFilters(), + 'notifications' => $this->userNotification->readSettings($user['id']), + 'types' => $this->userNotificationType->getTypes(), + 'filters' => $this->userNotificationFilter->getFilters(), 'user' => $user, ))); } + /** + * Display user integrations + * + * @access public + */ + public function integrations() + { + $user = $this->getUser(); + + if ($this->request->isPost()) { + $values = $this->request->getValues(); + $this->userMetadata->save($user['id'], $values); + $this->session->flash(t('User updated successfully.')); + $this->response->redirect($this->helper->url->to('user', 'integrations', array('user_id' => $user['id']))); + } + + $this->response->html($this->layout('user/integrations', array( + 'user' => $user, + 'values' => $this->userMetadata->getall($user['id']), + ))); + } + /** * Display external accounts * @@ -240,7 +260,6 @@ class User extends Base $switch = $this->request->getStringParam('switch'); if ($switch === 'enable' || $switch === 'disable') { - $this->checkCSRFParam(); if ($this->user->{$switch.'PublicAccess'}($user['id'])) { @@ -270,16 +289,13 @@ class User extends Base $errors = array(); if ($this->request->isPost()) { - $values = $this->request->getValues(); list($valid, $errors) = $this->user->validatePasswordModification($values); if ($valid) { - if ($this->user->update($values)) { $this->session->flash(t('Password modified successfully.')); - } - else { + } else { $this->session->flashError(t('Unable to change the password.')); } @@ -308,13 +324,11 @@ class User extends Base unset($values['password']); if ($this->request->isPost()) { - $values = $this->request->getValues(); if ($this->userSession->isAdmin()) { $values += array('is_admin' => 0, 'is_project_admin' => 0); - } - else { + } else { // Regular users can't be admin if (isset($values['is_admin'])) { unset($values['is_admin']); @@ -328,11 +342,9 @@ class User extends Base list($valid, $errors) = $this->user->validateModification($values); if ($valid) { - if ($this->user->update($values)) { $this->session->flash(t('User updated successfully.')); - } - else { + } else { $this->session->flashError(t('Unable to update your user.')); } @@ -363,16 +375,13 @@ class User extends Base unset($values['password']); if ($this->request->isPost()) { - $values = $this->request->getValues() + array('disable_login_form' => 0, 'is_ldap_user' => 0); list($valid, $errors) = $this->user->validateModification($values); if ($valid) { - if ($this->user->update($values)) { $this->session->flash(t('User updated successfully.')); - } - else { + } else { $this->session->flashError(t('Unable to update your user.')); } @@ -397,7 +406,6 @@ class User extends Base $user = $this->getUser(); if ($this->request->getStringParam('confirmation') === 'yes') { - $this->checkCSRFParam(); if ($this->user->remove($user['id'])) { diff --git a/sources/app/Controller/Webhook.php b/sources/app/Controller/Webhook.php index 1a4cfe9..a7e9bde 100644 --- a/sources/app/Controller/Webhook.php +++ b/sources/app/Controller/Webhook.php @@ -1,6 +1,6 @@ $this->request->getIntegerParam('category_id'), ); - list($valid,) = $this->taskValidator->validateCreation($values); + list($valid, ) = $this->taskValidator->validateCreation($values); if ($valid && $this->taskCreation->create($values)) { $this->response->text('OK'); @@ -92,37 +92,4 @@ class Webhook extends Base echo $result ? 'PARSED' : 'IGNORED'; } - - /** - * Handle Postmark webhooks - * - * @access public - */ - public function postmark() - { - $this->checkWebhookToken(); - echo $this->postmark->receiveEmail($this->request->getJson()) ? 'PARSED' : 'IGNORED'; - } - - /** - * Handle Mailgun webhooks - * - * @access public - */ - public function mailgun() - { - $this->checkWebhookToken(); - echo $this->mailgun->receiveEmail($_POST) ? 'PARSED' : 'IGNORED'; - } - - /** - * Handle Sendgrid webhooks - * - * @access public - */ - public function sendgrid() - { - $this->checkWebhookToken(); - echo $this->sendgrid->receiveEmail($_POST) ? 'PARSED' : 'IGNORED'; - } } diff --git a/sources/app/Controller/Webnotification.php b/sources/app/Controller/Webnotification.php deleted file mode 100644 index a481e9b..0000000 --- a/sources/app/Controller/Webnotification.php +++ /dev/null @@ -1,39 +0,0 @@ -userSession->getId(); - - $this->webNotification->markAllAsRead($user_id); - $this->response->redirect($this->helper->url->to('app', 'notifications', array('user_id' => $user_id))); - } - - /** - * Mark a notification as read - * - * @access public - */ - public function remove() - { - $user_id = $this->userSession->getId(); - $notification_id = $this->request->getIntegerParam('notification_id'); - - $this->webNotification->markAsRead($user_id, $notification_id); - $this->response->redirect($this->helper->url->to('app', 'notifications', array('user_id' => $user_id))); - } -} diff --git a/sources/app/Core/Base.php b/sources/app/Core/Base.php index 7503e84..d402fb3 100644 --- a/sources/app/Core/Base.php +++ b/sources/app/Core/Base.php @@ -1,6 +1,6 @@ container['logger']->debug('Sending email to '.$email.' ('.MAIL_TRANSPORT.')'); - - $start_time = microtime(true); - $author = 'Kanboard'; - - if (Session::isOpen() && $this->userSession->isLogged()) { - $author = e('%s via Kanboard', $this->user->getFullname($this->session['user'])); - } - - switch (MAIL_TRANSPORT) { - case 'sendgrid': - $this->sendgrid->sendEmail($email, $name, $subject, $html, $author); - break; - case 'mailgun': - $this->mailgun->sendEmail($email, $name, $subject, $html, $author); - break; - case 'postmark': - $this->postmark->sendEmail($email, $name, $subject, $html, $author); - break; - default: - $this->smtp->sendEmail($email, $name, $subject, $html, $author); - } - - $this->container['logger']->debug('Email sent in '.round(microtime(true) - $start_time, 6).' seconds'); - } -} diff --git a/sources/app/Core/Helper.php b/sources/app/Core/Helper.php index 64eaed2..5edaa3f 100644 --- a/sources/app/Core/Helper.php +++ b/sources/app/Core/Helper.php @@ -1,6 +1,6 @@ helpers[$name])) { - $class = '\Helper\\'.ucfirst($name); + $class = '\Kanboard\Helper\\'.ucfirst($name); $this->helpers[$name] = new $class($this->container); } diff --git a/sources/app/Core/HttpClient.php b/sources/app/Core/HttpClient.php index 99534cf..7f4ea47 100644 --- a/sources/app/Core/HttpClient.php +++ b/sources/app/Core/HttpClient.php @@ -1,6 +1,6 @@ container['logger']->error('HttpClient: request failed'); } diff --git a/sources/app/Core/Lexer.php b/sources/app/Core/Lexer.php index d7e6fde..ca2ef89 100644 --- a/sources/app/Core/Lexer.php +++ b/sources/app/Core/Lexer.php @@ -1,6 +1,6 @@ offset = 0; while (isset($input[$this->offset])) { - $result = $this->match(substr($input, $this->offset)); if ($result === false) { @@ -84,7 +83,6 @@ class Lexer { foreach ($this->tokenMap as $pattern => $name) { if (preg_match($pattern, $string, $matches)) { - $this->offset += strlen($matches[1]); return array( @@ -113,7 +111,6 @@ class Lexer ); while (false !== ($token = current($tokens))) { - switch ($token['token']) { case 'T_ASSIGNEE': case 'T_COLOR': diff --git a/sources/app/Core/Markdown.php b/sources/app/Core/Markdown.php index fa4e808..f08c486 100644 --- a/sources/app/Core/Markdown.php +++ b/sources/app/Core/Markdown.php @@ -1,9 +1,9 @@ link) && preg_match('!#(\d+)!i', $Excerpt['text'], $matches)) { - $url = $this->helper->href( $this->link['controller'], $this->link['action'], diff --git a/sources/app/Core/NotificationInterface.php b/sources/app/Core/NotificationInterface.php deleted file mode 100644 index 5dca74e..0000000 --- a/sources/app/Core/NotificationInterface.php +++ /dev/null @@ -1,22 +0,0 @@ -accessToken) && ! empty($code)) { - $params = array( 'code' => $code, 'client_id' => $this->clientId, diff --git a/sources/app/Core/ObjectStorage/FileStorage.php b/sources/app/Core/ObjectStorage/FileStorage.php index 75160e7..dd049ca 100644 --- a/sources/app/Core/ObjectStorage/FileStorage.php +++ b/sources/app/Core/ObjectStorage/FileStorage.php @@ -1,6 +1,6 @@ path.DIRECTORY_SEPARATOR.dirname($key) : $this->path; + $folder = strpos($key, DIRECTORY_SEPARATOR) !== false ? $this->path.DIRECTORY_SEPARATOR.dirname($key) : $this->path; if (! is_dir($folder) && ! mkdir($folder, 0755, true)) { throw new ObjectStorageException('Unable to create folder: '.$folder); diff --git a/sources/app/Core/ObjectStorage/ObjectStorageException.php b/sources/app/Core/ObjectStorage/ObjectStorageException.php index e89aeb2..9e98ff5 100644 --- a/sources/app/Core/ObjectStorage/ObjectStorageException.php +++ b/sources/app/Core/ObjectStorage/ObjectStorageException.php @@ -1,6 +1,6 @@ action, $this->getUrlParams($this->page - 1, $this->order, $this->direction) ); - } - else { + } else { $html .= '← '.t('Previous'); } @@ -382,8 +381,7 @@ class Paginator $this->action, $this->getUrlParams($this->page + 1, $this->order, $this->direction) ); - } - else { + } else { $html .= t('Next').' →'; } diff --git a/sources/app/Core/Plugin/Base.php b/sources/app/Core/Plugin/Base.php index 1b7ac8f..1526537 100644 --- a/sources/app/Core/Plugin/Base.php +++ b/sources/app/Core/Plugin/Base.php @@ -1,6 +1,6 @@ container; - $this->container['dispatcher']->addListener($event, function() use ($container, $callback) { + $this->container['dispatcher']->addListener($event, function () use ($container, $callback) { call_user_func($callback, $container); }); } @@ -66,7 +66,7 @@ abstract class Base extends \Core\Base */ public function getPluginName() { - return ucfirst(substr(get_called_class(), 7, -7)); + return ucfirst(substr(get_called_class(), 16, -7)); } /** diff --git a/sources/app/Core/Plugin/Hook.php b/sources/app/Core/Plugin/Hook.php index fa14af1..a3bcd91 100644 --- a/sources/app/Core/Plugin/Hook.php +++ b/sources/app/Core/Plugin/Hook.php @@ -1,6 +1,6 @@ container); Tool::buildDic($this->container, $instance->getClasses()); @@ -90,16 +91,15 @@ class Loader extends \Core\Base */ public function migrateSchema($plugin) { - $last_version = constant('\Plugin\\'.$plugin.'\Schema\VERSION'); + $last_version = constant('\Kanboard\Plugin\\'.$plugin.'\Schema\VERSION'); $current_version = $this->getSchemaVersion($plugin); try { - $this->db->startTransaction(); $this->db->getDriver()->disableForeignKeys(); for ($i = $current_version + 1; $i <= $last_version; $i++) { - $function_name = '\Plugin\\'.$plugin.'\Schema\version_'.$i; + $function_name = '\Kanboard\Plugin\\'.$plugin.'\Schema\version_'.$i; if (function_exists($function_name)) { call_user_func($function_name, $this->db->getConnection()); @@ -109,11 +109,10 @@ class Loader extends \Core\Base $this->db->getDriver()->enableForeignKeys(); $this->db->closeTransaction(); $this->setSchemaVersion($plugin, $i - 1); - } - catch (PDOException $e) { + } catch (PDOException $e) { $this->db->cancelTransaction(); $this->db->getDriver()->enableForeignKeys(); - die('Unable to migrate schema for the plugin: '.$plugin.' => '.$e->getMessage()); + throw new RuntimeException('Unable to migrate schema for the plugin: '.$plugin.' => '.$e->getMessage()); } } diff --git a/sources/app/Core/Request.php b/sources/app/Core/Request.php index 1eff66f..5eda2d0 100644 --- a/sources/app/Core/Request.php +++ b/sources/app/Core/Request.php @@ -1,6 +1,6 @@ status($status_code); $this->nocache(); + header('Content-Type: text/csv'); - Tool::csv($data); + Csv::output($data); exit; } diff --git a/sources/app/Core/Router.php b/sources/app/Core/Router.php index 93d266b..843f513 100644 --- a/sources/app/Core/Router.php +++ b/sources/app/Core/Router.php @@ -1,6 +1,8 @@ paths as $route) { - if ($count === $route['count']) { - $params = array(); for ($i = 0; $i < $count; $i++) { - if ($route['pattern'][$i]{0} === ':') { $params[substr($route['pattern'][$i], 1)] = $parts[$i]; - } - else if ($route['pattern'][$i] !== $parts[$i]) { + } elseif ($route['pattern'][$i] !== $parts[$i]) { break; } } @@ -168,7 +166,6 @@ class Router extends Base } foreach ($this->urls[$controller][$action] as $pattern) { - if (array_diff_key($params, $pattern['params']) === array()) { $url = $pattern['path']; $i = 0; @@ -197,7 +194,7 @@ class Router extends Base */ public function sanitize($value, $default_value) { - return ! ctype_alpha($value) || empty($value) ? $default_value : strtolower($value); + return ! preg_match('/^[a-zA-Z_0-9]+$/', $value) ? $default_value : $value; } /** @@ -213,12 +210,17 @@ class Router extends Base $this->controller = $this->sanitize($_GET['controller'], 'app'); $this->action = $this->sanitize($_GET['action'], 'index'); $plugin = ! empty($_GET['plugin']) ? $this->sanitize($_GET['plugin'], '') : ''; - } - else { + } else { list($this->controller, $this->action) = $this->findRoute($this->getPath($uri, $query_string)); // TODO: add plugin for routes $plugin = ''; } - $class = empty($plugin) ? '\Controller\\'.ucfirst($this->controller) : '\Plugin\\'.ucfirst($plugin).'\Controller\\'.ucfirst($this->controller); + + $class = '\Kanboard\\'; + $class .= empty($plugin) ? 'Controller\\'.ucfirst($this->controller) : 'Plugin\\'.ucfirst($plugin).'\Controller\\'.ucfirst($this->controller); + + if (! class_exists($class) || ! method_exists($class, $this->action)) { + throw new RuntimeException('Controller or method not found for the given url!'); + } $instance = new $class($this->container); $instance->beforeAction($this->controller, $this->action); diff --git a/sources/app/Core/Security.php b/sources/app/Core/Security.php index 0bd7c99..54207ee 100644 --- a/sources/app/Core/Security.php +++ b/sources/app/Core/Security.php @@ -1,6 +1,6 @@ $classes) { foreach ($classes as $name) { - $class = '\\'.$namespace.'\\'.$name; + $class = '\\Kanboard\\'.$namespace.'\\'.$name; $container[lcfirst($name)] = function ($c) use ($class) { return new $class($c); }; @@ -104,14 +83,11 @@ class Tool $dst_width = $resize_width; $dst_height = floor($src_height * ($resize_width / $src_width)); $dst_image = imagecreatetruecolor($dst_width, $dst_height); - } - elseif ($resize_width == 0 && $resize_height > 0) { + } elseif ($resize_width == 0 && $resize_height > 0) { $dst_width = floor($src_width * ($resize_height / $src_height)); $dst_height = $resize_height; $dst_image = imagecreatetruecolor($dst_width, $dst_height); - } - else { - + } else { $src_ratio = $src_width / $src_height; $resize_ratio = $resize_width / $resize_height; @@ -120,8 +96,7 @@ class Tool $dst_height = floor($src_height * ($resize_width / $src_width)); $dst_y = ($dst_height - $resize_height) / 2 * (-1); - } - else { + } else { $dst_width = floor($src_width * ($resize_height / $src_height)); $dst_height = $resize_height; diff --git a/sources/app/Core/Translator.php b/sources/app/Core/Translator.php index e9aa1f3..96a481f 100644 --- a/sources/app/Core/Translator.php +++ b/sources/app/Core/Translator.php @@ -1,6 +1,6 @@ projects = array(); - } - else { - + } else { $this->projects = $this->db ->table(self::TABLE) ->asc('start_date') diff --git a/sources/app/Formatter/TaskFilterAutoCompleteFormatter.php b/sources/app/Formatter/TaskFilterAutoCompleteFormatter.php index 999a894..c9af465 100644 --- a/sources/app/Formatter/TaskFilterAutoCompleteFormatter.php +++ b/sources/app/Formatter/TaskFilterAutoCompleteFormatter.php @@ -1,9 +1,9 @@ query->findAll() as $task) { - $start = new DateTime; $start->setTimestamp($task[$this->startColumn]); @@ -82,7 +81,6 @@ class TaskFilterICalendarFormatter extends TaskFilterCalendarEvent implements Fo public function addFullDayEvents() { foreach ($this->query->findAll() as $task) { - $date = new DateTime; $date->setTimestamp($task[$this->startColumn]); diff --git a/sources/app/Helper/App.php b/sources/app/Helper/App.php index 5fb89af..19801fa 100644 --- a/sources/app/Helper/App.php +++ b/sources/app/Helper/App.php @@ -1,6 +1,6 @@ '.$this->helper->e($this->session['flash_message']).''; unset($this->session['flash_message']); unset($this->session['flash_error_message']); - } - else if (isset($this->session['flash_error_message'])) { + } elseif (isset($this->session['flash_error_message'])) { $html = '
'.$this->helper->e($this->session['flash_error_message']).'
'; unset($this->session['flash_message']); unset($this->session['flash_error_message']); diff --git a/sources/app/Helper/Asset.php b/sources/app/Helper/Asset.php index fd555e0..c4178e8 100644 --- a/sources/app/Helper/Asset.php +++ b/sources/app/Helper/Asset.php @@ -1,6 +1,6 @@ '; foreach ($options as $id => $value) { - $html .= ''; } @@ -177,6 +180,23 @@ class Form extends \Core\Base return $html; } + /** + * Display file field + * + * @access public + * @param string $name + * @param array $errors + * @param boolean $multiple + * @return string + */ + public function file($name, array $errors = array(), $multiple = false) + { + $html = ''; + $html .= $this->errorList($errors, $name); + + return $html; + } + /** * Display a input field * @@ -311,7 +331,6 @@ class Form extends \Core\Base $html = ''; if (isset($errors[$name])) { - $html .= '