├── .editorconfig ├── .github └── workflows │ └── tests.yml ├── .php-cs-fixer.dist.php ├── LICENSE ├── README.md ├── composer.json └── src ├── Api ├── Client │ ├── Client.php │ └── ClientRequest.php ├── Project │ ├── Project.php │ └── ProjectRequest.php ├── Tag │ ├── Tag.php │ └── TagRequest.php ├── Task │ ├── Task.php │ └── TaskRequest.php ├── TimeEntry │ ├── StopTimeEntryRequest.php │ ├── TimeEntriesDurationRequest.php │ ├── TimeEntry.php │ ├── TimeEntryRequest.php │ └── UpdateTimeEntryRequest.php ├── User │ └── User.php └── Workspace │ ├── Workspace.php │ └── WorkspaceRequest.php ├── ApiFactory.php ├── Client.php ├── ClientBuilder.php ├── Exception ├── BadRequest.php ├── ClockifyException.php ├── Forbidden.php ├── NotFound.php └── Unauthorized.php └── Model ├── AutomaticLockDto.php ├── AutomaticLockEnum.php ├── ClientDto.php ├── CurrentUserDto.php ├── DashboardSelection.php ├── DashboardViewType.php ├── DaysEnum.php ├── EstimateDto.php ├── EstimateType.php ├── HourlyRateDto.php ├── MembershipDto.php ├── MembershipEnum.php ├── PagesEnum.php ├── PeriodEnum.php ├── ProjectDtoImpl.php ├── Round.php ├── SummaryReportSettingsDto.php ├── TagDto.php ├── TaskDto.php ├── TaskStatus.php ├── TimeEntryDtoImpl.php ├── TimeIntervalDto.php ├── UserDto.php ├── UserSettingsDto.php ├── UserStatus.php ├── WorkspaceDto.php └── WorkspaceSettingsDto.php /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | indent_style = space 8 | indent_size = 4 9 | trim_trailing_whitespace = true 10 | 11 | [*.yml] 12 | indent_size = 2 13 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: Continuous Integration 2 | on: [push] 3 | 4 | jobs: 5 | linter: 6 | name: Code Style 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: Checkout 10 | uses: actions/checkout@v2 11 | - name: Setup PHP 12 | uses: shivammathur/setup-php@v2 13 | with: 14 | php-version: 7.4 15 | coverage: xdebug 16 | - name: Get Composer Cache Directory 17 | id: composer-cache 18 | run: echo "::set-output name=dir::$(composer config cache-files-dir)" 19 | - name: Cache dependencies 20 | uses: actions/cache@v2 21 | with: 22 | path: ${{ steps.composer-cache.outputs.dir }} 23 | key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} 24 | restore-keys: ${{ runner.os }}-composer- 25 | - name: Install Dependencies 26 | run: composer install --no-progress 27 | - name: Run php-cs-fixture 28 | run: vendor/bin/php-cs-fixer fix -v --dry-run 29 | 30 | stan: 31 | name: Static analysis 32 | runs-on: ubuntu-latest 33 | steps: 34 | - name: Checkout 35 | uses: actions/checkout@v2 36 | - name: Setup PHP 37 | uses: shivammathur/setup-php@v2 38 | with: 39 | php-version: 7.4 40 | coverage: xdebug 41 | - name: Get Composer Cache Directory 42 | id: composer-cache 43 | run: echo "::set-output name=dir::$(composer config cache-files-dir)" 44 | - name: Cache dependencies 45 | uses: actions/cache@v2 46 | with: 47 | path: ${{ steps.composer-cache.outputs.dir }} 48 | key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} 49 | restore-keys: ${{ runner.os }}-composer- 50 | - name: Install Dependencies 51 | run: composer install --no-progress 52 | - name: Run phpstan 53 | run: vendor/bin/phpstan analyse src -c phpstan.neon -l 5 54 | 55 | tests: 56 | name: Unit Tests 57 | runs-on: ubuntu-latest 58 | strategy: 59 | matrix: 60 | php: ['7.3', '7.4', '8.0', '8.1'] 61 | flags: ['', '--prefer-lowest', '--prefer-stable'] 62 | steps: 63 | - name: Checkout 64 | uses: actions/checkout@v2 65 | - name: Setup PHP 66 | uses: shivammathur/setup-php@v2 67 | with: 68 | php-version: ${{ matrix.php }} 69 | coverage: xdebug 70 | - name: Get Composer Cache Directory 71 | id: composer-cache 72 | run: echo "::set-output name=dir::$(composer config cache-files-dir)" 73 | - name: Cache dependencies 74 | uses: actions/cache@v2 75 | with: 76 | path: ${{ steps.composer-cache.outputs.dir }} 77 | key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} 78 | restore-keys: ${{ runner.os }}-composer- 79 | - name: Install Dependencies 80 | run: composer update --prefer-dist --no-interaction --optimize-autoloader --prefer-stable --no-progress $COMPOSER_FLAGS 81 | env: 82 | COMPOSER_FLAGS: ${{ matrix.flags }} 83 | - name: Run PHPUnit 84 | run: vendor/bin/phpunit 85 | -------------------------------------------------------------------------------- /.php-cs-fixer.dist.php: -------------------------------------------------------------------------------- 1 | in(__DIR__) 5 | ->exclude('vendor') 6 | ; 7 | 8 | $config = new PhpCsFixer\Config(); 9 | $config 10 | ->setRules([ 11 | '@PSR2' => true, 12 | 'array_syntax' => ['syntax' => 'short'], 13 | 'function_declaration' => ['closure_function_spacing' => 'none'], 14 | 'single_import_per_statement' => false, 15 | ]) 16 | ->setFinder($finder) 17 | ; 18 | 19 | return $config; 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016-2018 Jérémy DECOOL 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Clockify API client 2 | ==================== 3 | 4 | [![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Fjdecool%2Fclockify-api%2Fbadge%3Fref%3Dmaster&style=flat)](https://actions-badge.atrox.dev/jdecool/clockify-api/goto?ref=master) 5 | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/jdecool/clockify-api/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/jdecool/clockify-api/?branch=master) 6 | [![Latest Stable Version](https://poser.pugx.org/jdecool/clockify-api/v/stable.png)](https://packagist.org/packages/jdecool/clockify-api) 7 | 8 | PHP client for [Clockify.me API](https://clockify.me/developers-api). 9 | 10 | ## Install it 11 | 12 | You need to install the library with a PSR-18 compliant HTTP client. 13 | 14 | Example using Guzzle: 15 | 16 | ```bash 17 | composer require jdecool/clockify-api guzzlehttp/guzzle http-interop/http-factory-guzzle 18 | ``` 19 | 20 | The library is decoupled from any HTTP message client with [HTTPlug](http://httplug.io). 21 | That's why you need to install a client implementation `http://httplug.io/` in this example. 22 | 23 | ## Getting started 24 | 25 | ### Use the HTTP client 26 | 27 | ```php 28 | createClientV1('your-clockify-api-key'); 34 | 35 | $workspaces = $client->get('workspaces'); 36 | ``` 37 | 38 | ### Use the decicated API client 39 | 40 | ```php 41 | require __DIR__.'/vendor/autoload.php'; 42 | 43 | $builder = new JDecool\Clockify\ClientBuilder(); 44 | $client = $builder->createClientV1('your-clockify-api-key'); 45 | 46 | $apiFactory = new JDecool\Clockify\ApiFactory($client); 47 | $workspaceApi = $apiFactory->workspaceApi(); 48 | 49 | $workspaces = $workspaceApi->workspaces(); // return an array of JDecool\Clockify\Model\WorkspaceDto 50 | ``` 51 | 52 | Available APIs: 53 | 54 | * [Client](https://clockify.me/developers-api#tag-Client) 55 | * [Project](https://clockify.me/developers-api#tag-Project) 56 | * [Tag](https://clockify.me/developers-api#tag-Tag) 57 | * [Task](https://clockify.me/developers-api#tag-Task) 58 | * [Time entry](https://clockify.me/developers-api#tag-Time-entry) 59 | * [User](https://clockify.me/developers-api#tag-User) 60 | * [Workspace](https://clockify.me/developers-api#tag-Workspace) 61 | 62 | ## LICENSE 63 | 64 | This library is licensed under the [MIT License](LICENSE). 65 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jdecool/clockify-api", 3 | "type": "library", 4 | "description": "PHP Client for Clockify.me API", 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "Jérémy DECOOL", 9 | "email": "contact@jdecool.fr" 10 | } 11 | ], 12 | "require": { 13 | "php": "^7.3|^8.0", 14 | "ext-json": "*", 15 | "guzzlehttp/guzzle": "^7.2", 16 | "http-interop/http-factory-guzzle": "^1.0", 17 | "myclabs/php-enum": "^1.7", 18 | "php-http/client-common": "^2.3", 19 | "php-http/discovery": "^1.12", 20 | "php-http/guzzle7-adapter": "^0.1.1", 21 | "php-http/httplug": "^2.1" 22 | }, 23 | "require-dev": { 24 | "friendsofphp/php-cs-fixer": "^3.1", 25 | "phpstan/phpstan": "^0.12.57", 26 | "phpunit/phpunit": "^9.5" 27 | }, 28 | "autoload": { 29 | "psr-4": { 30 | "JDecool\\Clockify\\": "src" 31 | } 32 | }, 33 | "autoload-dev": { 34 | "psr-4": { 35 | "JDecool\\Clockify\\Tests\\": "tests" 36 | } 37 | }, 38 | "config": { 39 | "sort-packages": true, 40 | "allow-plugins": { 41 | "php-http/discovery": true 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Api/Client/Client.php: -------------------------------------------------------------------------------- 1 | http = $http; 20 | } 21 | 22 | /** 23 | * @return ClientDto[] 24 | */ 25 | public function clients(string $workspaceId, array $params = []): array 26 | { 27 | if (isset($params['name']) && empty($params['name'])) { 28 | throw new ClockifyException('Invalid "name" parameter'); 29 | } 30 | 31 | if (isset($params['page']) && (!is_int($params['page']) || $params['page'] < 1)) { 32 | throw new ClockifyException('Invalid "page" parameter'); 33 | } 34 | 35 | if (isset($params['page-size']) && (!is_int($params['page-size']) || $params['page-size'] < 1)) { 36 | throw new ClockifyException('Invalid "page-size" parameter'); 37 | } 38 | 39 | $data = $this->http->get("/workspaces/$workspaceId/clients", $params); 40 | 41 | return array_map( 42 | static function(array $client): ClientDto { 43 | return ClientDto::fromArray($client); 44 | }, 45 | $data 46 | ); 47 | } 48 | 49 | public function create(string $workspaceId, ClientRequest $request): ClientDto 50 | { 51 | $data = $this->http->post("/workspaces/$workspaceId/clients", $request->toArray()); 52 | 53 | return ClientDto::fromArray($data); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Api/Client/ClientRequest.php: -------------------------------------------------------------------------------- 1 | name = $name; 14 | } 15 | 16 | public function name(): string 17 | { 18 | return $this->name; 19 | } 20 | 21 | public function toArray(): array 22 | { 23 | return [ 24 | 'name' => $this->name, 25 | ]; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Api/Project/Project.php: -------------------------------------------------------------------------------- 1 | http = $http; 20 | } 21 | 22 | /** 23 | * @return ProjectDtoImpl[] 24 | */ 25 | public function projects(string $workspaceId, array $params = []): array 26 | { 27 | if (isset($params['name']) && empty($params['name'])) { 28 | throw new ClockifyException('Invalid "name" parameter'); 29 | } 30 | 31 | if (isset($params['page']) && (!is_int($params['page']) || $params['page'] < 1)) { 32 | throw new ClockifyException('Invalid "page" parameter'); 33 | } 34 | 35 | if (isset($params['page-size']) && (!is_int($params['page-size']) || $params['page-size'] < 1)) { 36 | throw new ClockifyException('Invalid "page-size" parameter'); 37 | } 38 | 39 | $data = $this->http->get("/workspaces/$workspaceId/projects", $params); 40 | 41 | return array_map( 42 | static function(array $project): ProjectDtoImpl { 43 | return ProjectDtoImpl::fromArray($project); 44 | }, 45 | $data 46 | ); 47 | } 48 | 49 | public function create(string $workspaceId, ProjectRequest $request): ProjectDtoImpl 50 | { 51 | $data = $this->http->post(" /workspaces/$workspaceId/projects", $request->toArray()); 52 | 53 | return ProjectDtoImpl::fromArray($data); 54 | } 55 | 56 | public function delete(string $workspaceId, string $projectId): void 57 | { 58 | $this->http->delete("/workspaces/$workspaceId/projects/$projectId"); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Api/Project/ProjectRequest.php: -------------------------------------------------------------------------------- 1 | http = $http; 20 | } 21 | 22 | /** 23 | * @return TagDto[] 24 | */ 25 | public function tags(string $workspaceId, array $params = []): array 26 | { 27 | if (isset($params['name']) && empty($params['name'])) { 28 | throw new ClockifyException('Invalid "name" parameter'); 29 | } 30 | 31 | if (isset($params['page']) && (!is_int($params['page']) || $params['page'] < 1)) { 32 | throw new ClockifyException('Invalid "page" parameter'); 33 | } 34 | 35 | if (isset($params['page-size']) && (!is_int($params['page-size']) || $params['page-size'] < 1)) { 36 | throw new ClockifyException('Invalid "page-size" parameter'); 37 | } 38 | 39 | $data = $this->http->get("/workspaces/$workspaceId/tags", $params); 40 | 41 | return array_map( 42 | static function(array $tag): TagDto { 43 | return TagDto::fromArray($tag); 44 | }, 45 | $data 46 | ); 47 | } 48 | 49 | public function create(string $workspaceId, TagRequest $request): TagDto 50 | { 51 | $data = $this->http->post("/workspaces/$workspaceId/tags", $request->toArray()); 52 | 53 | return TagDto::fromArray($data); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Api/Tag/TagRequest.php: -------------------------------------------------------------------------------- 1 | name = $name; 14 | } 15 | 16 | public function name(): string 17 | { 18 | return $this->name; 19 | } 20 | 21 | public function toArray(): array 22 | { 23 | return [ 24 | 'name' => $this->name, 25 | ]; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Api/Task/Task.php: -------------------------------------------------------------------------------- 1 | http = $http; 20 | } 21 | 22 | /** 23 | * @return TaskDto[] 24 | */ 25 | public function tasks(string $workspaceId, string $projectId, array $params = []): array 26 | { 27 | if (isset($params['is-active']) && !is_bool($params['is-active'])) { 28 | throw new ClockifyException('Invalid "is-active" parameter (should be a boolean value)'); 29 | } 30 | 31 | if (isset($params['name']) && empty($params['name'])) { 32 | throw new ClockifyException('Invalid "name" parameter'); 33 | } 34 | 35 | if (isset($params['page']) && (!is_int($params['page']) || $params['page'] < 1)) { 36 | throw new ClockifyException('Invalid "page" parameter'); 37 | } 38 | 39 | if (isset($params['page-size']) && (!is_int($params['page-size']) || $params['page-size'] < 1)) { 40 | throw new ClockifyException('Invalid "page-size" parameter'); 41 | } 42 | 43 | $data = $this->http->get("/workspaces/$workspaceId/projects/$projectId/tasks", $params); 44 | 45 | return array_map( 46 | static function(array $task): TaskDto { 47 | return TaskDto::fromArray($task); 48 | }, 49 | $data 50 | ); 51 | } 52 | 53 | public function create(string $workspaceId, string $projectId, TaskRequest $request): TaskDto 54 | { 55 | $data = $this->http->post("/workspaces/$workspaceId/projects/$projectId/tasks", $request->toArray()); 56 | 57 | return TaskDto::fromArray($data); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/Api/Task/TaskRequest.php: -------------------------------------------------------------------------------- 1 | id = $id; 18 | $this->name = $name; 19 | $this->assigneeId = $assigneeId; 20 | $this->estimate = $estimate; 21 | $this->status = $status; 22 | } 23 | 24 | public function id(): string 25 | { 26 | return $this->id; 27 | } 28 | 29 | public function name(): string 30 | { 31 | return $this->name; 32 | } 33 | 34 | public function assigneeId(): string 35 | { 36 | return $this->assigneeId; 37 | } 38 | 39 | public function estimate(): string 40 | { 41 | return $this->estimate; 42 | } 43 | 44 | public function status(): string 45 | { 46 | return $this->status; 47 | } 48 | 49 | public function toArray(): array 50 | { 51 | return [ 52 | 'id' => $this->id, 53 | 'name' => $this->name, 54 | 'assigneeId' => $this->assigneeId, 55 | 'estimate' => $this->estimate, 56 | 'status' => $this->status, 57 | ]; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/Api/TimeEntry/StopTimeEntryRequest.php: -------------------------------------------------------------------------------- 1 | end = $end; 14 | } 15 | 16 | public function end(): string 17 | { 18 | return $this->end; 19 | } 20 | 21 | public function toArray(): array 22 | { 23 | return [ 24 | 'end' => $this->end, 25 | ]; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Api/TimeEntry/TimeEntriesDurationRequest.php: -------------------------------------------------------------------------------- 1 | start = $start; 15 | $this->end = $end; 16 | } 17 | 18 | public function start(): string 19 | { 20 | return $this->start; 21 | } 22 | 23 | public function end(): string 24 | { 25 | return $this->end; 26 | } 27 | 28 | public function toArray(): array 29 | { 30 | return [ 31 | 'start' => $this->start, 32 | 'end' => $this->end, 33 | ]; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Api/TimeEntry/TimeEntry.php: -------------------------------------------------------------------------------- 1 | http = $http; 20 | } 21 | 22 | public function create(string $workspaceId, TimeEntryRequest $request): TimeEntryDtoImpl 23 | { 24 | $data = $this->http->post("/workspaces/$workspaceId/time-entries", $request->toArray()); 25 | 26 | return TimeEntryDtoImpl::fromArray($data); 27 | } 28 | 29 | public function createForUser(string $workspaceId, string $userId, TimeEntryRequest $request): TimeEntryDtoImpl 30 | { 31 | $data = $this->http->post("/workspaces/$workspaceId/user/$userId/time-entries", $request->toArray()); 32 | 33 | return TimeEntryDtoImpl::fromArray($data); 34 | } 35 | 36 | public function update(string $workspaceId, string $id, UpdateTimeEntryRequest $request): TimeEntryDtoImpl 37 | { 38 | $data = $this->http->put("/workspaces/$workspaceId/time-entries/$id", $request->toArray()); 39 | 40 | return TimeEntryDtoImpl::fromArray($data); 41 | } 42 | 43 | public function entry(string $workspaceId, string $id, array $params = []): TimeEntryDtoImpl 44 | { 45 | if (isset($params['consider-duration-format']) && !is_bool($params['consider-duration-format'])) { 46 | throw new ClockifyException('Invalid "consider-duration-format" parameter (should be a boolean value)'); 47 | } 48 | 49 | if (isset($params['hydrated']) && !is_bool($params['hydrated'])) { 50 | throw new ClockifyException('Invalid "hydrated" parameter (should be a boolean value)'); 51 | } 52 | 53 | $data = $this->http->get("/workspaces/$workspaceId/time-entries/$id", $params); 54 | 55 | return TimeEntryDtoImpl::fromArray($data); 56 | } 57 | 58 | public function delete(string $workspaceId, string $id): void 59 | { 60 | $this->http->delete("/workspaces/$workspaceId/time-entries/$id"); 61 | } 62 | 63 | public function stopRunningTime(string $workspaceId, string $userId, StopTimeEntryRequest $request): TimeEntryDtoImpl 64 | { 65 | $data = $this->http->patch("/workspaces/$workspaceId/user/$userId/time-entries", $request->toArray()); 66 | 67 | return TimeEntryDtoImpl::fromArray($data); 68 | } 69 | 70 | public function find(string $workspaceId, string $userId, array $params = []): array 71 | { 72 | if (isset($params['description']) && !is_string($params['description'])) { 73 | throw new ClockifyException('Invalid "description" parameter'); 74 | } 75 | 76 | if (isset($params['start']) && !is_string($params['start'])) { 77 | throw new ClockifyException('Invalid "start" parameter'); 78 | } 79 | 80 | if (isset($params['end']) && !is_string($params['end'])) { 81 | throw new ClockifyException('Invalid "end" parameter'); 82 | } 83 | 84 | if (isset($params['project']) && !is_string($params['project'])) { 85 | throw new ClockifyException('Invalid "project" parameter'); 86 | } 87 | 88 | if (isset($params['task']) && !is_string($params['task'])) { 89 | throw new ClockifyException('Invalid "task" parameter'); 90 | } 91 | 92 | if (isset($params['tags']) && !is_array($params['tags'])) { 93 | throw new ClockifyException('Invalid "tags" parameter'); 94 | } 95 | 96 | if (isset($params['project-required']) && !is_bool($params['project-required'])) { 97 | throw new ClockifyException('Invalid "project-required" parameter'); 98 | } 99 | 100 | if (isset($params['task-required']) && !is_bool($params['task-required'])) { 101 | throw new ClockifyException('Invalid "task-required" parameter'); 102 | } 103 | 104 | if (isset($params['consider-duration-format']) && !is_bool($params['consider-duration-format'])) { 105 | throw new ClockifyException('Invalid "consider-duration-format" parameter'); 106 | } 107 | 108 | if (isset($params['hydrated']) && !is_bool($params['hydrated'])) { 109 | throw new ClockifyException('Invalid "hydrated" parameter'); 110 | } 111 | 112 | if (isset($params['in-progress']) && !is_bool($params['in-progress'])) { 113 | throw new ClockifyException('Invalid "in-progress" parameter'); 114 | } 115 | 116 | if (isset($params['page']) && (!is_int($params['page']) || $params['page'] < 1)) { 117 | throw new ClockifyException('Invalid "page" parameter'); 118 | } 119 | 120 | if (isset($params['page-size']) && (!is_int($params['page-size']) || $params['page-size'] < 1)) { 121 | throw new ClockifyException('Invalid "page-size" parameter'); 122 | } 123 | 124 | $data = $this->http->get("/workspaces/$workspaceId/user/$userId/time-entries", $params); 125 | 126 | return array_map( 127 | static function(array $timeEntry): TimeEntryDtoImpl { 128 | return TimeEntryDtoImpl::fromArray($timeEntry); 129 | }, 130 | $data 131 | ); 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /src/Api/TimeEntry/TimeEntryRequest.php: -------------------------------------------------------------------------------- 1 | id = $id; 40 | $this->start = $start; 41 | $this->billable = $billable; 42 | $this->description = $description; 43 | $this->projectId = $projectId; 44 | $this->userId = $userId; 45 | $this->taskId = $taskId; 46 | $this->end = $end; 47 | $this->tagIds = $tagIds; 48 | $this->timeInterval = $timeInterval; 49 | $this->workspaceId = $workspaceId; 50 | $this->isLocked = $isLocked; 51 | } 52 | 53 | public function id(): string 54 | { 55 | return $this->id; 56 | } 57 | 58 | public function start(): string 59 | { 60 | return $this->start; 61 | } 62 | 63 | public function billable(): bool 64 | { 65 | return $this->billable; 66 | } 67 | 68 | public function description(): string 69 | { 70 | return $this->description; 71 | } 72 | 73 | public function projectId(): string 74 | { 75 | return $this->projectId; 76 | } 77 | 78 | public function userId(): string 79 | { 80 | return $this->userId; 81 | } 82 | 83 | public function taskId(): string 84 | { 85 | return $this->taskId; 86 | } 87 | 88 | public function end(): string 89 | { 90 | return $this->end; 91 | } 92 | 93 | /** 94 | * @return string[] 95 | */ 96 | public function tagIds(): array 97 | { 98 | return $this->tagIds; 99 | } 100 | 101 | public function timeInterval(): TimeEntriesDurationRequest 102 | { 103 | return $this->timeInterval; 104 | } 105 | 106 | public function workspaceId(): string 107 | { 108 | return $this->workspaceId; 109 | } 110 | 111 | public function isLocked(): bool 112 | { 113 | return $this->isLocked; 114 | } 115 | 116 | public function toArray(): array 117 | { 118 | return [ 119 | 'id' => $this->id, 120 | 'start' => $this->start, 121 | 'billable' => $this->billable, 122 | 'description' => $this->description, 123 | 'projectId' => $this->projectId, 124 | 'userId' => $this->userId, 125 | 'taskId' => $this->taskId, 126 | 'end' => $this->end, 127 | 'tagIds' => $this->tagIds, 128 | 'timeInterval' => $this->timeInterval->toArray(), 129 | 'workspaceId' => $this->workspaceId, 130 | 'isLocked' => $this->isLocked, 131 | ]; 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /src/Api/TimeEntry/UpdateTimeEntryRequest.php: -------------------------------------------------------------------------------- 1 | start = $start; 30 | $this->billable = $billable; 31 | $this->description = $description; 32 | $this->projectId = $projectId; 33 | $this->taskId = $taskId; 34 | $this->end = $end; 35 | $this->tagIds = $tagIds; 36 | } 37 | 38 | public function start(): string 39 | { 40 | return $this->start; 41 | } 42 | 43 | public function billable(): bool 44 | { 45 | return $this->billable; 46 | } 47 | 48 | public function description(): string 49 | { 50 | return $this->description; 51 | } 52 | 53 | public function projectId(): string 54 | { 55 | return $this->projectId; 56 | } 57 | 58 | public function taskId(): string 59 | { 60 | return $this->taskId; 61 | } 62 | 63 | public function end(): string 64 | { 65 | return $this->end; 66 | } 67 | 68 | /** 69 | * @return string[] 70 | */ 71 | public function tagIds(): array 72 | { 73 | return $this->tagIds; 74 | } 75 | 76 | public function toArray(): array 77 | { 78 | return [ 79 | 'start' => $this->start, 80 | 'billable' => $this->billable, 81 | 'description' => $this->description, 82 | 'projectId' => $this->projectId, 83 | 'taskId' => $this->taskId, 84 | 'end' => $this->end, 85 | 'tagIds' => $this->tagIds, 86 | ]; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/Api/User/User.php: -------------------------------------------------------------------------------- 1 | http = $http; 20 | } 21 | 22 | public function current(): CurrentUserDto 23 | { 24 | $data = $this->http->get("/user"); 25 | 26 | return CurrentUserDto::fromArray($data); 27 | } 28 | 29 | /** 30 | * @return UserDto[] 31 | */ 32 | public function workspaceUsers(string $workspaceId): array 33 | { 34 | $data = $this->http->get("/workspaces/$workspaceId/users"); 35 | return array_map( 36 | static function(array $user): UserDto { 37 | return UserDto::fromArray($user); 38 | }, 39 | $data 40 | ); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Api/Workspace/Workspace.php: -------------------------------------------------------------------------------- 1 | http = $http; 19 | } 20 | 21 | /** 22 | * @return WorkspaceDto[] 23 | */ 24 | public function workspaces(): array 25 | { 26 | $data = $this->http->get('/workspaces'); 27 | 28 | return array_map( 29 | static function(array $workspace): WorkspaceDto { 30 | return WorkspaceDto::fromArray($workspace); 31 | }, 32 | $data 33 | ); 34 | } 35 | 36 | public function create(WorkspaceRequest $request): WorkspaceDto 37 | { 38 | $data = $this->http->post('/workspaces', $request->toArray()); 39 | 40 | return WorkspaceDto::fromArray($data); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Api/Workspace/WorkspaceRequest.php: -------------------------------------------------------------------------------- 1 | name = $name; 14 | } 15 | 16 | public function name(): string 17 | { 18 | return $this->name; 19 | } 20 | 21 | public function toArray(): array 22 | { 23 | return [ 24 | 'name' => $this->name, 25 | ]; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/ApiFactory.php: -------------------------------------------------------------------------------- 1 | client = $client; 24 | } 25 | 26 | public function clientApi(): ClientApi 27 | { 28 | return new ClientApi($this->client); 29 | } 30 | 31 | public function projectApi(): Project 32 | { 33 | return new Project($this->client); 34 | } 35 | 36 | public function tagApi(): Tag 37 | { 38 | return new Tag($this->client); 39 | } 40 | 41 | public function taskApi(): Task 42 | { 43 | return new Task($this->client); 44 | } 45 | 46 | public function timeEntryApi(): TimeEntry 47 | { 48 | return new TimeEntry($this->client); 49 | } 50 | 51 | public function userApi(): User 52 | { 53 | return new User($this->client); 54 | } 55 | 56 | public function workspaceApi(): Workspace 57 | { 58 | return new Workspace($this->client); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Client.php: -------------------------------------------------------------------------------- 1 | http = $http; 24 | } 25 | 26 | public function get(string $uri, array $params = []): array 27 | { 28 | if (!empty($params)) { 29 | $uri .= '?'.http_build_query($params); 30 | } 31 | 32 | $response = $this->http->get($uri); 33 | 34 | if (200 !== $response->getStatusCode()) { 35 | throw $this->createExceptionFromResponse($response); 36 | } 37 | 38 | return json_decode($response->getBody()->getContents(), true, 512, JSON_THROW_ON_ERROR); 39 | } 40 | 41 | public function post(string $uri, array $data): array 42 | { 43 | $response = $this->http->post($uri, [], json_encode($data, JSON_THROW_ON_ERROR)); 44 | 45 | if (201 !== $response->getStatusCode()) { 46 | throw $this->createExceptionFromResponse($response); 47 | } 48 | 49 | return json_decode($response->getBody()->getContents(), true, 512, JSON_THROW_ON_ERROR); 50 | } 51 | 52 | public function put(string $uri, array $data): array 53 | { 54 | $response = $this->http->put($uri, [], json_encode($data, JSON_THROW_ON_ERROR)); 55 | 56 | if (!in_array($response->getStatusCode(), [200, 201], true)) { 57 | throw $this->createExceptionFromResponse($response); 58 | } 59 | 60 | return json_decode($response->getBody()->getContents(), true, 512, JSON_THROW_ON_ERROR); 61 | } 62 | 63 | public function patch(string $uri, array $data): array 64 | { 65 | $response = $this->http->patch($uri, [], json_encode($data, JSON_THROW_ON_ERROR)); 66 | 67 | if (!in_array($response->getStatusCode(), [200, 204], true)) { 68 | throw $this->createExceptionFromResponse($response); 69 | } 70 | 71 | return json_decode($response->getBody()->getContents(), true, 512, JSON_THROW_ON_ERROR); 72 | } 73 | 74 | public function delete(string $uri): void 75 | { 76 | $response = $this->http->delete($uri); 77 | 78 | if (204 !== $response->getStatusCode()) { 79 | throw $this->createExceptionFromResponse($response); 80 | } 81 | } 82 | 83 | private function createExceptionFromResponse(ResponseInterface $response): ClockifyException 84 | { 85 | $data = json_decode((string) $response->getBody(), true); 86 | $message = $data['message'] ?? ''; 87 | $code = $data['code'] ?? 0; 88 | 89 | switch ($response->getStatusCode()) { 90 | case 400: 91 | return new BadRequest($message, $code); 92 | 93 | case 401: 94 | return new Unauthorized($message, $code); 95 | 96 | case 403: 97 | return new Forbidden($message, $code); 98 | 99 | case 404: 100 | return new NotFound($message, $code); 101 | } 102 | 103 | return new ClockifyException($message, $code); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/ClientBuilder.php: -------------------------------------------------------------------------------- 1 | httpClient = $httpClient ?? Psr18ClientDiscovery::find(); 44 | $this->requestFactory = $requestFactory ?? Psr17FactoryDiscovery::findRequestFactory(); 45 | $this->uriFactory = $uriFactory ?? Psr17FactoryDiscovery::findUriFactory(); 46 | $this->streamFactory = $streamFactory ?? Psr17FactoryDiscovery::findStreamFactory(); 47 | } 48 | 49 | public function createClientV1(string $apiKey): Client 50 | { 51 | return $this->create(self::ENDPOINT_V1, $apiKey); 52 | } 53 | 54 | public function create(string $endpoint, string $apiKey): Client 55 | { 56 | if (false === filter_var($endpoint, FILTER_VALIDATE_URL)) { 57 | throw new RuntimeException('Invalid Clockify endpoint.'); 58 | } 59 | 60 | if ('' === trim($apiKey)) { 61 | throw new RuntimeException('API token is required.'); 62 | } 63 | 64 | $plugins = [ 65 | new AuthenticationPlugin( 66 | new Header('X-Api-Key', $apiKey), 67 | ), 68 | new AddHostPlugin( 69 | $this->uriFactory->createUri($endpoint), 70 | ), 71 | new AddPathPlugin( 72 | $this->uriFactory->createUri($endpoint), 73 | ), 74 | new HeaderSetPlugin([ 75 | 'User-Agent' => 'github.com/jdecool/clockify-api', 76 | 'Content-Type' => 'application/json', 77 | ]), 78 | ]; 79 | 80 | $http = new HttpMethodsClient( 81 | new PluginClient($this->httpClient, $plugins), 82 | $this->requestFactory, 83 | $this->streamFactory, 84 | ); 85 | 86 | return new Client($http); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/Exception/BadRequest.php: -------------------------------------------------------------------------------- 1 | changeDay = $changeDay; 37 | $this->dayOfMonth = $dayOfMonth; 38 | $this->firstDay = $firstDay; 39 | $this->olderThanPeriod = $olderThanPeriod; 40 | $this->olderThanValue = $olderThanValue; 41 | $this->type = $type; 42 | } 43 | 44 | public function changeDay(): DaysEnum 45 | { 46 | return $this->changeDay; 47 | } 48 | 49 | public function dayOfMonth(): int 50 | { 51 | return $this->dayOfMonth; 52 | } 53 | 54 | public function firstDay(): DaysEnum 55 | { 56 | return $this->firstDay; 57 | } 58 | 59 | public function olderThanPeriod(): PeriodEnum 60 | { 61 | return $this->olderThanPeriod; 62 | } 63 | 64 | public function olderThanValue(): int 65 | { 66 | return $this->olderThanValue; 67 | } 68 | 69 | public function type(): AutomaticLockEnum 70 | { 71 | return $this->type; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/Model/AutomaticLockEnum.php: -------------------------------------------------------------------------------- 1 | id = $id; 25 | $this->name = $name; 26 | $this->workspaceId = $workspaceId; 27 | } 28 | 29 | public function id(): string 30 | { 31 | return $this->id; 32 | } 33 | 34 | public function name(): string 35 | { 36 | return $this->name; 37 | } 38 | 39 | public function workspaceId(): string 40 | { 41 | return $this->workspaceId; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Model/CurrentUserDto.php: -------------------------------------------------------------------------------- 1 | activeWorkspace = $activeWorkspace; 54 | $this->defaultWorkspace = $defaultWorkspace; 55 | $this->email = $email; 56 | $this->id = $id; 57 | $this->memberships = $memberships; 58 | $this->name = $name; 59 | $this->profilePicture = $profilePicture; 60 | $this->settings = $settings; 61 | $this->status = $status; 62 | } 63 | 64 | public function activeWorkspace(): string 65 | { 66 | return $this->activeWorkspace; 67 | } 68 | 69 | public function defaultWorkspace(): string 70 | { 71 | return $this->defaultWorkspace; 72 | } 73 | 74 | public function email(): string 75 | { 76 | return $this->email; 77 | } 78 | 79 | public function id(): string 80 | { 81 | return $this->id; 82 | } 83 | 84 | /** 85 | * @return MembershipDto[] 86 | */ 87 | public function memberships(): array 88 | { 89 | return $this->memberships; 90 | } 91 | 92 | public function name(): string 93 | { 94 | return $this->name; 95 | } 96 | 97 | public function profilePicture(): string 98 | { 99 | return $this->profilePicture; 100 | } 101 | 102 | public function settings(): UserSettingsDto 103 | { 104 | return $this->settings; 105 | } 106 | 107 | public function status(): UserStatus 108 | { 109 | return $this->status; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/Model/DashboardSelection.php: -------------------------------------------------------------------------------- 1 | estimate = $estimate; 23 | $this->type = $type; 24 | } 25 | 26 | public function estimate(): string 27 | { 28 | return $this->estimate; 29 | } 30 | 31 | public function type(): EstimateType 32 | { 33 | return $this->type; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Model/EstimateType.php: -------------------------------------------------------------------------------- 1 | amount = $amount; 20 | $this->currency = $currency; 21 | } 22 | 23 | public function amount(): int 24 | { 25 | return $this->amount; 26 | } 27 | 28 | public function currency(): string 29 | { 30 | return $this->currency; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Model/MembershipDto.php: -------------------------------------------------------------------------------- 1 | hourlyRate = $hourlyRate; 34 | $this->membershipStatus = $membershipStatus; 35 | $this->membershipType = $membershipType; 36 | $this->targetId = $targetId; 37 | $this->userId = $userId; 38 | } 39 | 40 | public function hourlyRate(): ?HourlyRateDto 41 | { 42 | return $this->hourlyRate; 43 | } 44 | 45 | public function membershipStatus(): MembershipEnum 46 | { 47 | return $this->membershipStatus; 48 | } 49 | 50 | public function membershipType(): string 51 | { 52 | return $this->membershipType; 53 | } 54 | 55 | public function targetId(): string 56 | { 57 | return $this->targetId; 58 | } 59 | 60 | public function userId(): string 61 | { 62 | return $this->userId; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/Model/MembershipEnum.php: -------------------------------------------------------------------------------- 1 | archived = $archived; 66 | $this->billable = $billable; 67 | $this->clientId = $clientId; 68 | $this->clientName = $clientName; 69 | $this->color = $color; 70 | $this->duration = $duration; 71 | $this->estimate = $estimate; 72 | $this->hourlyRate = $hourlyRate; 73 | $this->id = $id; 74 | $this->memberships = $memberships; 75 | $this->name = $name; 76 | $this->public = $public; 77 | $this->workspaceId = $workspaceId; 78 | } 79 | 80 | public function archived(): bool 81 | { 82 | return $this->archived; 83 | } 84 | 85 | public function billable(): bool 86 | { 87 | return $this->billable; 88 | } 89 | 90 | public function clientId(): string 91 | { 92 | return $this->clientId; 93 | } 94 | 95 | public function clientName() 96 | { 97 | return $this->clientName; 98 | } 99 | 100 | public function color(): string 101 | { 102 | return $this->color; 103 | } 104 | 105 | public function duration(): string 106 | { 107 | return $this->duration; 108 | } 109 | 110 | public function estimate(): EstimateDto 111 | { 112 | return $this->estimate; 113 | } 114 | 115 | public function hourlyRate(): ?HourlyRateDto 116 | { 117 | return $this->hourlyRate; 118 | } 119 | 120 | public function id(): string 121 | { 122 | return $this->id; 123 | } 124 | 125 | /** 126 | * @return MembershipDto[] 127 | */ 128 | public function memberships(): array 129 | { 130 | return $this->memberships; 131 | } 132 | 133 | public function name(): string 134 | { 135 | return $this->name; 136 | } 137 | 138 | public function public(): bool 139 | { 140 | return $this->public; 141 | } 142 | 143 | public function workspaceId(): string 144 | { 145 | return $this->workspaceId; 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /src/Model/Round.php: -------------------------------------------------------------------------------- 1 | minutes = $minutes; 23 | $this->round = $round; 24 | } 25 | 26 | public function minutes(): string 27 | { 28 | return $this->minutes; 29 | } 30 | 31 | public function round(): string 32 | { 33 | return $this->round; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Model/SummaryReportSettingsDto.php: -------------------------------------------------------------------------------- 1 | group = $group; 23 | $this->subgroup = $subgroup; 24 | } 25 | 26 | public function group(): string 27 | { 28 | return $this->group; 29 | } 30 | 31 | public function subgroup(): string 32 | { 33 | return $this->subgroup; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Model/TagDto.php: -------------------------------------------------------------------------------- 1 | id = $id; 25 | $this->name = $name; 26 | $this->workspaceId = $workspaceId; 27 | } 28 | 29 | public function id(): string 30 | { 31 | return $this->id; 32 | } 33 | 34 | public function name(): string 35 | { 36 | return $this->name; 37 | } 38 | 39 | public function workspaceId(): string 40 | { 41 | return $this->workspaceId; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Model/TaskDto.php: -------------------------------------------------------------------------------- 1 | assigneeId = $assigneeId; 37 | $this->estimate = $estimate; 38 | $this->id = $id; 39 | $this->name = $name; 40 | $this->projectId = $projectId; 41 | $this->status = $status; 42 | } 43 | 44 | public function assigneeId(): string 45 | { 46 | return $this->assigneeId; 47 | } 48 | 49 | public function estimate(): string 50 | { 51 | return $this->estimate; 52 | } 53 | 54 | public function id(): string 55 | { 56 | return $this->id; 57 | } 58 | 59 | public function name(): string 60 | { 61 | return $this->name; 62 | } 63 | 64 | public function projectId(): string 65 | { 66 | return $this->projectId; 67 | } 68 | 69 | public function status(): TaskStatus 70 | { 71 | return $this->status; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/Model/TaskStatus.php: -------------------------------------------------------------------------------- 1 | billable = $billable; 52 | $this->description = $description; 53 | $this->id = $id; 54 | $this->isLocked = $isLocked; 55 | $this->projectId = $projectId; 56 | $this->tagIds = $tagIds; 57 | $this->taskId = $taskId; 58 | $this->timeInterval = $timeInterval; 59 | $this->userId = $userId; 60 | $this->workspaceId = $workspaceId; 61 | } 62 | 63 | public function billable(): bool 64 | { 65 | return $this->billable; 66 | } 67 | 68 | public function description(): string 69 | { 70 | return $this->description; 71 | } 72 | 73 | public function id(): string 74 | { 75 | return $this->id; 76 | } 77 | 78 | public function isLocked(): bool 79 | { 80 | return $this->isLocked; 81 | } 82 | 83 | public function projectId(): string 84 | { 85 | return $this->projectId; 86 | } 87 | 88 | /** 89 | * @return string[] 90 | */ 91 | public function tagIds() 92 | { 93 | return $this->tagIds; 94 | } 95 | 96 | public function taskId(): string 97 | { 98 | return $this->taskId; 99 | } 100 | 101 | public function timeInterval(): TimeIntervalDto 102 | { 103 | return $this->timeInterval; 104 | } 105 | 106 | public function userId(): string 107 | { 108 | return $this->userId; 109 | } 110 | 111 | public function workspaceId(): string 112 | { 113 | return $this->workspaceId; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/Model/TimeIntervalDto.php: -------------------------------------------------------------------------------- 1 | duration = $duration; 30 | $this->start = $start; 31 | $this->end = $end; 32 | } 33 | 34 | public function duration(): string 35 | { 36 | return $this->duration; 37 | } 38 | 39 | public function end(): ?DateTimeImmutable 40 | { 41 | return $this->end; 42 | } 43 | 44 | public function start(): DateTimeImmutable 45 | { 46 | return $this->start; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Model/UserDto.php: -------------------------------------------------------------------------------- 1 | activeWorkspace = $activeWorkspace; 54 | $this->defaultWorkspace = $defaultWorkspace; 55 | $this->email = $email; 56 | $this->id = $id; 57 | $this->memberships = $memberships; 58 | $this->name = $name; 59 | $this->profilePicture = $profilePicture; 60 | $this->settings = $settings; 61 | $this->status = $status; 62 | } 63 | 64 | public function activeWorkspace(): string 65 | { 66 | return $this->activeWorkspace; 67 | } 68 | 69 | public function defaultWorkspace(): string 70 | { 71 | return $this->defaultWorkspace; 72 | } 73 | 74 | public function email(): string 75 | { 76 | return $this->email; 77 | } 78 | 79 | public function id(): string 80 | { 81 | return $this->id; 82 | } 83 | 84 | /** 85 | * @return MembershipDto[] 86 | */ 87 | public function memberships(): array 88 | { 89 | return $this->memberships; 90 | } 91 | 92 | public function name(): string 93 | { 94 | return $this->name; 95 | } 96 | 97 | public function profilePicture(): string 98 | { 99 | return $this->profilePicture; 100 | } 101 | 102 | public function settings(): ?UserSettingsDto 103 | { 104 | return $this->settings; 105 | } 106 | 107 | public function status(): UserStatus 108 | { 109 | return $this->status; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/Model/UserSettingsDto.php: -------------------------------------------------------------------------------- 1 | collapseAllProjectLists = $collapseAllProjectLists; 64 | $this->dashboardPinToTop = $dashboardPinToTop; 65 | $this->dashboardSelection = $dashboardSelection; 66 | $this->dashboardViewType = $dashboardViewType; 67 | $this->dateFormat = $dateFormat; 68 | $this->isCompactViewOn = $isCompactViewOn; 69 | $this->longRunning = $longRunning; 70 | $this->projectListCollapse = $projectListCollapse; 71 | $this->sendNewsletter = $sendNewsletter; 72 | $this->summaryReportSettings = $summaryReportSettings; 73 | $this->timeFormat = $timeFormat; 74 | $this->timeTrackingManual = $timeTrackingManual; 75 | $this->timeZone = $timeZone; 76 | $this->weekStart = $weekStart; 77 | $this->weeklyUpdates = $weeklyUpdates; 78 | } 79 | 80 | public function collapseAllProjectLists(): bool 81 | { 82 | return $this->collapseAllProjectLists; 83 | } 84 | 85 | public function dashboardPinToTop(): bool 86 | { 87 | return $this->dashboardPinToTop; 88 | } 89 | 90 | public function dashboardSelection(): DashboardSelection 91 | { 92 | return $this->dashboardSelection; 93 | } 94 | 95 | public function dashboardViewType(): DashboardViewType 96 | { 97 | return $this->dashboardViewType; 98 | } 99 | 100 | public function dateFormat(): string 101 | { 102 | return $this->dateFormat; 103 | } 104 | 105 | public function isCompactViewOn(): bool 106 | { 107 | return $this->isCompactViewOn; 108 | } 109 | 110 | public function longRunning(): bool 111 | { 112 | return $this->longRunning; 113 | } 114 | 115 | public function projectListCollapse(): int 116 | { 117 | return $this->projectListCollapse; 118 | } 119 | 120 | public function sendNewsletter(): bool 121 | { 122 | return $this->sendNewsletter; 123 | } 124 | 125 | public function summaryReportSettings(): SummaryReportSettingsDto 126 | { 127 | return $this->summaryReportSettings; 128 | } 129 | 130 | public function timeFormat(): string 131 | { 132 | return $this->timeFormat; 133 | } 134 | 135 | public function timeTrackingManual(): bool 136 | { 137 | return $this->timeTrackingManual; 138 | } 139 | 140 | public function timeZone(): string 141 | { 142 | return $this->timeZone; 143 | } 144 | 145 | public function weekStart(): DaysEnum 146 | { 147 | return $this->weekStart; 148 | } 149 | 150 | public function weeklyUpdates(): bool 151 | { 152 | return $this->weeklyUpdates; 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /src/Model/UserStatus.php: -------------------------------------------------------------------------------- 1 | hourlyRate = $hourlyRate; 45 | $this->id = $id; 46 | $this->imageUrl = $imageUrl; 47 | $this->memberships = $memberships; 48 | $this->name = $name; 49 | $this->workspaceSettings = $workspaceSettings; 50 | } 51 | 52 | public function hourlyRate(): ?HourlyRateDto 53 | { 54 | return $this->hourlyRate; 55 | } 56 | 57 | public function id(): string 58 | { 59 | return $this->id; 60 | } 61 | 62 | public function imageUrl(): string 63 | { 64 | return $this->imageUrl; 65 | } 66 | 67 | /** 68 | * @return MembershipDto[] 69 | */ 70 | public function memberships() 71 | { 72 | return $this->memberships; 73 | } 74 | 75 | public function name(): string 76 | { 77 | return $this->name; 78 | } 79 | 80 | public function workspaceSettings(): WorkspaceSettingsDto 81 | { 82 | return $this->workspaceSettings; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/Model/WorkspaceSettingsDto.php: -------------------------------------------------------------------------------- 1 | adminOnlyPages = $adminOnlyPages; 90 | $this->automaticLock = $automaticLock; 91 | $this->canSeeTimeSheet = $canSeeTimeSheet; 92 | $this->defaultBillableProjects = $defaultBillableProjects; 93 | $this->forceDescription = $forceDescription; 94 | $this->forceProjects = $forceProjects; 95 | $this->forceTags = $forceTags; 96 | $this->forceTasks = $forceTasks; 97 | $this->lockTimeEntries = $lockTimeEntries; 98 | $this->onlyAdminsCreateProject = $onlyAdminsCreateProject; 99 | $this->onlyAdminsCreateTag = $onlyAdminsCreateTag; 100 | $this->onlyAdminsSeeAllTimeEntries = $onlyAdminsSeeAllTimeEntries; 101 | $this->onlyAdminsSeeBillableRates = $onlyAdminsSeeBillableRates; 102 | $this->onlyAdminsSeeDashboard = $onlyAdminsSeeDashboard; 103 | $this->onlyAdminsSeePublicProjectsEntries = $onlyAdminsSeePublicProjectsEntries; 104 | $this->projectFavorites = $projectFavorites; 105 | $this->projectGroupingLabel = $projectGroupingLabel; 106 | $this->projectPickerSpecialFilter = $projectPickerSpecialFilter; 107 | $this->round = $round; 108 | $this->timeRoundingInReports = $timeRoundingInReports; 109 | $this->trackTimeDownToSecond = $trackTimeDownToSecond; 110 | } 111 | 112 | /** 113 | * @return PagesEnum[] 114 | */ 115 | public function adminOnlyPages(): array 116 | { 117 | return $this->adminOnlyPages; 118 | } 119 | 120 | public function automaticLock(): ?AutomaticLockDto 121 | { 122 | return $this->automaticLock; 123 | } 124 | 125 | public function canSeeTimeSheet(): bool 126 | { 127 | return $this->canSeeTimeSheet; 128 | } 129 | 130 | public function defaultBillableProjects(): bool 131 | { 132 | return $this->defaultBillableProjects; 133 | } 134 | 135 | public function forceDescription(): bool 136 | { 137 | return $this->forceDescription; 138 | } 139 | 140 | public function forceProjects(): bool 141 | { 142 | return $this->forceProjects; 143 | } 144 | 145 | public function forceTags(): bool 146 | { 147 | return $this->forceTags; 148 | } 149 | 150 | public function forceTasks(): bool 151 | { 152 | return $this->forceTasks; 153 | } 154 | 155 | public function lockTimeEntries(): ?string 156 | { 157 | return $this->lockTimeEntries; 158 | } 159 | 160 | public function onlyAdminsCreateProject(): bool 161 | { 162 | return $this->onlyAdminsCreateProject; 163 | } 164 | 165 | public function onlyAdminsCreateTag(): bool 166 | { 167 | return $this->onlyAdminsCreateTag; 168 | } 169 | 170 | public function onlyAdminsSeeAllTimeEntries(): bool 171 | { 172 | return $this->onlyAdminsSeeAllTimeEntries; 173 | } 174 | 175 | public function onlyAdminsSeeBillableRates(): bool 176 | { 177 | return $this->onlyAdminsSeeBillableRates; 178 | } 179 | 180 | public function onlyAdminsSeeDashboard(): bool 181 | { 182 | return $this->onlyAdminsSeeDashboard; 183 | } 184 | 185 | public function onlyAdminsSeePublicProjectsEntries(): bool 186 | { 187 | return $this->onlyAdminsSeePublicProjectsEntries; 188 | } 189 | 190 | public function projectFavorites(): bool 191 | { 192 | return $this->projectFavorites; 193 | } 194 | 195 | public function projectGroupingLabel(): string 196 | { 197 | return $this->projectGroupingLabel; 198 | } 199 | 200 | public function projectPickerSpecialFilter(): bool 201 | { 202 | return $this->projectPickerSpecialFilter; 203 | } 204 | 205 | public function round(): Round 206 | { 207 | return $this->round; 208 | } 209 | 210 | public function timeRoundingInReports(): bool 211 | { 212 | return $this->timeRoundingInReports; 213 | } 214 | 215 | public function trackTimeDownToSecond(): bool 216 | { 217 | return $this->trackTimeDownToSecond; 218 | } 219 | } 220 | --------------------------------------------------------------------------------