├── LICENCE.md ├── Makefile ├── README.md ├── centrifugo └── docker │ ├── development │ └── centrifugo │ │ └── config.json │ └── production │ ├── centrifugo.docker │ └── centrifugo │ └── config.json ├── docker-compose-production.yml ├── docker-compose.yml ├── manager ├── .dockerignore ├── .env ├── .env.test ├── .gitignore ├── assets │ ├── css │ │ ├── _chat.scss │ │ ├── _variables.scss │ │ └── app.scss │ └── js │ │ └── app.js ├── bin │ ├── console │ └── phpunit ├── composer.json ├── composer.lock ├── config │ ├── bootstrap.php │ ├── bundles.php │ ├── packages │ │ ├── assets.yaml │ │ ├── cache.yaml │ │ ├── dev │ │ │ ├── debug.yaml │ │ │ ├── easy_log_handler.yaml │ │ │ ├── monolog.yaml │ │ │ ├── routing.yaml │ │ │ ├── swiftmailer.yaml │ │ │ └── web_profiler.yaml │ │ ├── doctrine.yaml │ │ ├── doctrine_migrations.yaml │ │ ├── exercise_html_purifier.yaml │ │ ├── flysystem.yaml │ │ ├── framework.yaml │ │ ├── knp_menu.yaml │ │ ├── knp_paginator.yaml │ │ ├── knpu_oauth2_client.yaml │ │ ├── messenger.yaml │ │ ├── nyholm_psr7.yaml │ │ ├── prod │ │ │ ├── doctrine.yaml │ │ │ ├── monolog.yaml │ │ │ └── webpack_encore.yaml │ │ ├── routing.yaml │ │ ├── security.yaml │ │ ├── sensio_framework_extra.yaml │ │ ├── swiftmailer.yaml │ │ ├── test │ │ │ ├── framework.yaml │ │ │ ├── monolog.yaml │ │ │ ├── routing.yaml │ │ │ ├── security.yaml │ │ │ ├── swiftmailer.yaml │ │ │ └── web_profiler.yaml │ │ ├── translation.yaml │ │ ├── trikoder_oauth2.yaml │ │ ├── twig.yaml │ │ ├── validator.yaml │ │ └── webpack_encore.yaml │ ├── routes.yaml │ ├── routes │ │ ├── annotations.yaml │ │ └── dev │ │ │ ├── twig.yaml │ │ │ └── web_profiler.yaml │ ├── services.yaml │ ├── services_dev.yaml │ └── services_test.yaml ├── docker │ ├── development │ │ ├── nginx.docker │ │ ├── nginx │ │ │ └── default.conf │ │ ├── php-cli.docker │ │ ├── php-fpm.docker │ │ └── php │ │ │ └── xdebug.ini │ └── production │ │ ├── nginx.docker │ │ ├── nginx │ │ └── default.conf │ │ ├── php-cli.docker │ │ ├── php-fpm.docker │ │ ├── php │ │ └── default.ini │ │ ├── postgres.docker │ │ └── redis.docker ├── package.json ├── phpunit.xml.dist ├── public │ ├── docs │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── index.html │ │ ├── oauth2-redirect.html │ │ ├── openapi.json │ │ ├── swagger-ui-bundle.js │ │ ├── swagger-ui-bundle.js.map │ │ ├── swagger-ui-standalone-preset.js │ │ ├── swagger-ui-standalone-preset.js.map │ │ ├── swagger-ui.css │ │ ├── swagger-ui.css.map │ │ ├── swagger-ui.js │ │ └── swagger-ui.js.map │ ├── favicon.ico │ ├── index.php │ └── logo.png ├── src │ ├── Annotation │ │ ├── Guid.php │ │ ├── RequiresUserCredits.php │ │ └── RequiresUserCreditsSubscriber.php │ ├── Command │ │ ├── Api │ │ │ └── DocsCommand.php │ │ └── User │ │ │ ├── ConfirmCommand.php │ │ │ └── RoleCommand.php │ ├── Container │ │ └── Model │ │ │ └── User │ │ │ └── Service │ │ │ └── ResetTokenizerFactory.php │ ├── Controller │ │ ├── Api │ │ │ ├── Auth │ │ │ │ └── SignUpController.php │ │ │ ├── DomainExceptionFormatter.php │ │ │ ├── HomeController.php │ │ │ ├── PaginationSerializer.php │ │ │ ├── Profile │ │ │ │ ├── NameController.php │ │ │ │ └── ShowController.php │ │ │ └── Work │ │ │ │ └── Projects │ │ │ │ ├── ProjectsController.php │ │ │ │ └── TasksController.php │ │ ├── Auth │ │ │ ├── AuthController.php │ │ │ ├── OAuth │ │ │ │ └── FacebookController.php │ │ │ ├── ResetController.php │ │ │ └── SignUpController.php │ │ ├── ErrorHandler.php │ │ ├── HomeController.php │ │ ├── Profile │ │ │ ├── EmailController.php │ │ │ ├── NameController.php │ │ │ ├── OAuth │ │ │ │ ├── DetachController.php │ │ │ │ └── FacebookController.php │ │ │ └── ShowController.php │ │ ├── UsersController.php │ │ └── Work │ │ │ ├── HomeController.php │ │ │ ├── Members │ │ │ ├── GroupsController.php │ │ │ └── MembersController.php │ │ │ └── Projects │ │ │ ├── ActionsController.php │ │ │ ├── CalendarController.php │ │ │ ├── Project │ │ │ ├── ActionsController.php │ │ │ ├── CalendarController.php │ │ │ ├── ProjectController.php │ │ │ ├── Settings │ │ │ │ ├── DepartmentsController.php │ │ │ │ ├── MembersController.php │ │ │ │ └── SettingsController.php │ │ │ └── TasksController.php │ │ │ ├── ProjectsController.php │ │ │ ├── RolesController.php │ │ │ ├── Task │ │ │ └── CommentController.php │ │ │ └── TasksController.php │ ├── DataFixtures │ │ ├── OAuth │ │ │ └── ClientFixture.php │ │ ├── UserFixture.php │ │ └── Work │ │ │ ├── Members │ │ │ ├── GroupFixture.php │ │ │ └── MemberFixture.php │ │ │ └── Projects │ │ │ ├── ProjectFixture.php │ │ │ ├── RoleFixture.php │ │ │ └── TaskFixture.php │ ├── Event │ │ ├── Dispatcher │ │ │ ├── Message │ │ │ │ ├── Handler.php │ │ │ │ └── Message.php │ │ │ └── MessengerEventDispatcher.php │ │ └── Listener │ │ │ └── Work │ │ │ └── Projects │ │ │ └── Task │ │ │ ├── EmailNotificationSubscriber.php │ │ │ └── FileRemoveSubscriber.php │ ├── Kernel.php │ ├── Menu │ │ ├── SidebarMenu.php │ │ └── Work │ │ │ ├── MainMenu.php │ │ │ └── Projects │ │ │ ├── ProjectMenu.php │ │ │ ├── SettingsMenu.php │ │ │ └── TaskPresetMenu.php │ ├── Migrations │ │ ├── Version20190413104318.php │ │ ├── Version20190426140032.php │ │ ├── Version20190426150151.php │ │ ├── Version20190504151832.php │ │ ├── Version20190504152056.php │ │ ├── Version20190525090851.php │ │ ├── Version20190525103125.php │ │ ├── Version20190525111320.php │ │ ├── Version20190525120929.php │ │ ├── Version20190601133927.php │ │ ├── Version20190601134140.php │ │ ├── Version20190614152818.php │ │ ├── Version20190615142504.php │ │ ├── Version20190622114352.php │ │ ├── Version20190629104355.php │ │ ├── Version20190809064507.php │ │ └── Version20190810064712.php │ ├── Model │ │ ├── AggregateRoot.php │ │ ├── Comment │ │ │ ├── Entity │ │ │ │ └── Comment │ │ │ │ │ ├── AuthorId.php │ │ │ │ │ ├── AuthorIdType.php │ │ │ │ │ ├── Comment.php │ │ │ │ │ ├── CommentRepository.php │ │ │ │ │ ├── Entity.php │ │ │ │ │ ├── Id.php │ │ │ │ │ └── IdType.php │ │ │ └── UseCase │ │ │ │ └── Comment │ │ │ │ ├── Create │ │ │ │ ├── Command.php │ │ │ │ ├── Form.php │ │ │ │ └── Handler.php │ │ │ │ ├── Edit │ │ │ │ ├── Command.php │ │ │ │ ├── Form.php │ │ │ │ └── Handler.php │ │ │ │ └── Remove │ │ │ │ ├── Command.php │ │ │ │ └── Handler.php │ │ ├── EntityNotFoundException.php │ │ ├── EventDispatcher.php │ │ ├── EventsTrait.php │ │ ├── Flusher.php │ │ ├── User │ │ │ ├── Entity │ │ │ │ └── User │ │ │ │ │ ├── Email.php │ │ │ │ │ ├── EmailType.php │ │ │ │ │ ├── Id.php │ │ │ │ │ ├── IdType.php │ │ │ │ │ ├── Name.php │ │ │ │ │ ├── Network.php │ │ │ │ │ ├── ResetToken.php │ │ │ │ │ ├── Role.php │ │ │ │ │ ├── RoleType.php │ │ │ │ │ ├── User.php │ │ │ │ │ └── UserRepository.php │ │ │ ├── Service │ │ │ │ ├── NewEmailConfirmTokenSender.php │ │ │ │ ├── NewEmailConfirmTokenizer.php │ │ │ │ ├── PasswordGenerator.php │ │ │ │ ├── PasswordHasher.php │ │ │ │ ├── ResetTokenSender.php │ │ │ │ ├── ResetTokenizer.php │ │ │ │ ├── SignUpConfirmTokenSender.php │ │ │ │ └── SignUpConfirmTokenizer.php │ │ │ └── UseCase │ │ │ │ ├── Activate │ │ │ │ ├── Command.php │ │ │ │ └── Handler.php │ │ │ │ ├── Block │ │ │ │ ├── Command.php │ │ │ │ └── Handler.php │ │ │ │ ├── Create │ │ │ │ ├── Command.php │ │ │ │ ├── Form.php │ │ │ │ └── Handler.php │ │ │ │ ├── Edit │ │ │ │ ├── Command.php │ │ │ │ ├── Form.php │ │ │ │ └── Handler.php │ │ │ │ ├── Email │ │ │ │ ├── Confirm │ │ │ │ │ ├── Command.php │ │ │ │ │ └── Handler.php │ │ │ │ └── Request │ │ │ │ │ ├── Command.php │ │ │ │ │ ├── Form.php │ │ │ │ │ └── Handler.php │ │ │ │ ├── Name │ │ │ │ ├── Command.php │ │ │ │ ├── Form.php │ │ │ │ └── Handler.php │ │ │ │ ├── Network │ │ │ │ ├── Attach │ │ │ │ │ ├── Command.php │ │ │ │ │ └── Handler.php │ │ │ │ ├── Auth │ │ │ │ │ ├── Command.php │ │ │ │ │ └── Handler.php │ │ │ │ └── Detach │ │ │ │ │ ├── Command.php │ │ │ │ │ └── Handler.php │ │ │ │ ├── Reset │ │ │ │ ├── Request │ │ │ │ │ ├── Command.php │ │ │ │ │ ├── Form.php │ │ │ │ │ └── Handler.php │ │ │ │ └── Reset │ │ │ │ │ ├── Command.php │ │ │ │ │ ├── Form.php │ │ │ │ │ └── Handler.php │ │ │ │ ├── Role │ │ │ │ ├── Command.php │ │ │ │ ├── Form.php │ │ │ │ └── Handler.php │ │ │ │ └── SignUp │ │ │ │ ├── Confirm │ │ │ │ ├── ByToken │ │ │ │ │ ├── Command.php │ │ │ │ │ └── Handler.php │ │ │ │ └── Manual │ │ │ │ │ ├── Command.php │ │ │ │ │ └── Handler.php │ │ │ │ └── Request │ │ │ │ ├── Command.php │ │ │ │ ├── Form.php │ │ │ │ └── Handler.php │ │ └── Work │ │ │ ├── Entity │ │ │ ├── Members │ │ │ │ ├── Group │ │ │ │ │ ├── Group.php │ │ │ │ │ ├── GroupRepository.php │ │ │ │ │ ├── Id.php │ │ │ │ │ └── IdType.php │ │ │ │ └── Member │ │ │ │ │ ├── Email.php │ │ │ │ │ ├── EmailType.php │ │ │ │ │ ├── Id.php │ │ │ │ │ ├── IdType.php │ │ │ │ │ ├── Member.php │ │ │ │ │ ├── MemberRepository.php │ │ │ │ │ ├── Name.php │ │ │ │ │ ├── Status.php │ │ │ │ │ └── StatusType.php │ │ │ └── Projects │ │ │ │ ├── Project │ │ │ │ ├── Department │ │ │ │ │ ├── Department.php │ │ │ │ │ ├── Id.php │ │ │ │ │ └── IdType.php │ │ │ │ ├── Id.php │ │ │ │ ├── IdType.php │ │ │ │ ├── Membership.php │ │ │ │ ├── Project.php │ │ │ │ ├── ProjectRepository.php │ │ │ │ ├── Status.php │ │ │ │ └── StatusType.php │ │ │ │ ├── Role │ │ │ │ ├── Id.php │ │ │ │ ├── IdType.php │ │ │ │ ├── Permission.php │ │ │ │ ├── PermissionsType.php │ │ │ │ ├── Role.php │ │ │ │ └── RoleRepository.php │ │ │ │ └── Task │ │ │ │ ├── Change │ │ │ │ ├── Change.php │ │ │ │ ├── Id.php │ │ │ │ ├── IdType.php │ │ │ │ └── Set.php │ │ │ │ ├── Event │ │ │ │ ├── TaskEdited.php │ │ │ │ ├── TaskExecutorAssigned.php │ │ │ │ ├── TaskExecutorRevoked.php │ │ │ │ ├── TaskFileAdded.php │ │ │ │ ├── TaskFileRemoved.php │ │ │ │ ├── TaskPlanChanged.php │ │ │ │ ├── TaskPriorityChanged.php │ │ │ │ ├── TaskProgressChanged.php │ │ │ │ ├── TaskStatusChanged.php │ │ │ │ └── TaskTypeChanged.php │ │ │ │ ├── File │ │ │ │ ├── File.php │ │ │ │ ├── Id.php │ │ │ │ ├── IdType.php │ │ │ │ └── Info.php │ │ │ │ ├── Id.php │ │ │ │ ├── IdType.php │ │ │ │ ├── Status.php │ │ │ │ ├── StatusType.php │ │ │ │ ├── Task.php │ │ │ │ ├── TaskRepository.php │ │ │ │ ├── Type.php │ │ │ │ └── TypeType.php │ │ │ └── UseCase │ │ │ ├── Members │ │ │ ├── Group │ │ │ │ ├── Create │ │ │ │ │ ├── Command.php │ │ │ │ │ ├── Form.php │ │ │ │ │ └── Handler.php │ │ │ │ ├── Edit │ │ │ │ │ ├── Command.php │ │ │ │ │ ├── Form.php │ │ │ │ │ └── Handler.php │ │ │ │ └── Remove │ │ │ │ │ ├── Command.php │ │ │ │ │ └── Handler.php │ │ │ └── Member │ │ │ │ ├── Archive │ │ │ │ ├── Command.php │ │ │ │ └── Handler.php │ │ │ │ ├── Create │ │ │ │ ├── Command.php │ │ │ │ ├── Form.php │ │ │ │ └── Handler.php │ │ │ │ ├── Edit │ │ │ │ ├── Command.php │ │ │ │ ├── Form.php │ │ │ │ └── Handler.php │ │ │ │ ├── Move │ │ │ │ ├── Command.php │ │ │ │ ├── Form.php │ │ │ │ └── Handler.php │ │ │ │ └── Reinstate │ │ │ │ ├── Command.php │ │ │ │ └── Handler.php │ │ │ └── Projects │ │ │ ├── Project │ │ │ ├── Archive │ │ │ │ ├── Command.php │ │ │ │ └── Handler.php │ │ │ ├── Create │ │ │ │ ├── Command.php │ │ │ │ ├── Form.php │ │ │ │ └── Handler.php │ │ │ ├── Department │ │ │ │ ├── Create │ │ │ │ │ ├── Command.php │ │ │ │ │ ├── Form.php │ │ │ │ │ └── Handler.php │ │ │ │ ├── Edit │ │ │ │ │ ├── Command.php │ │ │ │ │ ├── Form.php │ │ │ │ │ └── Handler.php │ │ │ │ └── Remove │ │ │ │ │ ├── Command.php │ │ │ │ │ └── Handler.php │ │ │ ├── Edit │ │ │ │ ├── Command.php │ │ │ │ ├── Form.php │ │ │ │ └── Handler.php │ │ │ ├── Membership │ │ │ │ ├── Add │ │ │ │ │ ├── Command.php │ │ │ │ │ ├── Form.php │ │ │ │ │ └── Handler.php │ │ │ │ ├── Edit │ │ │ │ │ ├── Command.php │ │ │ │ │ ├── Form.php │ │ │ │ │ └── Handler.php │ │ │ │ └── Remove │ │ │ │ │ ├── Command.php │ │ │ │ │ └── Handler.php │ │ │ ├── Reinstate │ │ │ │ ├── Command.php │ │ │ │ └── Handler.php │ │ │ └── Remove │ │ │ │ ├── Command.php │ │ │ │ └── Handler.php │ │ │ ├── Role │ │ │ ├── Copy │ │ │ │ ├── Command.php │ │ │ │ ├── Form.php │ │ │ │ └── Handler.php │ │ │ ├── Create │ │ │ │ ├── Command.php │ │ │ │ ├── Form.php │ │ │ │ └── Handler.php │ │ │ ├── Edit │ │ │ │ ├── Command.php │ │ │ │ ├── Form.php │ │ │ │ └── Handler.php │ │ │ └── Remove │ │ │ │ ├── Command.php │ │ │ │ └── Handler.php │ │ │ └── Task │ │ │ ├── ChildOf │ │ │ ├── Command.php │ │ │ ├── Form.php │ │ │ └── Handler.php │ │ │ ├── Create │ │ │ ├── Command.php │ │ │ ├── Form.php │ │ │ ├── Handler.php │ │ │ ├── NameRow.php │ │ │ └── NamesType.php │ │ │ ├── Edit │ │ │ ├── Command.php │ │ │ ├── Form.php │ │ │ └── Handler.php │ │ │ ├── Executor │ │ │ ├── Assign │ │ │ │ ├── Command.php │ │ │ │ ├── Form.php │ │ │ │ └── Handler.php │ │ │ └── Revoke │ │ │ │ ├── Command.php │ │ │ │ └── Handler.php │ │ │ ├── Files │ │ │ ├── Add │ │ │ │ ├── Command.php │ │ │ │ ├── File.php │ │ │ │ ├── Form.php │ │ │ │ └── Handler.php │ │ │ └── Remove │ │ │ │ ├── Command.php │ │ │ │ └── Handler.php │ │ │ ├── Move │ │ │ ├── Command.php │ │ │ ├── Form.php │ │ │ └── Handler.php │ │ │ ├── Plan │ │ │ ├── Remove │ │ │ │ ├── Command.php │ │ │ │ └── Handler.php │ │ │ └── Set │ │ │ │ ├── Command.php │ │ │ │ ├── Form.php │ │ │ │ └── Handler.php │ │ │ ├── Priority │ │ │ ├── Command.php │ │ │ ├── Form.php │ │ │ └── Handler.php │ │ │ ├── Progress │ │ │ ├── Command.php │ │ │ ├── Form.php │ │ │ └── Handler.php │ │ │ ├── Remove │ │ │ ├── Command.php │ │ │ └── Handler.php │ │ │ ├── Start │ │ │ ├── Command.php │ │ │ └── Handler.php │ │ │ ├── Status │ │ │ ├── Command.php │ │ │ ├── Form.php │ │ │ └── Handler.php │ │ │ ├── Take │ │ │ ├── Command.php │ │ │ └── Handler.php │ │ │ ├── TakeAndStart │ │ │ ├── Command.php │ │ │ └── Handler.php │ │ │ └── Type │ │ │ ├── Command.php │ │ │ ├── Form.php │ │ │ └── Handler.php │ ├── ReadModel │ │ ├── Comment │ │ │ └── CommentRow.php │ │ ├── NotFoundException.php │ │ ├── User │ │ │ ├── AuthView.php │ │ │ ├── Filter │ │ │ │ ├── Filter.php │ │ │ │ └── Form.php │ │ │ ├── ShortView.php │ │ │ └── UserFetcher.php │ │ └── Work │ │ │ ├── Members │ │ │ ├── GroupFetcher.php │ │ │ └── Member │ │ │ │ ├── Filter │ │ │ │ ├── Filter.php │ │ │ │ └── Form.php │ │ │ │ └── MemberFetcher.php │ │ │ └── Projects │ │ │ ├── Action │ │ │ ├── ActionFetcher.php │ │ │ ├── Feed │ │ │ │ ├── Feed.php │ │ │ │ └── Item.php │ │ │ └── Filter.php │ │ │ ├── Calendar │ │ │ ├── CalendarFetcher.php │ │ │ ├── Query │ │ │ │ ├── Form.php │ │ │ │ └── Query.php │ │ │ └── Result.php │ │ │ ├── Project │ │ │ ├── DepartmentFetcher.php │ │ │ ├── Filter │ │ │ │ ├── Filter.php │ │ │ │ └── Form.php │ │ │ └── ProjectFetcher.php │ │ │ ├── RoleFetcher.php │ │ │ └── Task │ │ │ ├── CommentFetcher.php │ │ │ ├── Filter │ │ │ ├── Filter.php │ │ │ └── Form.php │ │ │ └── TaskFetcher.php │ ├── Security │ │ ├── LoginFormAuthenticator.php │ │ ├── OAuth │ │ │ ├── FacebookAuthenticator.php │ │ │ └── Server │ │ │ │ ├── RequestResolver.php │ │ │ │ └── UserResolver.php │ │ ├── UserChecker.php │ │ ├── UserIdentity.php │ │ ├── UserProvider.php │ │ └── Voter │ │ │ ├── Comment │ │ │ └── CommentAccess.php │ │ │ └── Work │ │ │ └── Projects │ │ │ ├── ProjectAccess.php │ │ │ └── TaskAccess.php │ ├── Service │ │ ├── Gravatar.php │ │ ├── Uploader │ │ │ ├── File.php │ │ │ └── FileUploader.php │ │ └── Work │ │ │ └── Processor │ │ │ ├── Driver │ │ │ ├── Driver.php │ │ │ ├── MemberDriver.php │ │ │ └── TaskDriver.php │ │ │ └── Processor.php │ ├── Twig │ │ └── Extension │ │ │ ├── CentrifugoExtension.php │ │ │ ├── GravatarExtension.php │ │ │ ├── MarkdownExtension.php │ │ │ ├── StoragePathExtension.php │ │ │ └── Work │ │ │ └── ProcessorExtension.php │ └── Widget │ │ ├── User │ │ ├── RoleWidget.php │ │ └── StatusWidget.php │ │ └── Work │ │ ├── Members │ │ └── Member │ │ │ └── StatusWidget.php │ │ └── Projects │ │ ├── ActionRowWidget.php │ │ ├── CalendarWidget.php │ │ ├── OwnTasksWidget.php │ │ ├── Project │ │ └── StatusWidget.php │ │ ├── Task │ │ ├── PriorityWidget.php │ │ ├── ProgressWidget.php │ │ ├── StatusWidget.php │ │ └── TypeWidget.php │ │ └── TasksForMeWidget.php ├── symfony.lock ├── templates │ ├── _flashes.html.twig │ ├── app │ │ ├── auth │ │ │ ├── login.html.twig │ │ │ ├── reset │ │ │ │ ├── request.html.twig │ │ │ │ └── reset.html.twig │ │ │ └── signup.html.twig │ │ ├── home.html.twig │ │ ├── profile │ │ │ ├── email.html.twig │ │ │ ├── name.html.twig │ │ │ └── show.html.twig │ │ ├── users │ │ │ ├── create.html.twig │ │ │ ├── edit.html.twig │ │ │ ├── index.html.twig │ │ │ ├── role.html.twig │ │ │ └── show.html.twig │ │ └── work │ │ │ ├── _tabs.html.twig │ │ │ ├── members │ │ │ ├── _tabs.html.twig │ │ │ ├── create.html.twig │ │ │ ├── edit.html.twig │ │ │ ├── groups │ │ │ │ ├── _tabs.html.twig │ │ │ │ ├── create.html.twig │ │ │ │ ├── edit.html.twig │ │ │ │ └── index.html.twig │ │ │ ├── index.html.twig │ │ │ ├── move.html.twig │ │ │ └── show.html.twig │ │ │ └── projects │ │ │ ├── actions.html.twig │ │ │ ├── calendar.html.twig │ │ │ ├── create.html.twig │ │ │ ├── index.html.twig │ │ │ ├── project │ │ │ ├── _tabs.html.twig │ │ │ ├── settings │ │ │ │ ├── _tabs.html.twig │ │ │ │ ├── departments │ │ │ │ │ ├── create.html.twig │ │ │ │ │ ├── edit.html.twig │ │ │ │ │ └── index.html.twig │ │ │ │ ├── edit.html.twig │ │ │ │ ├── members │ │ │ │ │ ├── assign.html.twig │ │ │ │ │ ├── edit.html.twig │ │ │ │ │ └── index.html.twig │ │ │ │ └── show.html.twig │ │ │ ├── show.html.twig │ │ │ └── tasks │ │ │ │ └── create.html.twig │ │ │ ├── roles │ │ │ ├── copy.html.twig │ │ │ ├── create.html.twig │ │ │ ├── edit.html.twig │ │ │ ├── index.html.twig │ │ │ └── show.html.twig │ │ │ └── tasks │ │ │ ├── _presets.html.twig │ │ │ ├── assign.html.twig │ │ │ ├── child.html.twig │ │ │ ├── comment.html.twig │ │ │ ├── comment │ │ │ └── edit.html.twig │ │ │ ├── create.html.twig │ │ │ ├── edit.html.twig │ │ │ ├── files.html.twig │ │ │ ├── index.html.twig │ │ │ ├── move.html.twig │ │ │ ├── plan.html.twig │ │ │ └── show.html.twig │ ├── auth.html.twig │ ├── base.html.twig │ ├── mail.html.twig │ ├── mail │ │ ├── user │ │ │ ├── email.html.twig │ │ │ ├── reset.html.twig │ │ │ └── signup.html.twig │ │ └── work │ │ │ └── projects │ │ │ └── task │ │ │ ├── executor-assigned-author.html.twig │ │ │ └── executor-assigned-executor.html.twig │ ├── override │ │ ├── menu.html.twig │ │ └── sortable_link.html.twig │ ├── processor │ │ └── work │ │ │ ├── member.html.twig │ │ │ └── task.html.twig │ └── widget │ │ ├── user │ │ ├── role.html.twig │ │ └── status.html.twig │ │ └── work │ │ ├── members │ │ └── member │ │ │ └── status.html.twig │ │ └── projects │ │ ├── action-row.html.twig │ │ ├── calendar.html.twig │ │ ├── own-tasks.html.twig │ │ ├── project │ │ └── status.html.twig │ │ ├── task │ │ ├── priority.html.twig │ │ ├── progress.html.twig │ │ ├── status.html.twig │ │ └── type.html.twig │ │ └── tasks-for-me.html.twig ├── tests │ ├── Builder │ │ ├── User │ │ │ └── UserBuilder.php │ │ └── Work │ │ │ ├── Members │ │ │ ├── GroupBuilder.php │ │ │ └── MemberBuilder.php │ │ │ └── Projects │ │ │ ├── ProjectBuilder.php │ │ │ ├── RoleBuilder.php │ │ │ └── TaskBuilder.php │ ├── Functional │ │ ├── Api │ │ │ ├── Auth │ │ │ │ └── SignUpTest.php │ │ │ ├── ClientFixture.php │ │ │ ├── HomeTest.php │ │ │ ├── Profile │ │ │ │ ├── NameTest.php │ │ │ │ ├── ProfileFixture.php │ │ │ │ └── ShowTest.php │ │ │ └── Work │ │ │ │ ├── MemberFixture.php │ │ │ │ ├── Projects │ │ │ │ ├── IndexFixture.php │ │ │ │ └── IndexTest.php │ │ │ │ └── Tasks │ │ │ │ ├── PlanTest.php │ │ │ │ ├── RemovePlanTest.php │ │ │ │ ├── ShowTest.php │ │ │ │ └── TaskFixture.php │ │ ├── AuthFixture.php │ │ ├── DbWebTestCase.php │ │ ├── HomeTest.php │ │ ├── OAuth │ │ │ ├── OAuthFixture.php │ │ │ └── PasswordTest.php │ │ └── Users │ │ │ ├── CreateTest.php │ │ │ ├── IndexTest.php │ │ │ ├── ShowTest.php │ │ │ └── UsersFixture.php │ ├── Unit │ │ └── Model │ │ │ ├── User │ │ │ └── Entity │ │ │ │ └── User │ │ │ │ ├── ActivateTest.php │ │ │ │ ├── BlockTest.php │ │ │ │ ├── Email │ │ │ │ ├── ConfirmTest.php │ │ │ │ └── RequestTest.php │ │ │ │ ├── Network │ │ │ │ └── AuthTest.php │ │ │ │ ├── Reset │ │ │ │ ├── RequestTest.php │ │ │ │ └── ResetTest.php │ │ │ │ ├── RoleTest.php │ │ │ │ └── SignUp │ │ │ │ ├── ConfirmTest.php │ │ │ │ └── RequestTest.php │ │ │ └── Work │ │ │ └── Entity │ │ │ └── Projects │ │ │ └── Task │ │ │ ├── ChangePriorityTest.php │ │ │ ├── ChangeProgressTest.php │ │ │ ├── ChangeStatusTest.php │ │ │ ├── ChangeTypeTest.php │ │ │ ├── CreateTest.php │ │ │ ├── EditTest.php │ │ │ ├── Executor │ │ │ ├── AssignTest.php │ │ │ └── RevokeTest.php │ │ │ ├── File │ │ │ └── AddTest.php │ │ │ ├── MoveTest.php │ │ │ ├── PlanTest.php │ │ │ ├── RemovePlanTest.php │ │ │ ├── SetChildOfTest.php │ │ │ ├── SetRootTest.php │ │ │ └── StartTest.php │ └── data │ │ └── oauth │ │ ├── private.key │ │ └── public.key ├── translations │ └── work_permissions.en.php ├── webpack.config.js └── yarn.lock └── storage ├── docker └── development │ ├── nginx.docker │ └── nginx │ └── default.conf └── public └── .gitignore /README.md: -------------------------------------------------------------------------------- 1 | Demo project for Symfony master-class https://elisdn.ru/project-manager 2 | -------------------------------------------------------------------------------- /centrifugo/docker/development/centrifugo/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "secret": "", 3 | "api_key": "", 4 | "namespaces": [ 5 | { 6 | "name": "alerts", 7 | "publish": false, 8 | "watch": true, 9 | "anonymous": false, 10 | "presence": true, 11 | "join_leave": true, 12 | "recover": false, 13 | "history_size": 10, 14 | "history_lifetime": 30 15 | } 16 | ] 17 | } -------------------------------------------------------------------------------- /centrifugo/docker/production/centrifugo.docker: -------------------------------------------------------------------------------- 1 | FROM centrifugo/centrifugo:v2.2 2 | 3 | COPY ./docker/production/centrifugo/config.json /centrifugo/config.json -------------------------------------------------------------------------------- /centrifugo/docker/production/centrifugo/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "secret": "", 3 | "api_key": "", 4 | "namespaces": [ 5 | { 6 | "name": "alerts", 7 | "publish": false, 8 | "watch": false, 9 | "anonymous": false, 10 | "presence": true, 11 | "join_leave": true, 12 | "recover": false, 13 | "history_size": 10, 14 | "history_lifetime": 30 15 | } 16 | ] 17 | } -------------------------------------------------------------------------------- /manager/.dockerignore: -------------------------------------------------------------------------------- 1 | /.ready 2 | 3 | ###> symfony/framework-bundle ### 4 | /.env.local 5 | /.env.local.php 6 | /.env.*.local 7 | /public/bundles/ 8 | /var/ 9 | /vendor/ 10 | ###< symfony/framework-bundle ### 11 | 12 | ###> symfony/phpunit-bridge ### 13 | /bin/.phpunit 14 | /phpunit.xml 15 | ###< symfony/phpunit-bridge ### 16 | 17 | ###> symfony/webpack-encore-bundle ### 18 | /node_modules/ 19 | /public/build/ 20 | npm-debug.log 21 | yarn-error.log 22 | ###< symfony/webpack-encore-bundle ### -------------------------------------------------------------------------------- /manager/.env.test: -------------------------------------------------------------------------------- 1 | # define your env variables for the test env here 2 | KERNEL_CLASS='App\Kernel' 3 | APP_SECRET='s$cretf0rt3st' 4 | SYMFONY_DEPRECATIONS_HELPER=999999 5 | 6 | OAUTH_PRIVATE_KEY=/app/tests/data/oauth/private.key 7 | OAUTH_PUBLIC_KEY=/app/tests/data/oauth/public.key -------------------------------------------------------------------------------- /manager/.gitignore: -------------------------------------------------------------------------------- 1 | /.ready 2 | 3 | ###> symfony/framework-bundle ### 4 | /.env.local 5 | /.env.local.php 6 | /.env.*.local 7 | /public/bundles/ 8 | /var/ 9 | /vendor/ 10 | ###< symfony/framework-bundle ### 11 | 12 | ###> symfony/phpunit-bridge ### 13 | .phpunit 14 | /phpunit.xml 15 | ###< symfony/phpunit-bridge ### 16 | 17 | ###> symfony/webpack-encore-bundle ### 18 | /node_modules/ 19 | /public/build/ 20 | npm-debug.log 21 | yarn-error.log 22 | ###< symfony/webpack-encore-bundle ### 23 | -------------------------------------------------------------------------------- /manager/assets/css/_variables.scss: -------------------------------------------------------------------------------- 1 | $body-bg: #f6f6f6; 2 | $font-size-base: .85rem; 3 | 4 | $breadcrumb-margin-bottom: 20px; 5 | 6 | $table-border-color: #e6e6e6; 7 | $table-cell-padding: 0.55rem; 8 | 9 | $card-border-color: #e6e6e6; 10 | $card-spacer-x: .7rem; 11 | $card-spacer-y: .6rem; -------------------------------------------------------------------------------- /manager/assets/js/app.js: -------------------------------------------------------------------------------- 1 | require('../css/app.scss'); 2 | 3 | require('bootstrap'); 4 | require('@coreui/coreui'); 5 | 6 | const Centrifuge = require('centrifuge'); 7 | const toastr = require('toastr'); 8 | 9 | document.addEventListener('DOMContentLoaded', function () { 10 | let url = document.querySelector('meta[name=centrifugo-url]').getAttribute('content'); 11 | let user = document.querySelector('meta[name=centrifugo-user]').getAttribute('content'); 12 | let token = document.querySelector('meta[name=centrifugo-token]').getAttribute('content'); 13 | let centrifuge = new Centrifuge(url); 14 | centrifuge.setToken(token); 15 | centrifuge.subscribe('alerts#' + user, function (message) { 16 | toastr.info(message.data.message); 17 | }); 18 | centrifuge.connect(); 19 | }); -------------------------------------------------------------------------------- /manager/bin/phpunit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | handle($request); 26 | $response->send(); 27 | $kernel->terminate($request, $response); 28 | -------------------------------------------------------------------------------- /manager/public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ElisDN/demo-project-manager/fe20d6880610c0271e31940d772191969e16f7c7/manager/public/logo.png -------------------------------------------------------------------------------- /manager/src/Annotation/Guid.php: -------------------------------------------------------------------------------- 1 | $pagination->count(), 15 | 'total' => $pagination->getTotalItemCount(), 16 | 'per_page' => $pagination->getItemNumberPerPage(), 17 | 'page' => $pagination->getCurrentPageNumber(), 18 | 'pages' => ceil($pagination->getTotalItemCount() / $pagination->getItemNumberPerPage()), 19 | ]; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /manager/src/Controller/ErrorHandler.php: -------------------------------------------------------------------------------- 1 | logger = $logger; 16 | } 17 | 18 | public function handle(\DomainException $e): void 19 | { 20 | $this->logger->warning($e->getMessage(), ['exception' => $e]); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /manager/src/Controller/HomeController.php: -------------------------------------------------------------------------------- 1 | render('app/home.html.twig'); 24 | } 25 | } -------------------------------------------------------------------------------- /manager/src/Controller/Profile/ShowController.php: -------------------------------------------------------------------------------- 1 | users = $users; 19 | } 20 | 21 | /** 22 | * @Route("/profile", name="profile") 23 | * @return Response 24 | */ 25 | public function show(): Response 26 | { 27 | $user = $this->users->get($this->getUser()->getId()); 28 | 29 | return $this->render('app/profile/show.html.twig', compact('user')); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /manager/src/Controller/Work/HomeController.php: -------------------------------------------------------------------------------- 1 | redirectToRoute('work.projects'); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /manager/src/Event/Dispatcher/Message/Handler.php: -------------------------------------------------------------------------------- 1 | dispatcher = $dispatcher; 17 | } 18 | 19 | public function __invoke(Message $message) 20 | { 21 | $this->dispatcher->dispatch($message->getEvent()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /manager/src/Event/Dispatcher/Message/Message.php: -------------------------------------------------------------------------------- 1 | event = $event; 14 | } 15 | 16 | public function getEvent(): object 17 | { 18 | return $this->event; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /manager/src/Event/Dispatcher/MessengerEventDispatcher.php: -------------------------------------------------------------------------------- 1 | bus = $bus; 18 | } 19 | 20 | public function dispatch(array $events): void 21 | { 22 | foreach ($events as $event) { 23 | $this->bus->dispatch(new Message($event)); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /manager/src/Event/Listener/Work/Projects/Task/FileRemoveSubscriber.php: -------------------------------------------------------------------------------- 1 | uploader = $uploader; 18 | } 19 | 20 | public static function getSubscribedEvents(): array 21 | { 22 | return [ 23 | TaskFileRemoved::class => 'onTaskFileRemoved', 24 | ]; 25 | } 26 | 27 | public function onTaskFileRemoved(TaskFileRemoved $event): void 28 | { 29 | $this->uploader->remove($event->info->getPath(), $event->info->getName()); 30 | } 31 | } -------------------------------------------------------------------------------- /manager/src/Model/AggregateRoot.php: -------------------------------------------------------------------------------- 1 | value = $value; 17 | } 18 | 19 | public function getValue(): string 20 | { 21 | return $this->value; 22 | } 23 | 24 | public function isEqualTo(self $id): bool 25 | { 26 | return $this->getValue() === $id->getValue(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /manager/src/Model/Comment/Entity/Comment/AuthorIdType.php: -------------------------------------------------------------------------------- 1 | getValue() : $value; 17 | } 18 | 19 | public function convertToPHPValue($value, AbstractPlatform $platform) 20 | { 21 | return !empty($value) ? new AuthorId($value) : null; 22 | } 23 | 24 | public function getName(): string 25 | { 26 | return self::NAME; 27 | } 28 | 29 | public function requiresSQLCommentHint(AbstractPlatform $platform) : bool 30 | { 31 | return true; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /manager/src/Model/Comment/Entity/Comment/Entity.php: -------------------------------------------------------------------------------- 1 | type = $type; 32 | $this->id = $id; 33 | } 34 | 35 | public function getType(): string 36 | { 37 | return $this->type; 38 | } 39 | 40 | public function getId(): string 41 | { 42 | return $this->id; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /manager/src/Model/Comment/Entity/Comment/Id.php: -------------------------------------------------------------------------------- 1 | value = $value; 18 | } 19 | 20 | public static function next(): self 21 | { 22 | return new self(Uuid::uuid4()->toString()); 23 | } 24 | 25 | public function getValue(): string 26 | { 27 | return $this->value; 28 | } 29 | 30 | public function __toString(): string 31 | { 32 | return $this->value; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /manager/src/Model/Comment/Entity/Comment/IdType.php: -------------------------------------------------------------------------------- 1 | getValue() : $value; 17 | } 18 | 19 | public function convertToPHPValue($value, AbstractPlatform $platform) 20 | { 21 | return !empty($value) ? new Id($value) : null; 22 | } 23 | 24 | public function getName(): string 25 | { 26 | return self::NAME; 27 | } 28 | 29 | public function requiresSQLCommentHint(AbstractPlatform $platform) : bool 30 | { 31 | return true; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /manager/src/Model/Comment/UseCase/Comment/Create/Command.php: -------------------------------------------------------------------------------- 1 | author = $author; 35 | $this->entityType = $type; 36 | $this->entityId = $id; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /manager/src/Model/Comment/UseCase/Comment/Create/Form.php: -------------------------------------------------------------------------------- 1 | add('text', Type\TextareaType::class, ['label' => 'Comment', 'attr' => ['rows' => 6]]); 18 | } 19 | 20 | public function configureOptions(OptionsResolver $resolver): void 21 | { 22 | $resolver->setDefaults(array( 23 | 'data_class' => Command::class, 24 | )); 25 | } 26 | 27 | public function getBlockPrefix(): string 28 | { 29 | return 'comment'; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /manager/src/Model/Comment/UseCase/Comment/Edit/Command.php: -------------------------------------------------------------------------------- 1 | id = $id; 26 | } 27 | 28 | public static function fromComment(Comment $comment): self 29 | { 30 | $command = new self($comment->getId()->getValue()); 31 | $command->text = $comment->getText(); 32 | return $command; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /manager/src/Model/Comment/UseCase/Comment/Edit/Form.php: -------------------------------------------------------------------------------- 1 | add('text', Type\TextareaType::class, ['label' => 'Comment', 'attr' => ['rows' => 6]]); 18 | } 19 | 20 | public function configureOptions(OptionsResolver $resolver): void 21 | { 22 | $resolver->setDefaults(array( 23 | 'data_class' => Command::class, 24 | )); 25 | } 26 | 27 | public function getBlockPrefix(): string 28 | { 29 | return 'comment'; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /manager/src/Model/Comment/UseCase/Comment/Edit/Handler.php: -------------------------------------------------------------------------------- 1 | comments = $comments; 19 | $this->flusher = $flusher; 20 | } 21 | 22 | public function handle(Command $command): void 23 | { 24 | $comment = $this->comments->get(new Id($command->id)); 25 | 26 | $comment->edit( 27 | new \DateTimeImmutable(), 28 | $command->text 29 | ); 30 | 31 | $this->flusher->flush(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /manager/src/Model/Comment/UseCase/Comment/Remove/Command.php: -------------------------------------------------------------------------------- 1 | id = $id; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /manager/src/Model/Comment/UseCase/Comment/Remove/Handler.php: -------------------------------------------------------------------------------- 1 | comments = $comments; 19 | $this->flusher = $flusher; 20 | } 21 | 22 | public function handle(Command $command): void 23 | { 24 | $comment = $this->comments->get(new Id($command->id)); 25 | 26 | $this->comments->remove($comment); 27 | 28 | $this->flusher->flush(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /manager/src/Model/EntityNotFoundException.php: -------------------------------------------------------------------------------- 1 | recordedEvents[] = $event; 14 | } 15 | 16 | public function releaseEvents(): array 17 | { 18 | $events = $this->recordedEvents; 19 | $this->recordedEvents = []; 20 | return $events; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /manager/src/Model/Flusher.php: -------------------------------------------------------------------------------- 1 | em = $em; 17 | $this->dispatcher = $dispatcher; 18 | } 19 | 20 | public function flush(AggregateRoot ...$roots): void 21 | { 22 | $this->em->flush(); 23 | 24 | foreach ($roots as $root) { 25 | $this->dispatcher->dispatch($root->releaseEvents()); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /manager/src/Model/User/Entity/User/Email.php: -------------------------------------------------------------------------------- 1 | value = mb_strtolower($value); 20 | } 21 | 22 | public function getValue(): string 23 | { 24 | return $this->value; 25 | } 26 | 27 | public function isEqual(self $other): bool 28 | { 29 | return $this->getValue() === $other->getValue(); 30 | } 31 | } -------------------------------------------------------------------------------- /manager/src/Model/User/Entity/User/EmailType.php: -------------------------------------------------------------------------------- 1 | getValue() : $value; 17 | } 18 | 19 | public function convertToPHPValue($value, AbstractPlatform $platform) 20 | { 21 | return !empty($value) ? new Email($value) : null; 22 | } 23 | 24 | public function getName(): string 25 | { 26 | return self::NAME; 27 | } 28 | 29 | public function requiresSQLCommentHint(AbstractPlatform $platform) : bool 30 | { 31 | return true; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /manager/src/Model/User/Entity/User/Id.php: -------------------------------------------------------------------------------- 1 | value = $value; 18 | } 19 | 20 | public static function next(): self 21 | { 22 | return new self(Uuid::uuid4()->toString()); 23 | } 24 | 25 | public function getValue(): string 26 | { 27 | return $this->value; 28 | } 29 | 30 | public function __toString(): string 31 | { 32 | return $this->getValue(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /manager/src/Model/User/Entity/User/IdType.php: -------------------------------------------------------------------------------- 1 | getValue() : $value; 17 | } 18 | 19 | public function convertToPHPValue($value, AbstractPlatform $platform) 20 | { 21 | return !empty($value) ? new Id($value) : null; 22 | } 23 | 24 | public function getName(): string 25 | { 26 | return self::NAME; 27 | } 28 | 29 | public function requiresSQLCommentHint(AbstractPlatform $platform) : bool 30 | { 31 | return true; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /manager/src/Model/User/Entity/User/RoleType.php: -------------------------------------------------------------------------------- 1 | getName() : $value; 17 | } 18 | 19 | public function convertToPHPValue($value, AbstractPlatform $platform) 20 | { 21 | return !empty($value) ? new Role($value) : null; 22 | } 23 | 24 | public function getName(): string 25 | { 26 | return self::NAME; 27 | } 28 | 29 | public function requiresSQLCommentHint(AbstractPlatform $platform) : bool 30 | { 31 | return true; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /manager/src/Model/User/Service/NewEmailConfirmTokenSender.php: -------------------------------------------------------------------------------- 1 | mailer = $mailer; 18 | $this->twig = $twig; 19 | } 20 | 21 | public function send(Email $email, string $token): void 22 | { 23 | $message = (new \Swift_Message('Email Confirmation')) 24 | ->setTo($email->getValue()) 25 | ->setBody($this->twig->render('mail/user/email.html.twig', [ 26 | 'token' => $token 27 | ]), 'text/html'); 28 | 29 | if (!$this->mailer->send($message)) { 30 | throw new \RuntimeException('Unable to send message.'); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /manager/src/Model/User/Service/NewEmailConfirmTokenizer.php: -------------------------------------------------------------------------------- 1 | toString(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /manager/src/Model/User/Service/PasswordGenerator.php: -------------------------------------------------------------------------------- 1 | toString(); 14 | } 15 | } -------------------------------------------------------------------------------- /manager/src/Model/User/Service/PasswordHasher.php: -------------------------------------------------------------------------------- 1 | interval = $interval; 17 | } 18 | 19 | public function generate(): ResetToken 20 | { 21 | return new ResetToken( 22 | Uuid::uuid4()->toString(), 23 | (new \DateTimeImmutable())->add($this->interval) 24 | ); 25 | } 26 | } -------------------------------------------------------------------------------- /manager/src/Model/User/Service/SignUpConfirmTokenSender.php: -------------------------------------------------------------------------------- 1 | mailer = $mailer; 18 | $this->twig = $twig; 19 | } 20 | 21 | public function send(Email $email, string $token): void 22 | { 23 | $message = (new \Swift_Message('Sig Up Confirmation')) 24 | ->setTo($email->getValue()) 25 | ->setBody($this->twig->render('mail/user/signup.html.twig', [ 26 | 'token' => $token 27 | ]), 'text/html'); 28 | 29 | if (!$this->mailer->send($message)) { 30 | throw new \RuntimeException('Unable to send message.'); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /manager/src/Model/User/Service/SignUpConfirmTokenizer.php: -------------------------------------------------------------------------------- 1 | toString(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /manager/src/Model/User/UseCase/Activate/Command.php: -------------------------------------------------------------------------------- 1 | id = $id; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /manager/src/Model/User/UseCase/Activate/Handler.php: -------------------------------------------------------------------------------- 1 | users = $users; 19 | $this->flusher = $flusher; 20 | } 21 | 22 | public function handle(Command $command): void 23 | { 24 | $user = $this->users->get(new Id($command->id)); 25 | 26 | $user->activate(); 27 | 28 | $this->flusher->flush(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /manager/src/Model/User/UseCase/Block/Command.php: -------------------------------------------------------------------------------- 1 | id = $id; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /manager/src/Model/User/UseCase/Block/Handler.php: -------------------------------------------------------------------------------- 1 | users = $users; 19 | $this->flusher = $flusher; 20 | } 21 | 22 | public function handle(Command $command): void 23 | { 24 | $user = $this->users->get(new Id($command->id)); 25 | 26 | $user->block(); 27 | 28 | $this->flusher->flush(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /manager/src/Model/User/UseCase/Create/Command.php: -------------------------------------------------------------------------------- 1 | add('firstName', Type\TextType::class, ['label' => 'First Name']) 16 | ->add('lastName', Type\TextType::class, ['label' => 'Last Name']) 17 | ->add('email', Type\EmailType::class, ['label' => 'Email']); 18 | } 19 | 20 | public function configureOptions(OptionsResolver $resolver): void 21 | { 22 | $resolver->setDefaults(array( 23 | 'data_class' => Command::class, 24 | )); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /manager/src/Model/User/UseCase/Edit/Form.php: -------------------------------------------------------------------------------- 1 | add('firstName', Type\TextType::class, ['label' => 'First Name']) 16 | ->add('lastName', Type\TextType::class, ['label' => 'Last Name']) 17 | ->add('email', Type\EmailType::class, ['label' => 'Email']); 18 | } 19 | 20 | public function configureOptions(OptionsResolver $resolver): void 21 | { 22 | $resolver->setDefaults(array( 23 | 'data_class' => Command::class, 24 | )); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /manager/src/Model/User/UseCase/Email/Confirm/Command.php: -------------------------------------------------------------------------------- 1 | id = $id; 21 | $this->token = $token; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /manager/src/Model/User/UseCase/Email/Confirm/Handler.php: -------------------------------------------------------------------------------- 1 | users = $users; 19 | $this->flusher = $flusher; 20 | } 21 | 22 | public function handle(Command $command): void 23 | { 24 | $user = $this->users->get(new Id($command->id)); 25 | 26 | $user->confirmEmailChanging($command->token); 27 | 28 | $this->flusher->flush(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /manager/src/Model/User/UseCase/Email/Request/Command.php: -------------------------------------------------------------------------------- 1 | id = $id; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /manager/src/Model/User/UseCase/Email/Request/Form.php: -------------------------------------------------------------------------------- 1 | add('email', Type\EmailType::class); 18 | } 19 | 20 | public function configureOptions(OptionsResolver $resolver): void 21 | { 22 | $resolver->setDefaults([ 23 | 'data_class' => Command::class, 24 | ]); 25 | } 26 | } -------------------------------------------------------------------------------- /manager/src/Model/User/UseCase/Name/Command.php: -------------------------------------------------------------------------------- 1 | id = $id; 31 | } 32 | 33 | public static function fromUser(User $user): self 34 | { 35 | $command = new self($user->getId()->getValue()); 36 | $command->first = $user->getName()->getFirst(); 37 | $command->last = $user->getName()->getLast(); 38 | return $command; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /manager/src/Model/User/UseCase/Name/Form.php: -------------------------------------------------------------------------------- 1 | add('first', Type\TextType::class) 16 | ->add('last', Type\TextType::class); 17 | } 18 | 19 | public function configureOptions(OptionsResolver $resolver): void 20 | { 21 | $resolver->setDefaults([ 22 | 'data_class' => Command::class, 23 | ]); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /manager/src/Model/User/UseCase/Name/Handler.php: -------------------------------------------------------------------------------- 1 | users = $users; 20 | $this->flusher = $flusher; 21 | } 22 | 23 | public function handle(Command $command): void 24 | { 25 | $user = $this->users->get(new Id($command->id)); 26 | 27 | $user->changeName(new Name( 28 | $command->first, 29 | $command->last 30 | )); 31 | 32 | $this->flusher->flush(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /manager/src/Model/User/UseCase/Network/Attach/Command.php: -------------------------------------------------------------------------------- 1 | user = $user; 25 | $this->network = $network; 26 | $this->identity = $identity; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /manager/src/Model/User/UseCase/Network/Auth/Command.php: -------------------------------------------------------------------------------- 1 | network = $network; 29 | $this->identity = $identity; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /manager/src/Model/User/UseCase/Network/Detach/Command.php: -------------------------------------------------------------------------------- 1 | user = $user; 25 | $this->network = $network; 26 | $this->identity = $identity; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /manager/src/Model/User/UseCase/Network/Detach/Handler.php: -------------------------------------------------------------------------------- 1 | users = $users; 19 | $this->flusher = $flusher; 20 | } 21 | 22 | public function handle(Command $command): void 23 | { 24 | $user = $this->users->get(new Id($command->user)); 25 | 26 | $user->detachNetwork( 27 | $command->network, 28 | $command->identity 29 | ); 30 | 31 | $this->flusher->flush(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /manager/src/Model/User/UseCase/Reset/Request/Command.php: -------------------------------------------------------------------------------- 1 | add('email', Type\EmailType::class); 18 | } 19 | 20 | public function configureOptions(OptionsResolver $resolver): void 21 | { 22 | $resolver->setDefaults([ 23 | 'data_class' => Command::class, 24 | ]); 25 | } 26 | } -------------------------------------------------------------------------------- /manager/src/Model/User/UseCase/Reset/Reset/Command.php: -------------------------------------------------------------------------------- 1 | token = $token; 26 | } 27 | } -------------------------------------------------------------------------------- /manager/src/Model/User/UseCase/Reset/Reset/Form.php: -------------------------------------------------------------------------------- 1 | add('password', Type\PasswordType::class); 18 | } 19 | 20 | public function configureOptions(OptionsResolver $resolver): void 21 | { 22 | $resolver->setDefaults([ 23 | 'data_class' => Command::class, 24 | ]); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /manager/src/Model/User/UseCase/Role/Command.php: -------------------------------------------------------------------------------- 1 | id = $id; 26 | } 27 | 28 | public static function fromUser(User $user): self 29 | { 30 | $command = new self($user->getId()->getValue()); 31 | $command->role = $user->getRole()->getName(); 32 | return $command; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /manager/src/Model/User/UseCase/Role/Form.php: -------------------------------------------------------------------------------- 1 | add('role', Type\ChoiceType::class, ['label' => 'Role', 'choices' => [ 17 | 'User' => Role::USER, 18 | 'Admin' => Role::ADMIN, 19 | ]]); 20 | } 21 | 22 | public function configureOptions(OptionsResolver $resolver): void 23 | { 24 | $resolver->setDefaults(array( 25 | 'data_class' => Command::class, 26 | )); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /manager/src/Model/User/UseCase/Role/Handler.php: -------------------------------------------------------------------------------- 1 | users = $users; 20 | $this->flusher = $flusher; 21 | } 22 | 23 | public function handle(Command $command): void 24 | { 25 | $user = $this->users->get(new Id($command->id)); 26 | 27 | $user->changeRole(new Role($command->role)); 28 | 29 | $this->flusher->flush(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /manager/src/Model/User/UseCase/SignUp/Confirm/ByToken/Command.php: -------------------------------------------------------------------------------- 1 | token = $token; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /manager/src/Model/User/UseCase/SignUp/Confirm/ByToken/Handler.php: -------------------------------------------------------------------------------- 1 | users = $users; 18 | $this->flusher = $flusher; 19 | } 20 | 21 | public function handle(Command $command): void 22 | { 23 | if (!$user = $this->users->findByConfirmToken($command->token)) { 24 | throw new \DomainException('Incorrect or confirmed token.'); 25 | } 26 | 27 | $user->confirmSignUp(); 28 | 29 | $this->flusher->flush(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /manager/src/Model/User/UseCase/SignUp/Confirm/Manual/Command.php: -------------------------------------------------------------------------------- 1 | id = $id; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /manager/src/Model/User/UseCase/SignUp/Confirm/Manual/Handler.php: -------------------------------------------------------------------------------- 1 | users = $users; 19 | $this->flusher = $flusher; 20 | } 21 | 22 | public function handle(Command $command): void 23 | { 24 | $user = $this->users->get(new Id($command->id)); 25 | 26 | $user->confirmSignUp(); 27 | 28 | $this->flusher->flush(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /manager/src/Model/User/UseCase/SignUp/Request/Command.php: -------------------------------------------------------------------------------- 1 | add('firstName', Type\TextType::class) 16 | ->add('lastName', Type\TextType::class) 17 | ->add('email', Type\EmailType::class) 18 | ->add('password', Type\PasswordType::class); 19 | } 20 | 21 | public function configureOptions(OptionsResolver $resolver): void 22 | { 23 | $resolver->setDefaults([ 24 | 'data_class' => Command::class, 25 | ]); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Members/Group/Id.php: -------------------------------------------------------------------------------- 1 | value = $value; 18 | } 19 | 20 | public static function next(): self 21 | { 22 | return new self(Uuid::uuid4()->toString()); 23 | } 24 | 25 | public function getValue(): string 26 | { 27 | return $this->value; 28 | } 29 | 30 | public function __toString(): string 31 | { 32 | return $this->value; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Members/Group/IdType.php: -------------------------------------------------------------------------------- 1 | getValue() : $value; 17 | } 18 | 19 | public function convertToPHPValue($value, AbstractPlatform $platform) 20 | { 21 | return !empty($value) ? new Id($value) : null; 22 | } 23 | 24 | public function getName(): string 25 | { 26 | return self::NAME; 27 | } 28 | 29 | public function requiresSQLCommentHint(AbstractPlatform $platform) : bool 30 | { 31 | return true; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Members/Member/Email.php: -------------------------------------------------------------------------------- 1 | value = mb_strtolower($value); 20 | } 21 | 22 | public function getValue(): string 23 | { 24 | return $this->value; 25 | } 26 | 27 | public function isEqual(self $other): bool 28 | { 29 | return $this->getValue() === $other->getValue(); 30 | } 31 | } -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Members/Member/EmailType.php: -------------------------------------------------------------------------------- 1 | getValue() : $value; 17 | } 18 | 19 | public function convertToPHPValue($value, AbstractPlatform $platform) 20 | { 21 | return !empty($value) ? new Email($value) : null; 22 | } 23 | 24 | public function getName(): string 25 | { 26 | return self::NAME; 27 | } 28 | 29 | public function requiresSQLCommentHint(AbstractPlatform $platform) : bool 30 | { 31 | return true; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Members/Member/Id.php: -------------------------------------------------------------------------------- 1 | value = $value; 18 | } 19 | 20 | public static function next(): self 21 | { 22 | return new self(Uuid::uuid4()->toString()); 23 | } 24 | 25 | public function isEqual(self $other): bool 26 | { 27 | return $this->getValue() === $other->getValue(); 28 | } 29 | 30 | public function getValue(): string 31 | { 32 | return $this->value; 33 | } 34 | 35 | public function __toString(): string 36 | { 37 | return $this->value; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Members/Member/IdType.php: -------------------------------------------------------------------------------- 1 | getValue() : $value; 17 | } 18 | 19 | public function convertToPHPValue($value, AbstractPlatform $platform) 20 | { 21 | return !empty($value) ? new Id($value) : null; 22 | } 23 | 24 | public function getName(): string 25 | { 26 | return self::NAME; 27 | } 28 | 29 | public function requiresSQLCommentHint(AbstractPlatform $platform) : bool 30 | { 31 | return true; 32 | } 33 | } -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Members/Member/StatusType.php: -------------------------------------------------------------------------------- 1 | getName() : $value; 17 | } 18 | 19 | public function convertToPHPValue($value, AbstractPlatform $platform) 20 | { 21 | return !empty($value) ? new Status($value) : null; 22 | } 23 | 24 | public function getName(): string 25 | { 26 | return self::NAME; 27 | } 28 | 29 | public function requiresSQLCommentHint(AbstractPlatform $platform) : bool 30 | { 31 | return true; 32 | } 33 | } -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Projects/Project/Department/Id.php: -------------------------------------------------------------------------------- 1 | value = $value; 18 | } 19 | 20 | public static function next(): self 21 | { 22 | return new self(Uuid::uuid4()->toString()); 23 | } 24 | 25 | public function isEqual(self $other): bool 26 | { 27 | return $this->getValue() === $other->getValue(); 28 | } 29 | 30 | public function getValue(): string 31 | { 32 | return $this->value; 33 | } 34 | 35 | public function __toString(): string 36 | { 37 | return $this->value; 38 | } 39 | } -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Projects/Project/Department/IdType.php: -------------------------------------------------------------------------------- 1 | getValue() : $value; 17 | } 18 | 19 | public function convertToPHPValue($value, AbstractPlatform $platform) 20 | { 21 | return !empty($value) ? new Id($value) : null; 22 | } 23 | 24 | public function getName(): string 25 | { 26 | return self::NAME; 27 | } 28 | 29 | public function requiresSQLCommentHint(AbstractPlatform $platform) : bool 30 | { 31 | return true; 32 | } 33 | } -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Projects/Project/Id.php: -------------------------------------------------------------------------------- 1 | value = $value; 18 | } 19 | 20 | public static function next(): self 21 | { 22 | return new self(Uuid::uuid4()->toString()); 23 | } 24 | 25 | public function getValue(): string 26 | { 27 | return $this->value; 28 | } 29 | 30 | public function __toString(): string 31 | { 32 | return $this->value; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Projects/Project/IdType.php: -------------------------------------------------------------------------------- 1 | getValue() : $value; 17 | } 18 | 19 | public function convertToPHPValue($value, AbstractPlatform $platform) 20 | { 21 | return !empty($value) ? new Id($value) : null; 22 | } 23 | 24 | public function getName(): string 25 | { 26 | return self::NAME; 27 | } 28 | 29 | public function requiresSQLCommentHint(AbstractPlatform $platform) : bool 30 | { 31 | return true; 32 | } 33 | } -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Projects/Project/StatusType.php: -------------------------------------------------------------------------------- 1 | getName() : $value; 17 | } 18 | 19 | public function convertToPHPValue($value, AbstractPlatform $platform) 20 | { 21 | return !empty($value) ? new Status($value) : null; 22 | } 23 | 24 | public function getName(): string 25 | { 26 | return self::NAME; 27 | } 28 | 29 | public function requiresSQLCommentHint(AbstractPlatform $platform) : bool 30 | { 31 | return true; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Projects/Role/Id.php: -------------------------------------------------------------------------------- 1 | value = $value; 18 | } 19 | 20 | public static function next(): self 21 | { 22 | return new self(Uuid::uuid4()->toString()); 23 | } 24 | 25 | public function getValue(): string 26 | { 27 | return $this->value; 28 | } 29 | 30 | public function __toString(): string 31 | { 32 | return $this->value; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Projects/Role/IdType.php: -------------------------------------------------------------------------------- 1 | getValue() : $value; 17 | } 18 | 19 | public function convertToPHPValue($value, AbstractPlatform $platform) 20 | { 21 | return !empty($value) ? new Id($value) : null; 22 | } 23 | 24 | public function getName(): string 25 | { 26 | return self::NAME; 27 | } 28 | 29 | public function requiresSQLCommentHint(AbstractPlatform $platform) : bool 30 | { 31 | return true; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Projects/Task/Change/Id.php: -------------------------------------------------------------------------------- 1 | value = $value; 17 | } 18 | 19 | public static function first(): self 20 | { 21 | return new self(1); 22 | } 23 | 24 | public function next(): self 25 | { 26 | return new self($this->value + 1); 27 | } 28 | 29 | public function getValue(): int 30 | { 31 | return $this->value; 32 | } 33 | 34 | public function __toString(): string 35 | { 36 | return (string)$this->value; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Projects/Task/Change/IdType.php: -------------------------------------------------------------------------------- 1 | getValue() : $value; 17 | } 18 | 19 | public function convertToPHPValue($value, AbstractPlatform $platform) 20 | { 21 | return !empty($value) ? new Id($value) : null; 22 | } 23 | 24 | public function getName(): string 25 | { 26 | return self::NAME; 27 | } 28 | 29 | public function requiresSQLCommentHint(AbstractPlatform $platform) : bool 30 | { 31 | return true; 32 | } 33 | } -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Projects/Task/Event/TaskEdited.php: -------------------------------------------------------------------------------- 1 | actorId = $actorId; 20 | $this->taskId = $taskId; 21 | $this->name = $name; 22 | $this->content = $content; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Projects/Task/Event/TaskExecutorAssigned.php: -------------------------------------------------------------------------------- 1 | actorId = $actorId; 19 | $this->taskId = $taskId; 20 | $this->executorId = $executorId; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Projects/Task/Event/TaskExecutorRevoked.php: -------------------------------------------------------------------------------- 1 | actorId = $actorId; 19 | $this->taskId = $taskId; 20 | $this->executorId = $executorId; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Projects/Task/Event/TaskFileAdded.php: -------------------------------------------------------------------------------- 1 | actorId = $actorId; 22 | $this->taskId = $taskId; 23 | $this->fileId = $fileId; 24 | $this->info = $info; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Projects/Task/Event/TaskFileRemoved.php: -------------------------------------------------------------------------------- 1 | actorId = $actorId; 22 | $this->taskId = $taskId; 23 | $this->fileId = $fileId; 24 | $this->info = $info; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Projects/Task/Event/TaskPlanChanged.php: -------------------------------------------------------------------------------- 1 | actorId = $actorId; 19 | $this->taskId = $taskId; 20 | $this->planDate = $planDate; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Projects/Task/Event/TaskPriorityChanged.php: -------------------------------------------------------------------------------- 1 | actorId = $actorId; 19 | $this->taskId = $taskId; 20 | $this->priority = $priority; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Projects/Task/Event/TaskProgressChanged.php: -------------------------------------------------------------------------------- 1 | actorId = $actorId; 19 | $this->taskId = $taskId; 20 | $this->progress = $progress; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Projects/Task/Event/TaskStatusChanged.php: -------------------------------------------------------------------------------- 1 | actorId = $actorId; 20 | $this->taskId = $taskId; 21 | $this->status = $status; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Projects/Task/Event/TaskTypeChanged.php: -------------------------------------------------------------------------------- 1 | actorId = $actorId; 20 | $this->taskId = $taskId; 21 | $this->type = $type; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Projects/Task/File/Id.php: -------------------------------------------------------------------------------- 1 | value = $value; 18 | } 19 | 20 | public static function next(): self 21 | { 22 | return new self(Uuid::uuid4()->toString()); 23 | } 24 | 25 | public function isEqual(self $other): bool 26 | { 27 | return $this->getValue() === $other->getValue(); 28 | } 29 | 30 | public function getValue(): string 31 | { 32 | return $this->value; 33 | } 34 | 35 | public function __toString(): string 36 | { 37 | return $this->value; 38 | } 39 | } -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Projects/Task/File/IdType.php: -------------------------------------------------------------------------------- 1 | getValue() : $value; 17 | } 18 | 19 | public function convertToPHPValue($value, AbstractPlatform $platform) 20 | { 21 | return !empty($value) ? new Id($value) : null; 22 | } 23 | 24 | public function getName(): string 25 | { 26 | return self::NAME; 27 | } 28 | 29 | public function requiresSQLCommentHint(AbstractPlatform $platform) : bool 30 | { 31 | return true; 32 | } 33 | } -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Projects/Task/Id.php: -------------------------------------------------------------------------------- 1 | value = $value; 17 | } 18 | 19 | public function getValue(): int 20 | { 21 | return $this->value; 22 | } 23 | 24 | public function __toString(): string 25 | { 26 | return (string)$this->value; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Projects/Task/IdType.php: -------------------------------------------------------------------------------- 1 | getValue() : $value; 17 | } 18 | 19 | public function convertToPHPValue($value, AbstractPlatform $platform) 20 | { 21 | return !empty($value) ? new Id($value) : null; 22 | } 23 | 24 | public function getName(): string 25 | { 26 | return self::NAME; 27 | } 28 | 29 | public function requiresSQLCommentHint(AbstractPlatform $platform) : bool 30 | { 31 | return true; 32 | } 33 | } -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Projects/Task/StatusType.php: -------------------------------------------------------------------------------- 1 | getName() : $value; 17 | } 18 | 19 | public function convertToPHPValue($value, AbstractPlatform $platform) 20 | { 21 | return !empty($value) ? new Status($value) : null; 22 | } 23 | 24 | public function getName(): string 25 | { 26 | return self::NAME; 27 | } 28 | 29 | public function requiresSQLCommentHint(AbstractPlatform $platform) : bool 30 | { 31 | return true; 32 | } 33 | } -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Projects/Task/Type.php: -------------------------------------------------------------------------------- 1 | name = $name; 26 | } 27 | 28 | public function isEqual(self $other): bool 29 | { 30 | return $this->getName() === $other->getName(); 31 | } 32 | 33 | public function getName(): string 34 | { 35 | return $this->name; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /manager/src/Model/Work/Entity/Projects/Task/TypeType.php: -------------------------------------------------------------------------------- 1 | getName() : $value; 17 | } 18 | 19 | public function convertToPHPValue($value, AbstractPlatform $platform) 20 | { 21 | return !empty($value) ? new Type($value) : null; 22 | } 23 | 24 | public function getName(): string 25 | { 26 | return self::NAME; 27 | } 28 | 29 | public function requiresSQLCommentHint(AbstractPlatform $platform) : bool 30 | { 31 | return true; 32 | } 33 | } -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Members/Group/Create/Command.php: -------------------------------------------------------------------------------- 1 | add('name', Type\TextType::class); 18 | } 19 | 20 | public function configureOptions(OptionsResolver $resolver): void 21 | { 22 | $resolver->setDefaults(array( 23 | 'data_class' => Command::class, 24 | )); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Members/Group/Create/Handler.php: -------------------------------------------------------------------------------- 1 | groups = $groups; 20 | $this->flusher = $flusher; 21 | } 22 | 23 | public function handle(Command $command): void 24 | { 25 | $group = new Group( 26 | Id::next(), 27 | $command->name 28 | ); 29 | 30 | $this->groups->add($group); 31 | 32 | $this->flusher->flush(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Members/Group/Edit/Command.php: -------------------------------------------------------------------------------- 1 | id = $id; 26 | } 27 | 28 | public static function fromGroup(Group $group): self 29 | { 30 | $command = new self($group->getId()->getValue()); 31 | $command->name = $group->getName(); 32 | return $command; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Members/Group/Edit/Form.php: -------------------------------------------------------------------------------- 1 | add('name', Type\TextType::class); 18 | } 19 | 20 | public function configureOptions(OptionsResolver $resolver): void 21 | { 22 | $resolver->setDefaults(array( 23 | 'data_class' => Command::class, 24 | )); 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Members/Group/Edit/Handler.php: -------------------------------------------------------------------------------- 1 | groups = $groups; 19 | $this->flusher = $flusher; 20 | } 21 | 22 | public function handle(Command $command): void 23 | { 24 | $group = $this->groups->get(new Id($command->id)); 25 | 26 | $group->edit($command->name); 27 | 28 | $this->flusher->flush(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Members/Group/Remove/Command.php: -------------------------------------------------------------------------------- 1 | id = $id; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Members/Member/Archive/Command.php: -------------------------------------------------------------------------------- 1 | id = $id; 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Members/Member/Archive/Handler.php: -------------------------------------------------------------------------------- 1 | members = $members; 19 | $this->flusher = $flusher; 20 | } 21 | 22 | public function handle(Command $command): void 23 | { 24 | $member = $this->members->get(new Id($command->id)); 25 | 26 | $member->archive(); 27 | 28 | $this->flusher->flush(); 29 | } 30 | } -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Members/Member/Create/Command.php: -------------------------------------------------------------------------------- 1 | id = $id; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Members/Member/Edit/Form.php: -------------------------------------------------------------------------------- 1 | add('firstName', Type\TextType::class) 18 | ->add('lastName', Type\TextType::class) 19 | ->add('email', Type\EmailType::class); 20 | } 21 | 22 | public function configureOptions(OptionsResolver $resolver): void 23 | { 24 | $resolver->setDefaults(array( 25 | 'data_class' => Command::class, 26 | )); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Members/Member/Move/Command.php: -------------------------------------------------------------------------------- 1 | id = $id; 24 | } 25 | 26 | public static function fromMember(Member $member): self 27 | { 28 | $command = new self($member->getId()->getValue()); 29 | $command->group = $member->getGroup()->getId()->getValue(); 30 | return $command; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Members/Member/Reinstate/Command.php: -------------------------------------------------------------------------------- 1 | id = $id; 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Members/Member/Reinstate/Handler.php: -------------------------------------------------------------------------------- 1 | members = $members; 19 | $this->flusher = $flusher; 20 | } 21 | 22 | public function handle(Command $command): void 23 | { 24 | $member = $this->members->get(new Id($command->id)); 25 | 26 | $member->reinstate(); 27 | 28 | $this->flusher->flush(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Project/Archive/Command.php: -------------------------------------------------------------------------------- 1 | id = $id; 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Project/Archive/Handler.php: -------------------------------------------------------------------------------- 1 | projects = $projects; 19 | $this->flusher = $flusher; 20 | } 21 | 22 | public function handle(Command $command): void 23 | { 24 | $project = $this->projects->get(new Id($command->id)); 25 | 26 | $project->archive(); 27 | 28 | $this->flusher->flush(); 29 | } 30 | } -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Project/Create/Command.php: -------------------------------------------------------------------------------- 1 | add('name', Type\TextType::class) 18 | ->add('sort', Type\IntegerType::class); 19 | } 20 | 21 | public function configureOptions(OptionsResolver $resolver): void 22 | { 23 | $resolver->setDefaults(array( 24 | 'data_class' => Command::class, 25 | )); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Project/Create/Handler.php: -------------------------------------------------------------------------------- 1 | projects = $projects; 20 | $this->flusher = $flusher; 21 | } 22 | 23 | public function handle(Command $command): void 24 | { 25 | $project = new Project( 26 | Id::next(), 27 | $command->name, 28 | $command->sort 29 | ); 30 | 31 | $this->projects->add($project); 32 | 33 | $this->flusher->flush(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Project/Department/Create/Command.php: -------------------------------------------------------------------------------- 1 | project = $project; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Project/Department/Create/Form.php: -------------------------------------------------------------------------------- 1 | add('name', Type\TextType::class); 18 | } 19 | 20 | public function configureOptions(OptionsResolver $resolver): void 21 | { 22 | $resolver->setDefaults(array( 23 | 'data_class' => Command::class, 24 | )); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Project/Department/Edit/Form.php: -------------------------------------------------------------------------------- 1 | add('name', Type\TextType::class); 18 | } 19 | 20 | public function configureOptions(OptionsResolver $resolver): void 21 | { 22 | $resolver->setDefaults(array( 23 | 'data_class' => Command::class, 24 | )); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Project/Department/Edit/Handler.php: -------------------------------------------------------------------------------- 1 | projects = $projects; 20 | $this->flusher = $flusher; 21 | } 22 | 23 | public function handle(Command $command): void 24 | { 25 | $project = $this->projects->get(new Id($command->project)); 26 | 27 | $project->editDepartment(new DepartmentId($command->id), $command->name); 28 | 29 | $this->flusher->flush(); 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Project/Department/Remove/Command.php: -------------------------------------------------------------------------------- 1 | project = $project; 23 | $this->id = $id; 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Project/Department/Remove/Handler.php: -------------------------------------------------------------------------------- 1 | projects = $projects; 20 | $this->flusher = $flusher; 21 | } 22 | 23 | public function handle(Command $command): void 24 | { 25 | $project = $this->projects->get(new Id($command->project)); 26 | 27 | $project->removeDepartment(new DepartmentId($command->id)); 28 | 29 | $this->flusher->flush(); 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Project/Edit/Command.php: -------------------------------------------------------------------------------- 1 | id = $id; 28 | } 29 | 30 | public static function fromProject(Project $project): self 31 | { 32 | $command = new self($project->getId()->getValue()); 33 | $command->name = $project->getName(); 34 | $command->sort = $project->getSort(); 35 | return $command; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Project/Edit/Form.php: -------------------------------------------------------------------------------- 1 | add('name', Type\TextType::class) 18 | ->add('sort', Type\IntegerType::class); 19 | } 20 | 21 | public function configureOptions(OptionsResolver $resolver): void 22 | { 23 | $resolver->setDefaults(array( 24 | 'data_class' => Command::class, 25 | )); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Project/Edit/Handler.php: -------------------------------------------------------------------------------- 1 | projects = $projects; 19 | $this->flusher = $flusher; 20 | } 21 | 22 | public function handle(Command $command): void 23 | { 24 | $project = $this->projects->get(new Id($command->id)); 25 | 26 | $project->edit( 27 | $command->name, 28 | $command->sort 29 | ); 30 | 31 | $this->flusher->flush(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Project/Membership/Add/Command.php: -------------------------------------------------------------------------------- 1 | project = $project; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Project/Membership/Remove/Command.php: -------------------------------------------------------------------------------- 1 | project = $project; 23 | $this->member = $member; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Project/Reinstate/Command.php: -------------------------------------------------------------------------------- 1 | id = $id; 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Project/Reinstate/Handler.php: -------------------------------------------------------------------------------- 1 | projects = $projects; 19 | $this->flusher = $flusher; 20 | } 21 | 22 | public function handle(Command $command): void 23 | { 24 | $project = $this->projects->get(new Id($command->id)); 25 | 26 | $project->reinstate(); 27 | 28 | $this->flusher->flush(); 29 | } 30 | } -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Project/Remove/Command.php: -------------------------------------------------------------------------------- 1 | id = $id; 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Project/Remove/Handler.php: -------------------------------------------------------------------------------- 1 | projects = $projects; 19 | $this->flusher = $flusher; 20 | } 21 | 22 | public function handle(Command $command): void 23 | { 24 | $project = $this->projects->get(new Id($command->id)); 25 | 26 | $this->projects->remove($project); 27 | 28 | $this->flusher->flush(); 29 | } 30 | } -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Role/Copy/Command.php: -------------------------------------------------------------------------------- 1 | id = $id; 25 | } 26 | } -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Role/Copy/Form.php: -------------------------------------------------------------------------------- 1 | add('name', Type\TextType::class); 18 | } 19 | 20 | public function configureOptions(OptionsResolver $resolver): void 21 | { 22 | $resolver->setDefaults(array( 23 | 'data_class' => Command::class, 24 | )); 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Role/Create/Command.php: -------------------------------------------------------------------------------- 1 | roles = $roles; 19 | $this->flusher = $flusher; 20 | } 21 | 22 | public function handle(Command $command): void 23 | { 24 | $role = $this->roles->get(new Id($command->id)); 25 | 26 | $role->edit($command->name, $command->permissions); 27 | 28 | $this->flusher->flush(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Role/Remove/Command.php: -------------------------------------------------------------------------------- 1 | id = $id; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Task/ChildOf/Command.php: -------------------------------------------------------------------------------- 1 | actor = $actor; 26 | $this->id = $id; 27 | } 28 | 29 | public static function fromTask(string $actor, Task $task): self 30 | { 31 | $command = new self($actor, $task->getId()->getValue()); 32 | $command->parent = $task->getParent() ? $task->getParent()->getId()->getValue() : null; 33 | return $command; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Task/ChildOf/Form.php: -------------------------------------------------------------------------------- 1 | add('parent', Type\IntegerType::class, ['required' => false]); 18 | } 19 | 20 | public function configureOptions(OptionsResolver $resolver): void 21 | { 22 | $resolver->setDefaults(array( 23 | 'data_class' => Command::class, 24 | )); 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Task/Create/NameRow.php: -------------------------------------------------------------------------------- 1 | name = $name; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Task/Edit/Form.php: -------------------------------------------------------------------------------- 1 | add('name', Type\TextType::class) 18 | ->add('content', Type\TextareaType::class, ['required' => false, 'attr' => ['rows' => 10]]); 19 | } 20 | 21 | public function configureOptions(OptionsResolver $resolver): void 22 | { 23 | $resolver->setDefaults(array( 24 | 'data_class' => Command::class, 25 | )); 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Task/Executor/Assign/Command.php: -------------------------------------------------------------------------------- 1 | actor = $actor; 28 | $this->id = $id; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Task/Executor/Revoke/Command.php: -------------------------------------------------------------------------------- 1 | actor = $actor; 27 | $this->id = $id; 28 | $this->member = $member; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Task/Files/Add/Command.php: -------------------------------------------------------------------------------- 1 | id = $id; 27 | $this->actor = $actor; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Task/Files/Add/File.php: -------------------------------------------------------------------------------- 1 | path = $path; 16 | $this->name = $name; 17 | $this->size = $size; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Task/Files/Remove/Command.php: -------------------------------------------------------------------------------- 1 | actor = $actor; 27 | $this->id = $id; 28 | $this->file = $file; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Task/Plan/Remove/Command.php: -------------------------------------------------------------------------------- 1 | actor = $actor; 23 | $this->id = $id; 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Task/Plan/Set/Command.php: -------------------------------------------------------------------------------- 1 | actor = $actor; 28 | $this->id = $id; 29 | } 30 | 31 | public static function fromTask(string $actor, Task $task): self 32 | { 33 | $command = new self($actor, $task->getId()->getValue()); 34 | $command->date = $task->getPlanDate() ?: new \DateTimeImmutable(); 35 | return $command; 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Task/Plan/Set/Form.php: -------------------------------------------------------------------------------- 1 | add('date', Type\DateType::class, ['widget' => 'single_text', 'input' => 'datetime_immutable']); 18 | } 19 | 20 | public function configureOptions(OptionsResolver $resolver): void 21 | { 22 | $resolver->setDefaults(array( 23 | 'data_class' => Command::class, 24 | )); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Task/Priority/Command.php: -------------------------------------------------------------------------------- 1 | actor = $actor; 28 | $this->id = $id; 29 | } 30 | 31 | public static function fromTask(string $actor, Task $task): self 32 | { 33 | $command = new self($actor, $task->getId()->getValue()); 34 | $command->priority = $task->getPriority(); 35 | return $command; 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Task/Progress/Command.php: -------------------------------------------------------------------------------- 1 | actor = $actor; 28 | $this->id = $id; 29 | } 30 | 31 | public static function fromTask(string $actor, Task $task): self 32 | { 33 | $command = new self($actor, $task->getId()->getValue()); 34 | $command->progress = $task->getProgress(); 35 | return $command; 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Task/Remove/Command.php: -------------------------------------------------------------------------------- 1 | id = $id; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Task/Remove/Handler.php: -------------------------------------------------------------------------------- 1 | tasks = $tasks; 19 | $this->flusher = $flusher; 20 | } 21 | 22 | public function handle(Command $command): void 23 | { 24 | $task = $this->tasks->get(new Id($command->id)); 25 | 26 | $this->tasks->remove($task); 27 | 28 | $this->flusher->flush($task); 29 | } 30 | } -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Task/Start/Command.php: -------------------------------------------------------------------------------- 1 | actor = $actor; 23 | $this->id = $id; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Task/Status/Command.php: -------------------------------------------------------------------------------- 1 | actor = $actor; 28 | $this->id = $id; 29 | } 30 | 31 | public static function fromTask(string $actor, Task $task): self 32 | { 33 | $command = new self($actor, $task->getId()->getValue()); 34 | $command->status = $task->getStatus()->getName(); 35 | return $command; 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Task/Take/Command.php: -------------------------------------------------------------------------------- 1 | id = $id; 23 | $this->actor = $actor; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Task/TakeAndStart/Command.php: -------------------------------------------------------------------------------- 1 | id = $id; 23 | $this->actor = $actor; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /manager/src/Model/Work/UseCase/Projects/Task/Type/Command.php: -------------------------------------------------------------------------------- 1 | actor = $actor; 28 | $this->id = $id; 29 | } 30 | 31 | public static function fromTask(string $actor, Task $task): self 32 | { 33 | $command = new self($actor, $task->getId()->getValue()); 34 | $command->type = $task->getType()->getName(); 35 | return $command; 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /manager/src/ReadModel/Comment/CommentRow.php: -------------------------------------------------------------------------------- 1 | project = $project; 15 | } 16 | 17 | public static function forProject(string $project): self 18 | { 19 | return new self($project); 20 | } 21 | 22 | public static function all(): self 23 | { 24 | return new self(null); 25 | } 26 | 27 | public function forMember(string $member): self 28 | { 29 | $clone = clone $this; 30 | $clone->member = $member; 31 | return $clone; 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /manager/src/ReadModel/Work/Projects/Calendar/Query/Query.php: -------------------------------------------------------------------------------- 1 | year = $year; 17 | $this->month = $month; 18 | } 19 | 20 | public static function fromDate(\DateTimeImmutable $date): self 21 | { 22 | return new self((int)$date->format('Y'), (int)$date->format('m')); 23 | } 24 | 25 | public function forProject(string $project): self 26 | { 27 | $clone = clone $this; 28 | $clone->project = $project; 29 | return $clone; 30 | } 31 | 32 | public function forMember(string $member): self 33 | { 34 | $clone = clone $this; 35 | $clone->member = $member; 36 | return $clone; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /manager/src/ReadModel/Work/Projects/Calendar/Result.php: -------------------------------------------------------------------------------- 1 | items = $items; 17 | $this->start = $start; 18 | $this->end = $end; 19 | $this->month = $month; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /manager/src/ReadModel/Work/Projects/Project/Filter/Filter.php: -------------------------------------------------------------------------------- 1 | member = $member; 18 | } 19 | 20 | public static function all(): self 21 | { 22 | return new self(null); 23 | } 24 | 25 | public static function forMember(string $id): self 26 | { 27 | return new self($id); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /manager/src/Security/OAuth/Server/RequestResolver.php: -------------------------------------------------------------------------------- 1 | 'onRequestResolve', 17 | ]; 18 | } 19 | 20 | public function onRequestResolve(AuthorizationRequestResolveEvent $event): void 21 | { 22 | $user = $event->getUser(); 23 | 24 | if (null === $user) { 25 | return; 26 | } 27 | 28 | $event->resolveAuthorization(AuthorizationRequestResolveEvent::AUTHORIZATION_APPROVED); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /manager/src/Security/UserChecker.php: -------------------------------------------------------------------------------- 1 | isActive()) { 20 | $exception = new DisabledException('User account is disabled.'); 21 | $exception->setUser($identity); 22 | throw $exception; 23 | } 24 | } 25 | 26 | public function checkPostAuth(UserInterface $identity): void 27 | { 28 | if (!$identity instanceof UserIdentity) { 29 | return; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /manager/src/Service/Gravatar.php: -------------------------------------------------------------------------------- 1 | $size, 13 | 'd' => 'identicon', 14 | ]); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /manager/src/Service/Uploader/File.php: -------------------------------------------------------------------------------- 1 | path = $path; 16 | $this->name = $name; 17 | $this->size = $size; 18 | } 19 | 20 | public function getPath(): string 21 | { 22 | return $this->path; 23 | } 24 | 25 | public function getName(): string 26 | { 27 | return $this->name; 28 | } 29 | 30 | public function getSize(): int 31 | { 32 | return $this->size; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /manager/src/Service/Work/Processor/Driver/Driver.php: -------------------------------------------------------------------------------- 1 | drivers = $drivers; 19 | } 20 | 21 | public function process(?string $text): string 22 | { 23 | $result = $text; 24 | foreach ($this->drivers as $driver) { 25 | $result = $driver->process($result); 26 | } 27 | return $result; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /manager/src/Twig/Extension/GravatarExtension.php: -------------------------------------------------------------------------------- 1 | ['html']]), 17 | ]; 18 | } 19 | 20 | public function gravatar(string $email, int $size): string 21 | { 22 | return Gravatar::url($email, $size); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /manager/src/Twig/Extension/MarkdownExtension.php: -------------------------------------------------------------------------------- 1 | markdown = $markdown; 18 | } 19 | 20 | public function getFilters(): array 21 | { 22 | return [ 23 | new TwigFilter('markdown', [$this, 'markdown'], ['is_safe' => ['html']]), 24 | ]; 25 | } 26 | 27 | public function markdown(?string $text): string 28 | { 29 | return $this->markdown->parse($text); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /manager/src/Twig/Extension/StoragePathExtension.php: -------------------------------------------------------------------------------- 1 | uploader = $uploader; 18 | } 19 | 20 | public function getFunctions(): array 21 | { 22 | return [ 23 | new TwigFunction('storage_path', [$this, 'path'], ['is_safe' => ['html']]), 24 | ]; 25 | } 26 | 27 | public function path(string $path): string 28 | { 29 | return $this->uploader->generateUrl($path); 30 | } 31 | } -------------------------------------------------------------------------------- /manager/src/Twig/Extension/Work/ProcessorExtension.php: -------------------------------------------------------------------------------- 1 | processor = $processor; 22 | } 23 | 24 | public function getFilters(): array 25 | { 26 | return [ 27 | new TwigFilter('work_processor', [$this, 'process'], ['is_safe' => ['html']]), 28 | ]; 29 | } 30 | 31 | public function process(?string $text): string 32 | { 33 | return $this->processor->process($text); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /manager/src/Widget/User/RoleWidget.php: -------------------------------------------------------------------------------- 1 | true, 'is_safe' => ['html']]), 17 | ]; 18 | } 19 | 20 | public function role(Environment $twig, string $role): string 21 | { 22 | return $twig->render('widget/user/role.html.twig', [ 23 | 'role' => $role 24 | ]); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /manager/src/Widget/User/StatusWidget.php: -------------------------------------------------------------------------------- 1 | true, 'is_safe' => ['html']]), 17 | ]; 18 | } 19 | 20 | public function status(Environment $twig, string $status): string 21 | { 22 | return $twig->render('widget/user/status.html.twig', [ 23 | 'status' => $status 24 | ]); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /manager/src/Widget/Work/Members/Member/StatusWidget.php: -------------------------------------------------------------------------------- 1 | true, 'is_safe' => ['html']]), 17 | ]; 18 | } 19 | 20 | public function status(Environment $twig, string $status): string 21 | { 22 | return $twig->render('widget/work/members/member/status.html.twig', [ 23 | 'status' => $status 24 | ]); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /manager/src/Widget/Work/Projects/ActionRowWidget.php: -------------------------------------------------------------------------------- 1 | true, 'is_safe' => ['html']]), 18 | ]; 19 | } 20 | 21 | public function row(Environment $twig, array $action): string 22 | { 23 | return $twig->render('widget/work/projects/action-row.html.twig', compact('action')); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /manager/src/Widget/Work/Projects/Project/StatusWidget.php: -------------------------------------------------------------------------------- 1 | true, 'is_safe' => ['html']]), 17 | ]; 18 | } 19 | 20 | public function status(Environment $twig, string $status): string 21 | { 22 | return $twig->render('widget/work/projects/project/status.html.twig', [ 23 | 'status' => $status 24 | ]); 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /manager/src/Widget/Work/Projects/Task/PriorityWidget.php: -------------------------------------------------------------------------------- 1 | true, 'is_safe' => ['html']]), 17 | ]; 18 | } 19 | 20 | public function priority(Environment $twig, string $priority): string 21 | { 22 | return $twig->render('widget/work/projects/task/priority.html.twig', [ 23 | 'priority' => $priority 24 | ]); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /manager/src/Widget/Work/Projects/Task/ProgressWidget.php: -------------------------------------------------------------------------------- 1 | true, 'is_safe' => ['html']]), 17 | ]; 18 | } 19 | 20 | public function progress(Environment $twig, int $progress): string 21 | { 22 | return $twig->render('widget/work/projects/task/progress.html.twig', [ 23 | 'progress' => $progress 24 | ]); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /manager/src/Widget/Work/Projects/Task/StatusWidget.php: -------------------------------------------------------------------------------- 1 | true, 'is_safe' => ['html']]), 17 | ]; 18 | } 19 | 20 | public function status(Environment $twig, string $status): string 21 | { 22 | return $twig->render('widget/work/projects/task/status.html.twig', [ 23 | 'status' => $status 24 | ]); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /manager/src/Widget/Work/Projects/Task/TypeWidget.php: -------------------------------------------------------------------------------- 1 | true, 'is_safe' => ['html']]), 17 | ]; 18 | } 19 | 20 | public function type(Environment $twig, string $type): string 21 | { 22 | return $twig->render('widget/work/projects/task/type.html.twig', [ 23 | 'type' => $type 24 | ]); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /manager/templates/_flashes.html.twig: -------------------------------------------------------------------------------- 1 | {% for message in app.flashes('success') %} 2 |
Email Confirm Link:
6 | 7 | {% set url = url('profile.email.confirm', {'token': token}) %} 8 | 9 | 10 | 11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /manager/templates/mail/user/reset.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'mail.html.twig' %} 2 | 3 | {% block body %} 4 | 5 |Password Reset Link:
6 | 7 | {% set url = url('auth.reset.reset', {'token': token}) %} 8 | 9 | 10 | 11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /manager/templates/mail/user/signup.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'mail.html.twig' %} 2 | 3 | {% block body %} 4 | 5 |Sign Up confirm link:
6 | 7 | {% set url = url('auth.signup.confirm', {'token': token}) %} 8 | 9 | 10 | 11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /manager/templates/mail/work/projects/task/executor-assigned-author.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'mail.html.twig' %} 2 | 3 | {% block body %} 4 | 5 |Hello, {{ author.name.first }}!
6 | 7 |Your task «{{ task.name }}» has assigned to executor {{ executor.name.full }}:
8 | 9 | {% set url = url('work.projects.tasks.show', {'id': task.id}) %} 10 | 11 | 12 | 13 | {% endblock %} -------------------------------------------------------------------------------- /manager/templates/mail/work/projects/task/executor-assigned-executor.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'mail.html.twig' %} 2 | 3 | {% block body %} 4 | 5 |Hello, {{ executor.name.first }}!
6 | 7 |You are assigned to task «{{ task.name }}»:
8 | 9 | {% set url = url('work.projects.tasks.show', {'id': task.id}) %} 10 | 11 | 12 | 13 | {% endblock %} -------------------------------------------------------------------------------- /manager/templates/override/menu.html.twig: -------------------------------------------------------------------------------- 1 | {% extends '@KnpMenu/menu.html.twig' %} 2 | 3 | {% block label %} 4 | {% if item.extra('icon') is not null %} 5 | 6 | {% endif %} 7 | {{ parent() }} 8 | {% endblock %} 9 | 10 | {% block item %} 11 | {% if item.displayed %} 12 | {% if matcher.isCurrent(item) %} 13 | {% do item.setLinkAttribute('class', item.getLinkAttribute('class') ~ ' ' ~ options.currentClass) %} 14 | {% endif %} 15 | {{ parent() }} 16 | {% endif %} 17 | {% endblock %} 18 | 19 | {% block compressed_root %} 20 | {{ block('root')|spaceless }} 21 | {% endblock %} -------------------------------------------------------------------------------- /manager/templates/override/sortable_link.html.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | {% if sorted %} 4 | {% if direction == 'desc' %} 5 | 6 | {% else %} 7 | 8 | {% endif %} 9 | {% else %} 10 | 11 | {% endif %} 12 | 13 | {{ title|raw }} 14 | 15 | -------------------------------------------------------------------------------- /manager/templates/processor/work/member.html.twig: -------------------------------------------------------------------------------- 1 | {{ member.name.full }} -------------------------------------------------------------------------------- /manager/templates/processor/work/task.html.twig: -------------------------------------------------------------------------------- 1 | #{{ task.id }} -------------------------------------------------------------------------------- /manager/templates/widget/user/role.html.twig: -------------------------------------------------------------------------------- 1 | {% if role == 'ROLE_USER' %} 2 | User 3 | {% elseif role == 'ROLE_ADMIN' %} 4 | Admin 5 | {% endif %} -------------------------------------------------------------------------------- /manager/templates/widget/user/status.html.twig: -------------------------------------------------------------------------------- 1 | {% if status == 'wait' %} 2 | Wait 3 | {% elseif status == 'active' %} 4 | Active 5 | {% elseif status == 'blocked' %} 6 | Block 7 | {% endif %} -------------------------------------------------------------------------------- /manager/templates/widget/work/members/member/status.html.twig: -------------------------------------------------------------------------------- 1 | {% if status == 'active' %} 2 | Active 3 | {% elseif status == 'archived' %} 4 | Archived 5 | {% endif %} -------------------------------------------------------------------------------- /manager/templates/widget/work/projects/project/status.html.twig: -------------------------------------------------------------------------------- 1 | {% if status == 'active' %} 2 | Active 3 | {% elseif status == 'archived' %} 4 | Archived 5 | {% endif %} -------------------------------------------------------------------------------- /manager/templates/widget/work/projects/task/priority.html.twig: -------------------------------------------------------------------------------- 1 | {% if priority == 1 %} 2 | {% set color = '#888' %} 3 | {% elseif priority == 2 %} 4 | {% set color = '#00c0ef' %} 5 | {% elseif priority == 3 %} 6 | {% set color = '#f39c12' %} 7 | {% elseif priority == 4 %} 8 | {% set color = '#dd4b39' %} 9 | {% endif %} 10 | 11 | 12 | {% for i in 1..4 %} 13 | {% if i <= priority %} 14 | 15 | {% else %} 16 | 17 | {% endif %} 18 | {% endfor %} 19 | -------------------------------------------------------------------------------- /manager/templates/widget/work/projects/task/progress.html.twig: -------------------------------------------------------------------------------- 1 | {% if progress %} 2 |