├── .env.example ├── .gitignore ├── .scrutinizer.yml ├── .styleci.yml ├── .travis.yml ├── LICENSE ├── README.md ├── apiary.apib ├── composer.json ├── phpstan-baseline.neon ├── phpstan.neon.dist ├── phpunit.xml ├── src ├── AssigneeTypeEnum.php ├── Attachment │ └── AttachmentService.php ├── Auth │ ├── AuthService.php │ ├── AuthSession.php │ ├── CurrentUser.php │ ├── LoginInfo.php │ └── SessionInfo.php ├── Board │ ├── Board.php │ ├── BoardService.php │ ├── Location.php │ └── PaginatedResult.php ├── ClassSerialize.php ├── Component │ ├── Component.php │ └── ComponentService.php ├── Configuration │ ├── AbstractConfiguration.php │ ├── ArrayConfiguration.php │ ├── ConfigurationInterface.php │ └── DotEnvConfiguration.php ├── Dumper.php ├── Epic │ ├── Epic.php │ ├── EpicColor.php │ └── EpicService.php ├── Field │ ├── Field.php │ ├── FieldService.php │ └── Schema.php ├── GreenHopperTrait.php ├── Group │ ├── Group.php │ ├── GroupSearchResult.php │ ├── GroupService.php │ └── GroupUser.php ├── Issue │ ├── AgileIssue.php │ ├── AgileIssueFields.php │ ├── AgileIssueService.php │ ├── Attachment.php │ ├── ChangeLog.php │ ├── Comment.php │ ├── Comments.php │ ├── Component.php │ ├── ContentField.php │ ├── CustomField.php │ ├── CustomFieldSearchResult.php │ ├── CustomFieldUsage.php │ ├── History.php │ ├── Issue.php │ ├── IssueBulkResult.php │ ├── IssueField.php │ ├── IssueSearchResult.php │ ├── IssueService.php │ ├── IssueStatus.php │ ├── IssueType.php │ ├── JQLCountResult.php │ ├── JqlFunction.php │ ├── JqlQuery.php │ ├── Notify.php │ ├── PaginatedWorklog.php │ ├── Priority.php │ ├── Property.php │ ├── RemoteIssueLink.php │ ├── RemoteIssueLinkObject.php │ ├── Reporter.php │ ├── SecurityScheme.php │ ├── Statuscategory.php │ ├── TimeTracking.php │ ├── Transition.php │ ├── TransitionTo.php │ ├── Version.php │ ├── VersionIssueCounts.php │ ├── VersionUnresolvedCount.php │ ├── Visibility.php │ ├── VisibilityTrait.php │ └── Worklog.php ├── IssueLink │ ├── IssueLink.php │ ├── IssueLinkService.php │ └── IssueLinkType.php ├── IssueType │ └── IssueTypeService.php ├── JiraClient.php ├── JiraException.php ├── JiraRestApiServiceProvider.php ├── JsonMapperHelper.php ├── JsonSerializableTrait.php ├── NoOperationMonologHandler.php ├── NoOperationMonologHandlerV3.php ├── Priority │ └── PriorityService.php ├── Project │ ├── Component.php │ ├── Project.php │ ├── ProjectService.php │ └── ProjectType.php ├── RapidCharts │ └── ScopeChangeBurnDownChartService.php ├── Request │ ├── Author.php │ ├── RequestComment.php │ └── RequestService.php ├── ServiceDesk │ ├── Attachment │ │ └── AttachmentService.php │ ├── Comment │ │ ├── Comment.php │ │ └── CommentService.php │ ├── Customer │ │ ├── Customer.php │ │ ├── CustomerLinks.php │ │ └── CustomerService.php │ ├── DataObjectTrait.php │ ├── Organisation │ │ ├── Organisation.php │ │ └── OrganisationService.php │ ├── Participant │ │ └── ParticipantService.php │ ├── Request │ │ ├── Request.php │ │ ├── RequestService.php │ │ └── RequestStatus.php │ └── ServiceDeskClient.php ├── ServiceDeskTrait.php ├── Sprint │ ├── Sprint.php │ ├── SprintSearchResult.php │ └── SprintService.php ├── Status │ ├── Status.php │ └── StatusService.php ├── StatusCategory │ └── StatusCategoryService.php ├── User │ ├── User.php │ └── UserService.php └── Version │ └── VersionService.php ├── test-data ├── comment.json ├── issue.json ├── issueField.json ├── issueFieldV3.json └── reporter-no-email-address.json └── tests ├── AssigneeTest.php ├── AttachmentTest.php ├── BoardTest.php ├── ComponentTest.php ├── CurlTest.php ├── CustomFieldsTest.php ├── EpicTest.php ├── GroupTest.php ├── IssueSecuritySechemTest.php ├── IssueTest.php ├── MapperTest.php ├── PriorityTest.php ├── ProjectTest.php ├── RemoteIssueLinkTest.php ├── SPrintTest.php ├── SearchTest.php ├── SerializeTest.php ├── ServiceDesk ├── Attachment │ └── AttachmentServiceTest.php ├── Comment │ ├── CommentServiceTest.php │ └── CommentTest.php ├── Customer │ ├── CustomerServiceTest.php │ └── CustomerTest.php ├── Organisation │ ├── OrganisationServiceTest.php │ └── OrganisationTest.php ├── Participant │ └── ParticipantServiceTest.php ├── Request │ ├── RequestServiceTest.php │ ├── RequestStatusTest.php │ └── RequestTest.php └── ServiceDeskClientTest.php ├── StatusTest.php ├── SubTaskTest.php ├── TimeTrackingTest.php ├── UserTest.php ├── VersionTest.php ├── WatcherLogTest.php └── WorkLogTest.php /.env.example: -------------------------------------------------------------------------------- 1 | JIRA_HOST="https://your-jira.host.com" 2 | JIRA_USER="jira-username" 3 | JIRA_PASS="jira-password" 4 | JIRA_LOG_ENABLED=true 5 | JIRA_LOG_FILE="jira-rest-client.log" 6 | JIRA_LOG_LEVEL="WARNING" 7 | 8 | ### if TOKEN_BASED_AUTH set to true, ignore JIRA_USER and JIRA_PASS. 9 | TOKEN_BASED_AUTH=true 10 | PERSONAL_ACCESS_TOKEN="your-access-token-here" 11 | 12 | ### to enable session cookie authorization 13 | # COOKIE_AUTH_ENABLED=true 14 | # COOKIE_FILE=storage/jira-cookie.txt 15 | ### if you are behind a proxy, add proxy settings 16 | # PROXY_SERVER="your-proxy-server" 17 | # PROXY_PORT="proxy-port" 18 | # PROXY_USER="proxy-username" 19 | # PROXY_PASSWORD="proxy-password" 20 | 21 | #CURLOPT_SSL_VERIFYHOST=false 22 | #CURLOPT_SSL_VERIFYPEER=false -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io 2 | 3 | ### Composer ### 4 | composer.phar 5 | vendor/ 6 | 7 | # Commit your application's lock file http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file 8 | # You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file 9 | # composer.lock 10 | 11 | 12 | ### Editor (Vim, PhpStorm) ### 13 | [._]*.s[a-w][a-z] 14 | [._]s[a-w][a-z] 15 | *.un~ 16 | Session.vim 17 | .netrwhist 18 | *~ 19 | .idea/ 20 | 21 | composer.lock 22 | config.php 23 | config.jira.json 24 | jira-rest-client.log 25 | screen_capture.png 26 | bug-description.pdf 27 | 28 | .env 29 | 30 | # Ignore Vagrant Stuff 31 | .vagrant 32 | Vagrantfile 33 | # Ignore scotch.io box and the folders of them 34 | public/ 35 | storage/ 36 | 37 | .phpunit.result.cache 38 | .env* 39 | .php_cs.cache 40 | -------------------------------------------------------------------------------- /.scrutinizer.yml: -------------------------------------------------------------------------------- 1 | filter: 2 | excluded_paths: 3 | - 'tests/*' 4 | tools: 5 | php_code_sniffer: 6 | config: 7 | standard: "PSR2" -------------------------------------------------------------------------------- /.styleci.yml: -------------------------------------------------------------------------------- 1 | preset: recommended 2 | disabled: 3 | # - self_accessor 4 | 5 | finder: 6 | exclude: 7 | - "tests" 8 | name: 9 | - "*.php" 10 | not-name: 11 | - "*Stub.php" 12 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 8.0 5 | - 8.1 6 | 7 | before_install: 8 | - travis_retry composer self-update 9 | - travis_retry composer update --no-interaction --prefer-dist 10 | 11 | before_script: 12 | - cp .env.example .env 13 | 14 | script: 15 | - ./vendor/bin/phpunit --verbose tests/SerializeTest 16 | - ./vendor/bin/phpunit --verbose tests/MapperTest 17 | 18 | jobs: 19 | include: 20 | - php: 8.0 21 | env: TYPE=phpstan 22 | script: 23 | - ./vendor/bin/phpstan analyse 24 | - php: 8.1 25 | env: TYPE=phpstan 26 | script: 27 | - ./vendor/bin/phpstan analyse 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 KwangSeob Jeong(lesstif@gmail.com) 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /apiary.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | HOST: http://polls.apiblueprint.org/ 3 | 4 | # jira 5 | 6 | Polls is a simple API allowing consumers to view polls and vote in them. 7 | 8 | ## Questions Collection [/questions] 9 | 10 | ### List All Questions [GET] 11 | 12 | + Response 200 (application/json) 13 | 14 | [ 15 | { 16 | "question": "Favourite programming language?", 17 | "published_at": "2015-08-05T08:40:51.620Z", 18 | "choices": [ 19 | { 20 | "choice": "Swift", 21 | "votes": 2048 22 | }, { 23 | "choice": "Python", 24 | "votes": 1024 25 | }, { 26 | "choice": "Objective-C", 27 | "votes": 512 28 | }, { 29 | "choice": "Ruby", 30 | "votes": 256 31 | } 32 | ] 33 | } 34 | ] 35 | 36 | ### Create a New Question [POST] 37 | 38 | You may create your own question using this action. It takes a JSON 39 | object containing a question and a collection of answers in the 40 | form of choices. 41 | 42 | + Request (application/json) 43 | 44 | { 45 | "question": "Favourite programming language?", 46 | "choices": [ 47 | "Swift", 48 | "Python", 49 | "Objective-C", 50 | "Ruby" 51 | ] 52 | } 53 | 54 | + Response 201 (application/json) 55 | 56 | + Headers 57 | 58 | Location: /questions/2 59 | 60 | + Body 61 | 62 | { 63 | "question": "Favourite programming language?", 64 | "published_at": "2015-08-05T08:40:51.620Z", 65 | "choices": [ 66 | { 67 | "choice": "Swift", 68 | "votes": 0 69 | }, { 70 | "choice": "Python", 71 | "votes": 0 72 | }, { 73 | "choice": "Objective-C", 74 | "votes": 0 75 | }, { 76 | "choice": "Ruby", 77 | "votes": 0 78 | } 79 | ] 80 | } -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lesstif/php-jira-rest-client", 3 | "description": "JIRA REST API Client for PHP Users.", 4 | "type": "library", 5 | "keywords": ["jira", "rest", "jira-php", "jira-rest"], 6 | "require": { 7 | "php": "^8.0", 8 | "ext-curl": "*", 9 | "ext-json": "*", 10 | "netresearch/jsonmapper": "^4.2|^5.0", 11 | "monolog/monolog": "^2.0|^3.0", 12 | "vlucas/phpdotenv": "^5.0|^6.0" 13 | }, 14 | "require-dev": { 15 | "phpunit/phpunit": "^9.0|^10.0", 16 | "mockery/mockery": "^1.0|^2.0", 17 | "symfony/var-dumper": "^5.0|^6.0|^7.0", 18 | "phpstan/phpstan": "^1.0|^2.0" 19 | }, 20 | "license": "Apache-2.0", 21 | "authors": [ 22 | { 23 | "name": "KwangSeob Jeong", 24 | "email": "lesstif@gmail.com", 25 | "homepage": "https://lesstif.com/" 26 | } 27 | ], 28 | "autoload": { 29 | "psr-4" : { 30 | "JiraRestApi\\" : "src" 31 | } 32 | }, 33 | "autoload-dev": { 34 | "psr-4" : { 35 | "JiraRestApi\\Test\\" : "tests" 36 | } 37 | }, 38 | "extra": { 39 | "laravel": { 40 | "providers": [ 41 | "JiraRestApi\\JiraRestApiServiceProvider" 42 | ] 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /phpstan-baseline.neon: -------------------------------------------------------------------------------- 1 | parameters: 2 | ignoreErrors: 3 | - 4 | message: "#^Property JiraRestApi\\\\Issue\\\\IssueField::\\$duedate \\(DateTimeInterface|null\\) does not accept string\\.$#" 5 | count: 1 6 | path: src/Issue/IssueField.php 7 | - 8 | message: "#^Property JiraRestApi\\\\Issue\\\\Version::\\$releaseDate \\(DateTimeInterface|null\\) does not accept string\\.$#" 9 | count: 1 10 | path: src/Version/VersionService.php 11 | - 12 | message: "#^Property JiraRestApi\\\\JiraClient::\\$log \\(Monolog\\\\Logger\\) does not accept Psr\\\\Log\\\\LoggerInterface\\.$#" 13 | count: 1 14 | path: src/JiraClient.php 15 | - 16 | message: "#^Property JiraRestApi\\\\Issue\\\\RemoteIssueLink::\\$object \\(JiraRestApi\\\\Issue\\\\RemoteIssueLinkObject|null\\) does not accept JiraRestApi\\\\Issue\\\\RemoteIssueLink\\.$#" 17 | count: 1 18 | path: src/Issue/RemoteIssueLink.php 19 | - 20 | message: "#^Call to function is_.+ with .+ will always evaluate to false\\.$#" 21 | path: src 22 | 23 | - 24 | message: "#expects Curl.*?Handle, resource given#" 25 | path: src/JiraClient.php 26 | 27 | - 28 | message: "#\\(resource\\) does not accept CurlHandle#" 29 | path: src/JiraClient.php -------------------------------------------------------------------------------- /phpstan.neon.dist: -------------------------------------------------------------------------------- 1 | includes: 2 | - phpstan-baseline.neon 3 | 4 | parameters: 5 | level: 5 6 | paths: 7 | - src 8 | excludes_analyse: 9 | - src/JiraRestApiServiceProvider.php 10 | reportUnmatchedIgnoredErrors: false 11 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | src/ 6 | 7 | 8 | 9 | 10 | tests/ 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/AssigneeTypeEnum.php: -------------------------------------------------------------------------------- 1 | 'PROJECT_LEAD', 15 | AssigneeTypeEnum::COMPONENT_LEAD => 'COMPONENT_LEAD', 16 | AssigneeTypeEnum::UNASSIGNED => 'UNASSIGNED', 17 | }; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Attachment/AttachmentService.php: -------------------------------------------------------------------------------- 1 | exec($this->uri.$id, null); 35 | 36 | $this->log->info("Result=\n".$ret); 37 | 38 | $attachment = $this->json_mapper->map( 39 | json_decode($ret), 40 | new Attachment() 41 | ); 42 | 43 | if ($outDir == null) { 44 | return $attachment; 45 | } 46 | 47 | // download contents 48 | if (!file_exists($outDir)) { 49 | mkdir($outDir, $mode, $recursive); 50 | } 51 | 52 | // extract filename 53 | $file = substr(strrchr($attachment->content, '/'), 1); 54 | 55 | if (file_exists($outDir.DIRECTORY_SEPARATOR.$file) && $overwrite == false) { 56 | return $attachment; 57 | } 58 | 59 | $this->download($attachment->content, $outDir, $file); 60 | 61 | return $attachment; 62 | } 63 | 64 | /** 65 | * Remove an attachment from an issue. 66 | * 67 | * @param string|int $id attachment id 68 | * 69 | * @throws \JiraRestApi\JiraException 70 | * 71 | * @return string 72 | */ 73 | public function remove($id) 74 | { 75 | $ret = $this->exec($this->uri.$id, null, 'DELETE'); 76 | 77 | $this->log->info("Result=\n".$ret); 78 | 79 | return $ret; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/Auth/AuthSession.php: -------------------------------------------------------------------------------- 1 | id; 36 | } 37 | 38 | /** 39 | * Get board url. 40 | */ 41 | public function getSelf() 42 | { 43 | return $this->self; 44 | } 45 | 46 | /** 47 | * Get board name. 48 | */ 49 | public function getName() 50 | { 51 | return $this->name; 52 | } 53 | 54 | /** 55 | * Get board type. 56 | */ 57 | public function getType() 58 | { 59 | return $this->type; 60 | } 61 | 62 | /** 63 | * Get location. 64 | */ 65 | public function getLocation() 66 | { 67 | return $this->location; 68 | } 69 | 70 | #[\ReturnTypeWillChange] 71 | public function jsonSerialize(): array 72 | { 73 | return array_filter(get_object_vars($this), function ($var) { 74 | return !is_null($var); 75 | }); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/Board/Location.php: -------------------------------------------------------------------------------- 1 | projectId; 34 | } 35 | 36 | /** 37 | * Get project id. 38 | */ 39 | public function getDisplayName() 40 | { 41 | return $this->displayName; 42 | } 43 | 44 | /** 45 | * Get project name. 46 | */ 47 | public function getProjectName() 48 | { 49 | return $this->projectName; 50 | } 51 | 52 | /** 53 | * Get project key. 54 | */ 55 | public function getProjectKey() 56 | { 57 | return $this->projectKey; 58 | } 59 | 60 | /** 61 | * Get project type key. 62 | */ 63 | public function getProjectTypeKey() 64 | { 65 | return $this->projectTypeKey; 66 | } 67 | 68 | /** 69 | * Get avatar uri. 70 | */ 71 | public function getAvatarUri() 72 | { 73 | return $this->avatarUri; 74 | } 75 | 76 | /** 77 | * Get name. 78 | */ 79 | public function getName() 80 | { 81 | return $this->name; 82 | } 83 | 84 | /** 85 | * {@inheritdoc} 86 | */ 87 | #[\ReturnTypeWillChange] 88 | public function jsonSerialize(): array 89 | { 90 | return array_filter(get_object_vars($this), function ($var) { 91 | return !is_null($var); 92 | }); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/Board/PaginatedResult.php: -------------------------------------------------------------------------------- 1 | startAt; 46 | } 47 | 48 | /** 49 | * @param int $startAt 50 | */ 51 | public function setStartAt($startAt) 52 | { 53 | $this->startAt = $startAt; 54 | } 55 | 56 | /** 57 | * @return int 58 | */ 59 | public function getMaxResults() 60 | { 61 | return $this->maxResults; 62 | } 63 | 64 | /** 65 | * @param int $maxResults 66 | */ 67 | public function setMaxResults($maxResults) 68 | { 69 | $this->maxResults = $maxResults; 70 | } 71 | 72 | /** 73 | * @return int 74 | */ 75 | public function getTotal() 76 | { 77 | return $this->total; 78 | } 79 | 80 | /** 81 | * @param int $total 82 | */ 83 | public function setTotal($total) 84 | { 85 | $this->total = $total; 86 | } 87 | 88 | /** 89 | * @return array 90 | */ 91 | public function getValues() 92 | { 93 | return $this->values; 94 | } 95 | 96 | /** 97 | * @param array $values 98 | */ 99 | public function setValues($values) 100 | { 101 | $this->values = $values; 102 | } 103 | 104 | /** 105 | * @param int $index 106 | * 107 | * @return mixed 108 | */ 109 | public function getValue($index) 110 | { 111 | return $this->values[$index]; 112 | } 113 | 114 | /** 115 | * @return string 116 | */ 117 | public function getExpand() 118 | { 119 | return $this->expand; 120 | } 121 | 122 | /** 123 | * @param string $expand 124 | */ 125 | public function setExpand($expand) 126 | { 127 | $this->expand = $expand; 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /src/ClassSerialize.php: -------------------------------------------------------------------------------- 1 | $value) { 21 | if ($excludeMode === true) { 22 | if (!in_array($key, $ignoreProperties)) { 23 | $retAr[$key] = $value; 24 | } 25 | } else { // include mode 26 | if (in_array($key, $ignoreProperties)) { 27 | $retAr[$key] = $value; 28 | } 29 | } 30 | } 31 | 32 | return $retAr; 33 | } 34 | 35 | /** 36 | * class property to String. 37 | * 38 | * @param array $ignoreProperties this properties to be excluded from String. 39 | * @param bool $excludeMode 40 | * 41 | * @return string 42 | */ 43 | public function toString(array $ignoreProperties = [], bool $excludeMode = true): string 44 | { 45 | $ar = $this->toArray($ignoreProperties, $excludeMode); 46 | 47 | return json_encode($ar, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Component/Component.php: -------------------------------------------------------------------------------- 1 | name; 43 | } 44 | 45 | public function setName(string $name): static 46 | { 47 | $this->name = $name; 48 | 49 | return $this; 50 | } 51 | 52 | public function setDescription($description): static 53 | { 54 | $this->description = $description; 55 | 56 | return $this; 57 | } 58 | 59 | public function setLeadUserName(string $leadUserName): static 60 | { 61 | $this->leadUserName = $leadUserName; 62 | 63 | return $this; 64 | } 65 | 66 | public function setAssigneeType(string $assigneeType): static 67 | { 68 | $this->assigneeType = $assigneeType; 69 | 70 | return $this; 71 | } 72 | 73 | public function setAssigneeTypeAsEnum(AssigneeTypeEnum $assigneeType): static 74 | { 75 | $this->assigneeType = $assigneeType->type(); 76 | 77 | return $this; 78 | } 79 | 80 | public function setProjectKey(string $projectKey): static 81 | { 82 | $this->project = $projectKey; 83 | 84 | return $this; 85 | } 86 | 87 | public function setProject(string $project): static 88 | { 89 | $this->project = $project; 90 | 91 | return $this; 92 | } 93 | 94 | #[\ReturnTypeWillChange] 95 | public function jsonSerialize(): array 96 | { 97 | return array_filter(get_object_vars($this), function ($var) { 98 | return !is_null($var); 99 | }); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/Component/ComponentService.php: -------------------------------------------------------------------------------- 1 | log->info("Create Component=\n".$data); 26 | 27 | $ret = $this->exec($this->uri, $data, 'POST'); 28 | 29 | return $this->json_mapper->map( 30 | json_decode($ret), 31 | new Component() 32 | ); 33 | } 34 | 35 | /** 36 | * get component. 37 | * 38 | * @param string|int $id component id 39 | * 40 | * @return Component 41 | */ 42 | public function get($id) 43 | { 44 | $ret = $this->exec($this->uri.'/'.$id); 45 | 46 | $this->log->info('Result='.$ret); 47 | 48 | return $this->json_mapper->map( 49 | json_decode($ret), 50 | new Component() 51 | ); 52 | } 53 | 54 | /** 55 | * @param Component $component 56 | * 57 | * @throws JiraException 58 | * 59 | * @return Component 60 | */ 61 | public function update(Component $component) 62 | { 63 | if (!$component->id || !is_numeric($component->id)) { 64 | throw new JiraException($component->id.' is not a valid component id.'); 65 | } 66 | 67 | $data = json_encode($component); 68 | $ret = $this->exec($this->uri.'/'.$component->id, $data, 'PUT'); 69 | 70 | return $this->json_mapper->map( 71 | json_decode($ret), 72 | new Component() 73 | ); 74 | } 75 | 76 | /** 77 | * @param Component $component 78 | * @param Component|false $moveIssuesTo 79 | * 80 | * @throws JiraException 81 | * 82 | * @return string 83 | */ 84 | public function delete(Component $component, $moveIssuesTo = false) 85 | { 86 | if (!$component->id || !is_numeric($component->id)) { 87 | throw new JiraException($component->id.' is not a valid component id.'); 88 | } 89 | 90 | $data = []; 91 | $paramArray = []; 92 | 93 | if ($moveIssuesTo && $moveIssuesTo instanceof Component) { 94 | $paramArray['moveIssuesTo'] = $moveIssuesTo->id; 95 | } 96 | 97 | $ret = $this->exec($this->uri.'/'.$component->id.$this->toHttpQueryParameter($paramArray), json_encode($data), 'DELETE'); 98 | 99 | return $ret; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/Configuration/ArrayConfiguration.php: -------------------------------------------------------------------------------- 1 | jiraLogEnabled = true; 20 | $this->jiraLogFile = 'jira-rest-client.log'; 21 | $this->jiraLogLevel = 'WARNING'; 22 | $this->curlOptSslVerifyHost = false; 23 | $this->curlOptSslVerifyPeer = false; 24 | $this->curlOptSslCert = ''; 25 | $this->curlOptSslCertPassword = ''; 26 | $this->curlOptSslKey = ''; 27 | $this->curlOptSslKeyPassword = ''; 28 | $this->curlOptVerbose = false; 29 | $this->cookieAuthEnabled = false; 30 | $this->cookieFile = 'jira-cookie.txt'; 31 | $this->curlOptUserAgent = $this->getDefaultUserAgentString(); 32 | $this->serviceDeskId = null; 33 | 34 | $this->useTokenBasedAuth = false; 35 | $this->personalAccessToken = ''; 36 | 37 | foreach ($configuration as $key => $value) { 38 | if (property_exists($this, $key)) { 39 | $this->$key = $value; 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Configuration/ConfigurationInterface.php: -------------------------------------------------------------------------------- 1 | dump((new VarCloner())->cloneVar($value)); 21 | } else { 22 | var_dump($value); 23 | } 24 | } 25 | 26 | public static function dd($x) 27 | { 28 | array_map(function ($x) { 29 | (new self())->dump($x); 30 | }, func_get_args()); 31 | exit(1); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Epic/Epic.php: -------------------------------------------------------------------------------- 1 | setAPIUri('/rest/agile/'.$this->version); 18 | } 19 | 20 | public function getEpic($id, $paramArray = []): ?Epic 21 | { 22 | $response = $this->exec($this->uri.'/'.$id.$this->toHttpQueryParameter($paramArray), null); 23 | 24 | try { 25 | return $this->json_mapper->map( 26 | json_decode($response, false, 512, $this->getJsonOptions()), 27 | new Epic() 28 | ); 29 | } catch (\JsonException $exception) { 30 | $this->log->error("Response cannot be decoded from json\nException: {$exception->getMessage()}"); 31 | 32 | return null; 33 | } 34 | } 35 | 36 | /** 37 | * @return \ArrayObject|AgileIssue[]|null 38 | */ 39 | public function getEpicIssues($id, $paramArray = []): ?\ArrayObject 40 | { 41 | $response = $this->exec($this->uri.'/'.$id.'/issue'.$this->toHttpQueryParameter($paramArray), null); 42 | 43 | try { 44 | return $this->json_mapper->mapArray( 45 | json_decode($response, false, 512, $this->getJsonOptions())->issues, 46 | new \ArrayObject(), 47 | AgileIssue::class 48 | ); 49 | } catch (\JsonException $exception) { 50 | $this->log->error("Response cannot be decoded from json\nException: {$exception->getMessage()}"); 51 | 52 | return null; 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Field/Field.php: -------------------------------------------------------------------------------- 1 | name = $name; 34 | 35 | return $this; 36 | } 37 | 38 | public function setDescription($description) 39 | { 40 | $this->description = $description; 41 | 42 | return $this; 43 | } 44 | 45 | /** 46 | * set custom field type. 47 | * 48 | * @see https://confluence.atlassian.com/jira064/changing-custom-field-types-720415917.html 49 | * 50 | * @param string $type 51 | * 52 | * @return $this 53 | */ 54 | public function setType(string $type) 55 | { 56 | $this->type = $type; 57 | 58 | return $this; 59 | } 60 | 61 | /** 62 | * atlassian supplied poor documentation. 63 | * 64 | * @param string $searcherKey 65 | * 66 | * @return $this 67 | */ 68 | public function setSearcherKey(string $searcherKey) 69 | { 70 | $this->searcherKey = $searcherKey; 71 | 72 | return $this; 73 | } 74 | 75 | /* @var string */ 76 | public $id; 77 | 78 | /* @var string */ 79 | public $name; 80 | 81 | /* @var string */ 82 | public $description; 83 | 84 | /* @var string */ 85 | public $type; 86 | 87 | /* @var boolean */ 88 | public $custom; 89 | 90 | /* @var boolean */ 91 | public $orderable; 92 | 93 | /* @var boolean */ 94 | public $navigable; 95 | 96 | /* @var boolean */ 97 | public $searchable; 98 | 99 | /** @var string */ 100 | public $searcherKey; 101 | 102 | /** 103 | * if field is custom, array has two element. first is custom field number represented in bracket with cf prefix, second element is field name. 104 | * 105 | * Ex: [0 => "cf[10201]", 1 => "My Check Box"] 106 | * 107 | * @var array 108 | */ 109 | public $clauseNames; 110 | 111 | /* @var Schema */ 112 | public $schema; 113 | 114 | #[\ReturnTypeWillChange] 115 | public function jsonSerialize(): array 116 | { 117 | return array_filter(get_object_vars($this)); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/Field/FieldService.php: -------------------------------------------------------------------------------- 1 | exec($this->uri, null); 21 | 22 | $fields = $this->json_mapper->mapArray( 23 | json_decode($ret, false), 24 | new \ArrayObject(), 25 | '\JiraRestApi\Field\Field' 26 | ); 27 | 28 | // temp array 29 | $ar = []; 30 | if ($fieldType === Field::CUSTOM) { 31 | foreach ($fields as $f) { 32 | if ($f->custom === true) { 33 | array_push($ar, $f); 34 | } 35 | } 36 | $fields = &$ar; 37 | } elseif ($fieldType === Field::SYSTEM) { 38 | foreach ($fields as $f) { 39 | if ($f->custom === false) { 40 | array_push($ar, $f); 41 | } 42 | } 43 | $fields = &$ar; 44 | } 45 | 46 | return $fields; 47 | } 48 | 49 | /** 50 | * Returned if the Custom Field Option exists and is visible by the calling user. 51 | * 52 | * Currently, JIRA doesn't provide a method to retrieve custom field's option. instead use getEditMeta(). 53 | * 54 | * @see IssueService::getEditMeta() . 55 | * 56 | * @param string $id custom field option id 57 | * 58 | * @throws \JiraRestApi\JiraException 59 | * 60 | * @return string 61 | */ 62 | public function getCustomFieldOption($id) 63 | { 64 | $ret = $this->exec('/customFieldOption/'.$id); 65 | 66 | $this->log->debug("get custom Field Option=\n".$ret); 67 | 68 | return $ret; 69 | } 70 | 71 | /** 72 | * create new field. 73 | * 74 | * @param Field $field object of Field class 75 | * 76 | * @throws \JiraRestApi\JiraException 77 | * @throws \JsonMapper_Exception 78 | * 79 | * @return Field created field class 80 | */ 81 | public function create(Field $field) 82 | { 83 | $data = json_encode($field); 84 | 85 | $this->log->info("Create Field=\n".$data); 86 | 87 | $ret = $this->exec($this->uri, $data, 'POST'); 88 | 89 | $cf = $this->json_mapper->map( 90 | json_decode($ret), 91 | new Field() 92 | ); 93 | 94 | return $cf; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/Field/Schema.php: -------------------------------------------------------------------------------- 1 | setAPIUri('/rest/greenhopper/'.$version); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Group/Group.php: -------------------------------------------------------------------------------- 1 | name = $name; 48 | 49 | return $this; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Group/GroupSearchResult.php: -------------------------------------------------------------------------------- 1 | exec($this->uri.$queryParam, null); 28 | 29 | $this->log->info("Result=\n".$ret); 30 | 31 | return $this->json_mapper->map( 32 | json_decode($ret), 33 | new Group() 34 | ); 35 | } 36 | 37 | /** 38 | * Get users from group. 39 | * 40 | * @param array $paramArray groupname, includeInactiveUsers, startAt, maxResults 41 | * 42 | * @throws \JiraRestApi\JiraException 43 | * @throws \JsonMapper_Exception 44 | * 45 | * @return GroupSearchResult 46 | */ 47 | public function getMembers($paramArray) 48 | { 49 | $queryParam = '?'.http_build_query($paramArray); 50 | 51 | $ret = $this->exec($this->uri.'/member'.$queryParam, null); 52 | 53 | $this->log->info("Result=\n".$ret); 54 | 55 | $userData = json_decode($ret); 56 | 57 | $res = $this->json_mapper->map($userData, new GroupSearchResult()); 58 | 59 | return $res; 60 | } 61 | 62 | /** 63 | * Creates a group by given group parameter. 64 | * 65 | * @param \JiraRestApi\Group\Group $group 66 | * 67 | * @throws \JiraRestApi\JiraException 68 | * @throws \JsonMapper_Exception 69 | * 70 | * @return Group 71 | */ 72 | public function createGroup(Group $group) 73 | { 74 | $data = json_encode($group); 75 | 76 | $ret = $this->exec($this->uri, $data); 77 | 78 | $this->log->info("Result=\n".$ret); 79 | 80 | $group = $this->json_mapper->map( 81 | json_decode($ret), 82 | new Group() 83 | ); 84 | 85 | return $group; 86 | } 87 | 88 | /** 89 | * Adds given user to a group. 90 | * 91 | * @param string $groupName 92 | * @param string $userName 93 | * 94 | * @throws \JiraRestApi\JiraException 95 | * @throws \JsonMapper_Exception 96 | * 97 | * @return Group Returns the current state of the group. 98 | */ 99 | public function addUserToGroup(string $groupName, string $userName) 100 | { 101 | $data = json_encode(['name' => $userName]); 102 | 103 | $ret = $this->exec($this->uri.'/user?groupname='.urlencode($groupName), $data); 104 | 105 | $this->log->info("Result=\n".$ret); 106 | 107 | $group = $this->json_mapper->map( 108 | json_decode($ret), 109 | new Group() 110 | ); 111 | 112 | return $group; 113 | } 114 | 115 | /** 116 | * Removes given user from a group. 117 | * 118 | * @param string $groupName 119 | * @param string $userName 120 | * 121 | * @throws \JiraRestApi\JiraException 122 | * 123 | * @return string|null Returns no content 124 | */ 125 | public function removeUserFromGroup(string $groupName, string $userName) 126 | { 127 | $param = http_build_query(['groupname' => $groupName, 'username' => $userName]); 128 | 129 | $ret = $this->exec($this->uri.'/user?'.$param, [], 'DELETE'); 130 | 131 | $this->log->info("Result=\n".$ret); 132 | 133 | return $ret; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/Group/GroupUser.php: -------------------------------------------------------------------------------- 1 | setAPIUri('/rest/agile/'.$this->agileVersion); 18 | } 19 | 20 | public function get($issueIdOrKey, $paramArray = []): ?AgileIssue 21 | { 22 | $response = $this->exec($this->uri.'/'.$issueIdOrKey.$this->toHttpQueryParameter($paramArray), null); 23 | 24 | try { 25 | return $this->json_mapper->map( 26 | json_decode($response, false, 512, $this->getJsonOptions()), 27 | new AgileIssue() 28 | ); 29 | } catch (\JsonException $exception) { 30 | $this->log->error("Response cannot be decoded from json\nException: {$exception->getMessage()}"); 31 | 32 | return null; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Issue/Attachment.php: -------------------------------------------------------------------------------- 1 | body = $body; 39 | 40 | return $this; 41 | } 42 | 43 | #[\ReturnTypeWillChange] 44 | public function jsonSerialize(): array 45 | { 46 | return array_filter(get_object_vars($this)); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Issue/Comments.php: -------------------------------------------------------------------------------- 1 | name = $name; 13 | } 14 | 15 | #[\ReturnTypeWillChange] 16 | public function jsonSerialize(): array 17 | { 18 | return array_filter(get_object_vars($this)); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Issue/ContentField.php: -------------------------------------------------------------------------------- 1 | content = []; 22 | } 23 | 24 | #[\ReturnTypeWillChange] 25 | public function jsonSerialize(): array 26 | { 27 | return array_filter(get_object_vars($this)); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Issue/CustomField.php: -------------------------------------------------------------------------------- 1 | fieldName = $fieldName; 29 | 30 | return $this; 31 | } 32 | 33 | public function setCustomFieldId($customFieldId) 34 | { 35 | $this->customFieldId = $customFieldId; 36 | 37 | return $this; 38 | } 39 | 40 | public function setIssueCountWithVersionInCustomField($issueCountWithVersionInCustomField) 41 | { 42 | $this->issueCountWithVersionInCustomField = $issueCountWithVersionInCustomField; 43 | 44 | return $this; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Issue/History.php: -------------------------------------------------------------------------------- 1 | issueErrors; 31 | } 32 | 33 | /** 34 | * @param array $issueErrors 35 | */ 36 | public function setIssueErrors($issueErrors) 37 | { 38 | $this->issueErrors = $issueErrors; 39 | } 40 | 41 | /** 42 | * @return Issue[] 43 | */ 44 | public function getIssues() 45 | { 46 | return $this->issues; 47 | } 48 | 49 | /** 50 | * @param Issue[] $issues 51 | */ 52 | public function setIssues($issues) 53 | { 54 | $this->issues = $issues; 55 | } 56 | 57 | /** 58 | * @param int $ndx 59 | * 60 | * @return Issue 61 | */ 62 | public function getIssue($ndx) 63 | { 64 | return $this->issues[$ndx]; 65 | } 66 | 67 | /** 68 | * @return string 69 | */ 70 | public function getExpand() 71 | { 72 | return $this->expand; 73 | } 74 | 75 | /** 76 | * @param string $expand 77 | */ 78 | public function setExpand($expand) 79 | { 80 | $this->expand = $expand; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/Issue/IssueSearchResult.php: -------------------------------------------------------------------------------- 1 | nextPageToken; 47 | } 48 | 49 | /** 50 | * @param string $nextPageToken 51 | */ 52 | public function setNextPageToken($nextPageToken) 53 | { 54 | $this->nextPageToken = $nextPageToken; 55 | } 56 | 57 | /** 58 | * @return Issue[] 59 | */ 60 | public function getIssues() 61 | { 62 | return $this->issues; 63 | } 64 | 65 | /** 66 | * @param Issue[] $issues 67 | */ 68 | public function setIssues($issues) 69 | { 70 | $this->issues = $issues; 71 | } 72 | 73 | /** 74 | * @param int $ndx 75 | * 76 | * @return Issue 77 | */ 78 | public function getIssue($ndx) 79 | { 80 | return $this->issues[$ndx]; 81 | } 82 | 83 | /** 84 | * @return ?string 85 | */ 86 | public function getExpand(): ?string 87 | { 88 | return $this->expand; 89 | } 90 | 91 | public function setExpand(?string $expand) 92 | { 93 | $this->expand = $expand; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/Issue/IssueStatus.php: -------------------------------------------------------------------------------- 1 | count; 23 | } 24 | 25 | /** 26 | * Set the count of issues. 27 | * 28 | * @param int $count 29 | */ 30 | public function setCount(int $count): void 31 | { 32 | $this->count = $count; 33 | } 34 | 35 | #[\ReturnTypeWillChange] 36 | public function jsonSerialize(): array 37 | { 38 | return [ 39 | 'count' => $this->count, 40 | ]; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Issue/Notify.php: -------------------------------------------------------------------------------- 1 | to = []; 28 | $this->to['users'] = []; 29 | $this->to['groups'] = []; 30 | 31 | $this->restrict = []; 32 | $this->restrict['groups'] = []; 33 | $this->restrict['permissions'] = []; 34 | 35 | $this->to['reporter'] = true; 36 | $this->to['assignee'] = true; 37 | $this->to['watchers'] = true; 38 | $this->to['voters'] = true; 39 | } 40 | 41 | public function setSubject($subject) 42 | { 43 | $this->subject = $subject; 44 | 45 | return $this; 46 | } 47 | 48 | public function setTextBody($textBody) 49 | { 50 | $this->textBody = $textBody; 51 | 52 | return $this; 53 | } 54 | 55 | public function setHtmlBody($htmlBody) 56 | { 57 | $this->htmlBody = $htmlBody; 58 | 59 | return $this; 60 | } 61 | 62 | public function sendToReporter($bool) 63 | { 64 | $this->to['reporter'] = $bool; 65 | 66 | return $this; 67 | } 68 | 69 | public function sendToAssignee($bool) 70 | { 71 | $this->to['assignee'] = $bool; 72 | 73 | return $this; 74 | } 75 | 76 | public function sendToWatchers($bool) 77 | { 78 | $this->to['watchers'] = $bool; 79 | 80 | return $this; 81 | } 82 | 83 | public function sendToVoters($bool) 84 | { 85 | $this->to['voters'] = $bool; 86 | 87 | return $this; 88 | } 89 | 90 | public function sendToUser($name, $active) 91 | { 92 | $user['name'] = $name; 93 | $user['active'] = $active; 94 | 95 | array_push($this->to['users'], $user); 96 | 97 | return $this; 98 | } 99 | 100 | public function sendToGroup($groupName) 101 | { 102 | $group['name'] = $groupName; 103 | 104 | array_push($this->to['groups'], $group); 105 | 106 | return $this; 107 | } 108 | 109 | public function setRestrictGroup($groupName) 110 | { 111 | $group['name'] = $groupName; 112 | 113 | array_push($this->restrict['groups'], $group); 114 | 115 | return $this; 116 | } 117 | 118 | public function setRestrictPermission($id, $key) 119 | { 120 | $perm['id'] = $id; 121 | $perm['key'] = $key; 122 | array_push($this->restrict['permissions'], $perm); 123 | 124 | return $this; 125 | } 126 | 127 | #[\ReturnTypeWillChange] 128 | public function jsonSerialize(): array 129 | { 130 | return array_filter(get_object_vars($this)); 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/Issue/PaginatedWorklog.php: -------------------------------------------------------------------------------- 1 | startAt; 40 | } 41 | 42 | /** 43 | * @param int $startAt 44 | */ 45 | public function setStartAt($startAt) 46 | { 47 | $this->startAt = $startAt; 48 | } 49 | 50 | /** 51 | * @return int 52 | */ 53 | public function getMaxResults() 54 | { 55 | return $this->maxResults; 56 | } 57 | 58 | /** 59 | * @param int $maxResults 60 | */ 61 | public function setMaxResults($maxResults) 62 | { 63 | $this->maxResults = $maxResults; 64 | } 65 | 66 | /** 67 | * @return int 68 | */ 69 | public function getTotal() 70 | { 71 | return $this->total; 72 | } 73 | 74 | /** 75 | * @param int $total 76 | */ 77 | public function setTotal($total) 78 | { 79 | $this->total = $total; 80 | } 81 | 82 | /** 83 | * @return \JiraRestApi\Issue\Worklog[] Worklogs 84 | */ 85 | public function getWorklogs() 86 | { 87 | return $this->worklogs; 88 | } 89 | 90 | /** 91 | * @param \JiraRestApi\Issue\Worklog[] $worklogs 92 | */ 93 | public function setWorklogs($worklogs) 94 | { 95 | $this->worklogs = $worklogs; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/Issue/Priority.php: -------------------------------------------------------------------------------- 1 | object)) { 39 | $this->object = new self(); 40 | } 41 | 42 | $this->object->url = $url; 43 | 44 | return $this; 45 | } 46 | 47 | public function setTitle($title) 48 | { 49 | $this->object->title = $title; 50 | 51 | return $this; 52 | } 53 | 54 | public function setSummary($summary) 55 | { 56 | $this->object->summary = $summary; 57 | 58 | return $this; 59 | } 60 | 61 | public function setRelationship($relationship) 62 | { 63 | $this->relationship = $relationship; 64 | 65 | return $this; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/Issue/RemoteIssueLinkObject.php: -------------------------------------------------------------------------------- 1 | $value) { 50 | if ($key === 'name' && ($this->isWantUnassigned() === true)) { 51 | continue; 52 | } elseif ($key === 'wantUnassigned') { 53 | unset($vars[$key]); 54 | } elseif (is_null($value) || $value === '') { 55 | unset($vars[$key]); 56 | } 57 | } 58 | 59 | if (empty($vars)) { 60 | return null; 61 | } 62 | 63 | return $vars; 64 | } 65 | 66 | /** 67 | * determine class has value for effective json serialize. 68 | * 69 | * @see https://github.com/lesstif/php-jira-rest-client/issues/126 70 | * 71 | * @return bool 72 | */ 73 | public function isEmpty() 74 | { 75 | if (empty($this->name) && empty($this->self)) { 76 | return true; 77 | } 78 | 79 | return false; 80 | } 81 | 82 | /** 83 | * @return bool 84 | */ 85 | public function isWantUnassigned() 86 | { 87 | if ($this->wantUnassigned) { 88 | return true; 89 | } 90 | 91 | return false; 92 | } 93 | 94 | /** 95 | * @param bool $param boolean 96 | */ 97 | public function setWantUnassigned(bool $param) 98 | { 99 | $this->wantUnassigned = $param; 100 | $this->name = null; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/Issue/SecurityScheme.php: -------------------------------------------------------------------------------- 1 | originalEstimate. 45 | * 46 | * @var int 47 | */ 48 | public $originalEstimateSeconds; 49 | 50 | /** 51 | * Remaining estimate in seconds, generated in jira 52 | * for create/update issue set $this->remainingEstimate. 53 | * 54 | * @var int 55 | */ 56 | public $remainingEstimateSeconds; 57 | 58 | /** 59 | * Time spent in seconds, generated in jira 60 | * for create/update issue set $this->timeSpent. 61 | * 62 | * @var int 63 | */ 64 | public $timeSpentSeconds; 65 | 66 | /** 67 | * @return string 68 | */ 69 | public function getOriginalEstimate() 70 | { 71 | return $this->originalEstimate; 72 | } 73 | 74 | /** 75 | * @param string $originalEstimate 76 | */ 77 | public function setOriginalEstimate($originalEstimate) 78 | { 79 | $this->originalEstimate = $originalEstimate; 80 | } 81 | 82 | /** 83 | * @return string 84 | */ 85 | public function getRemainingEstimate() 86 | { 87 | return $this->remainingEstimate; 88 | } 89 | 90 | /** 91 | * @param string $remainingEstimate 92 | */ 93 | public function setRemainingEstimate($remainingEstimate) 94 | { 95 | $this->remainingEstimate = $remainingEstimate; 96 | } 97 | 98 | /** 99 | * @return string 100 | */ 101 | public function getTimeSpent() 102 | { 103 | return $this->timeSpent; 104 | } 105 | 106 | /** 107 | * @param string $timeSpent 108 | */ 109 | public function setTimeSpent($timeSpent) 110 | { 111 | $this->timeSpent = $timeSpent; 112 | } 113 | 114 | /** 115 | * @return int 116 | */ 117 | public function getOriginalEstimateSeconds() 118 | { 119 | return $this->originalEstimateSeconds; 120 | } 121 | 122 | /** 123 | * @param int $originalEstimateSeconds 124 | */ 125 | public function setOriginalEstimateSeconds($originalEstimateSeconds) 126 | { 127 | $this->originalEstimateSeconds = $originalEstimateSeconds; 128 | } 129 | 130 | /** 131 | * @return int 132 | */ 133 | public function getRemainingEstimateSeconds() 134 | { 135 | return $this->remainingEstimateSeconds; 136 | } 137 | 138 | /** 139 | * @param int $remainingEstimateSeconds 140 | */ 141 | public function setRemainingEstimateSeconds($remainingEstimateSeconds) 142 | { 143 | $this->remainingEstimateSeconds = $remainingEstimateSeconds; 144 | } 145 | 146 | /** 147 | * @return int 148 | */ 149 | public function getTimeSpentSeconds() 150 | { 151 | return $this->timeSpentSeconds; 152 | } 153 | 154 | /** 155 | * @param int $timeSpentSeconds 156 | */ 157 | public function setTimeSpentSeconds($timeSpentSeconds) 158 | { 159 | $this->timeSpentSeconds = $timeSpentSeconds; 160 | } 161 | 162 | /** 163 | * Specify data which should be serialized to JSON. 164 | * 165 | * @link http://php.net/manual/en/jsonserializable.jsonserialize.php 166 | * 167 | * @return array data which can be serialized by json_encode, 168 | * which is a value of any type other than a resource. 169 | */ 170 | #[\ReturnTypeWillChange] 171 | public function jsonSerialize(): array 172 | { 173 | return array_filter(get_object_vars($this)); 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /src/Issue/Transition.php: -------------------------------------------------------------------------------- 1 | transition)) { 46 | $this->transition = []; 47 | } 48 | 49 | $this->transition['name'] = $name; 50 | } 51 | 52 | /** 53 | * set none translated transition name. 54 | * 55 | * @param string $untranslatedName 56 | */ 57 | public function setUntranslatedName(string $untranslatedName) 58 | { 59 | if (is_null($this->transition)) { 60 | $this->transition = []; 61 | } 62 | 63 | $this->transition['untranslatedName'] = $untranslatedName; 64 | } 65 | 66 | public function setTransitionId($id) 67 | { 68 | if (is_null($this->transition)) { 69 | $this->transition = []; 70 | } 71 | 72 | $this->transition['id'] = $id; 73 | } 74 | 75 | public function setCommentBody($commentBody) 76 | { 77 | if (is_null($this->update)) { 78 | $this->update = []; 79 | $this->update['comment'] = []; 80 | } 81 | 82 | $ar = []; 83 | $ar['add']['body'] = $commentBody; 84 | array_push($this->update['comment'], $ar); 85 | } 86 | 87 | #[\ReturnTypeWillChange] 88 | public function jsonSerialize(): array 89 | { 90 | return array_filter(get_object_vars($this)); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/Issue/TransitionTo.php: -------------------------------------------------------------------------------- 1 | name = $name; 37 | } 38 | 39 | #[\ReturnTypeWillChange] 40 | public function jsonSerialize(): array 41 | { 42 | return array_filter(get_object_vars($this)); 43 | } 44 | 45 | public function setProjectId($id): static 46 | { 47 | $this->projectId = $id; 48 | 49 | return $this; 50 | } 51 | 52 | public function setName($name): static 53 | { 54 | $this->name = $name; 55 | 56 | return $this; 57 | } 58 | 59 | public function setDescription($description) 60 | { 61 | $this->description = $description; 62 | 63 | return $this; 64 | } 65 | 66 | public function setArchived($archived): static 67 | { 68 | $this->archived = $archived; 69 | 70 | return $this; 71 | } 72 | 73 | public function setReleased($released): static 74 | { 75 | $this->released = $released; 76 | 77 | return $this; 78 | } 79 | 80 | public function setReleaseDateAsDateTime(DateTimeInterface $releaseDate, string $format = 'Y-m-d'): static 81 | { 82 | $this->releaseDate = $releaseDate->format($format); 83 | 84 | return $this; 85 | } 86 | 87 | public function setReleaseDateAsString(string $releaseDate): static 88 | { 89 | $this->releaseDate = $releaseDate; 90 | 91 | return $this; 92 | } 93 | 94 | public function setUserReleaseDateAsDateTime($userReleaseDate): static 95 | { 96 | $this->userReleaseDate = $userReleaseDate; 97 | 98 | return $this; 99 | } 100 | 101 | public function setStartDateAsDateTime(\DateTimeInterface $startDate, string $format = 'Y-m-d'): static 102 | { 103 | $this->startDate = $startDate->format($format); 104 | 105 | return $this; 106 | } 107 | 108 | public function setStartDateAsString(?string $startDate): static 109 | { 110 | $this->startDate = $startDate; 111 | 112 | return $this; 113 | } 114 | 115 | public function setUserStartDateAsDateTime(\DateTimeInterface $userStartDate, string $format = 'Y-m-d'): static 116 | { 117 | $this->userStartDate = $userStartDate->format($format); 118 | 119 | return $this; 120 | } 121 | 122 | public function setUserStartDateAsString(?string $userStartDate): static 123 | { 124 | $this->userStartDate = $userStartDate; 125 | 126 | return $this; 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/Issue/VersionIssueCounts.php: -------------------------------------------------------------------------------- 1 | self = $self; 35 | 36 | return $this; 37 | } 38 | 39 | public function setIssuesFixedCount($issuesFixedCount) 40 | { 41 | $this->issuesFixedCount = $issuesFixedCount; 42 | 43 | return $this; 44 | } 45 | 46 | public function setIssuesAffectedCount($issuesAffectedCount) 47 | { 48 | $this->issuesAffectedCount = $issuesAffectedCount; 49 | 50 | return $this; 51 | } 52 | 53 | public function setIssueCountWithCustomFieldsShowingVersion($issueCountWithCustomFieldsShowingVersion) 54 | { 55 | $this->issueCountWithCustomFieldsShowingVersion = $issueCountWithCustomFieldsShowingVersion; 56 | 57 | return $this; 58 | } 59 | 60 | public function setCustomFieldUsage($customFieldUsage) 61 | { 62 | $this->customFieldUsage = $customFieldUsage; 63 | 64 | return $this; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/Issue/VersionUnresolvedCount.php: -------------------------------------------------------------------------------- 1 | self = $self; 22 | 23 | return $this; 24 | } 25 | 26 | public function setIssuesUnresolvedCount($issuesUnresolvedCount) 27 | { 28 | $this->issuesUnresolvedCount = $issuesUnresolvedCount; 29 | 30 | return $this; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Issue/Visibility.php: -------------------------------------------------------------------------------- 1 | type = $type; 13 | } 14 | 15 | public function setValue(string $value) 16 | { 17 | $this->value = $value; 18 | } 19 | 20 | public function getType(): string 21 | { 22 | return $this->type; 23 | } 24 | 25 | public function getValue(): string 26 | { 27 | return $this->value; 28 | } 29 | 30 | #[\ReturnTypeWillChange] 31 | public function jsonSerialize(): array 32 | { 33 | return array_filter(get_object_vars($this)); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Issue/VisibilityTrait.php: -------------------------------------------------------------------------------- 1 | visibility = $type; 10 | 11 | return $this; 12 | } 13 | 14 | public function setVisibilityAsArray(array $array): static 15 | { 16 | if (is_null($this->visibility)) { 17 | $this->visibility = new Visibility(); 18 | } 19 | 20 | $this->visibility->setType($array['type']); 21 | $this->visibility->setValue($array['value']); 22 | 23 | return $this; 24 | } 25 | 26 | public function setVisibilityAsString(string $type, string $value): static 27 | { 28 | if (is_null($this->visibility)) { 29 | $this->visibility = new Visibility(); 30 | } 31 | 32 | $this->visibility->setType($type); 33 | $this->visibility->setValue($value); 34 | 35 | return $this; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Issue/Worklog.php: -------------------------------------------------------------------------------- 1 | comment = $comment; 94 | 95 | return $this; 96 | } 97 | 98 | // Note that in the docblock below, you cannot replace `mixed` by `\DateTimeInterface|string` because JsonMapper doesn't support that, 99 | // see . 100 | 101 | /** 102 | * Function to set start time of worklog. 103 | * 104 | * @param mixed $started started time value(\DateTimeInterface|string) e.g. - new \DateTime("2016-03-17 11:15:34") or "2016-03-17 11:15:34" 105 | * 106 | * @throws JiraException 107 | * 108 | * @return Worklog 109 | */ 110 | public function setStarted($started) 111 | { 112 | if (is_string($started)) { 113 | $dt = new \DateTime($started); 114 | } elseif ($started instanceof \DateTimeInterface) { 115 | $dt = $started; 116 | } else { 117 | throw new JiraException('field only accept date string or DateTimeInterface object.'.get_class($started)); 118 | } 119 | 120 | // workround micro second 121 | $this->started = $dt->format("Y-m-d\TH:i:s").'.000'.$dt->format('O'); 122 | 123 | return $this; 124 | } 125 | 126 | /** 127 | * Function to set start time of worklog. 128 | * 129 | * @param \DateTimeInterface $started e.g. - new \DateTime("2014-04-05 16:00:00") 130 | * 131 | * @return Worklog 132 | */ 133 | public function setStartedDateTime($started) 134 | { 135 | // workround micro second 136 | $this->started = $started->format("Y-m-d\TH:i:s").'.000'.$started->format('O'); 137 | 138 | return $this; 139 | } 140 | 141 | /** 142 | * Function to set worklog time in string. 143 | * 144 | * @param string $timeSpent 145 | * 146 | * @return Worklog 147 | */ 148 | public function setTimeSpent($timeSpent) 149 | { 150 | $this->timeSpent = $timeSpent; 151 | 152 | return $this; 153 | } 154 | 155 | /** 156 | * Function to set worklog time in seconds. 157 | * 158 | * @param int $timeSpentSeconds 159 | * 160 | * @return Worklog 161 | */ 162 | public function setTimeSpentSeconds($timeSpentSeconds) 163 | { 164 | $this->timeSpentSeconds = $timeSpentSeconds; 165 | 166 | return $this; 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /src/IssueLink/IssueLink.php: -------------------------------------------------------------------------------- 1 | type['name'] = $typeName; 38 | 39 | return $this; 40 | } 41 | 42 | /** 43 | * @param string|int $issueKey inward issue key or id 44 | * 45 | * @return $this 46 | */ 47 | public function setInwardIssue($issueKey) 48 | { 49 | $this->inwardIssue['key'] = $issueKey; 50 | 51 | return $this; 52 | } 53 | 54 | /** 55 | * @param string|int $issueKey out ward issue key or id 56 | * 57 | * @return $this 58 | */ 59 | public function setOutwardIssue($issueKey) 60 | { 61 | $this->outwardIssue['key'] = $issueKey; 62 | 63 | return $this; 64 | } 65 | 66 | /** 67 | * @param string|Comment $comment string or \JiraRestApi\Issue\Comment instance 68 | * 69 | * @return $this 70 | */ 71 | public function setComment($comment) 72 | { 73 | if (is_string($comment)) { 74 | $this->comment = new Comment(); 75 | $this->comment->setBody($comment); 76 | } elseif ($comment instanceof Comment) { 77 | $this->comment = $comment; 78 | } 79 | 80 | return $this; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/IssueLink/IssueLinkService.php: -------------------------------------------------------------------------------- 1 | log->info("addIssueLink=\n"); 19 | 20 | $data = json_encode($issueLink); 21 | 22 | $this->log->debug("Create IssueLink=\n".$data); 23 | 24 | $url = $this->uri.'/issueLink'; 25 | $type = 'POST'; 26 | 27 | return $this->exec($url, $data, $type); 28 | } 29 | 30 | /** 31 | * @throws \JiraRestApi\JiraException 32 | * 33 | * @return IssueLinkType[] 34 | */ 35 | public function getIssueLinkTypes() 36 | { 37 | $this->log->info("getIssueLinkTYpes=\n"); 38 | 39 | $url = $this->uri.'/issueLinkType'; 40 | 41 | $ret = $this->exec($url); 42 | 43 | $data = json_encode(json_decode($ret)->issueLinkTypes); 44 | 45 | $linkTypes = $this->json_mapper->mapArray( 46 | json_decode($data, false), 47 | new \ArrayObject(), 48 | '\JiraRestApi\IssueLink\IssueLinkType' 49 | ); 50 | 51 | return $linkTypes; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/IssueLink/IssueLinkType.php: -------------------------------------------------------------------------------- 1 | exec($this->uri.'/', null); 24 | $this->log->info("Result=\n".$ret); 25 | 26 | return $this->json_mapper->mapArray( 27 | json_decode($ret, false), 28 | new \ArrayObject(), 29 | IssueType::class 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/JiraException.php: -------------------------------------------------------------------------------- 1 | response = $response; 32 | } 33 | 34 | /** 35 | * Get error response. 36 | */ 37 | public function getResponse(): ?string 38 | { 39 | return $this->response; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/JiraRestApiServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->bind(ConfigurationInterface::class, function () { 31 | return new DotEnvConfiguration(base_path()); 32 | }); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/JsonMapperHelper.php: -------------------------------------------------------------------------------- 1 | {$propName} = $jsonValue; 22 | $object->customFields[$propName] = $jsonValue; 23 | } 24 | } elseif (isset($object->{$propName})) { 25 | $object->{$propName} = $jsonValue; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/JsonSerializableTrait.php: -------------------------------------------------------------------------------- 1 | exec($this->uri, null); 25 | 26 | $this->log->info("Result=\n".$ret); 27 | 28 | $priorityData = json_decode($ret); 29 | $priorities = []; 30 | 31 | foreach ($priorityData as $priority) { 32 | $priorities[] = $this->json_mapper->map($priority, new Priority()); 33 | } 34 | 35 | return $priorities; 36 | } 37 | 38 | /** 39 | * get specific priority info. 40 | * 41 | * @param string|int $priorityId priority id 42 | * 43 | * @throws \JiraRestApi\JiraException 44 | * @throws \JsonMapper_Exception 45 | * 46 | * @return \JiraRestApi\Issue\Priority 47 | */ 48 | public function get($priorityId) 49 | { 50 | $ret = $this->exec($this->uri."/$priorityId", null); 51 | 52 | $this->log->info("Result=\n".$ret); 53 | 54 | $priority = $this->json_mapper->map(json_decode($ret), new Priority()); 55 | 56 | return $priority; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Project/Component.php: -------------------------------------------------------------------------------- 1 | setupAPIUri(); 19 | } 20 | 21 | public function getBurnDownChartData($rapidViewId, $sprintId, $paramArray = []) 22 | { 23 | $paramArray['rapidViewId'] = $rapidViewId; 24 | $paramArray['sprintId'] = $sprintId; 25 | $json = $this->exec($this->uri.'/'.$this->toHttpQueryParameter($paramArray), null); 26 | $burnDownChart = json_decode($json); 27 | 28 | return $burnDownChart; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Request/Author.php: -------------------------------------------------------------------------------- 1 | body = $body; 30 | 31 | return $this; 32 | } 33 | 34 | /** 35 | * @param bool $public True for is public, false otherwise 36 | * 37 | * @return $this 38 | */ 39 | public function setIsPublic(bool $public) 40 | { 41 | $this->public = $public; 42 | 43 | return $this; 44 | } 45 | 46 | #[\ReturnTypeWillChange] 47 | public function jsonSerialize(): array 48 | { 49 | return array_filter(get_object_vars($this), function ($var) { 50 | return $var !== null; 51 | }); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Request/RequestService.php: -------------------------------------------------------------------------------- 1 | setupAPIUri(); 30 | } 31 | 32 | /** 33 | * Add the given comment to the specified request based on the provided $issueIdOrKey value. Returns a new 34 | * RequestComment with the response. 35 | * 36 | * @param string|int $issueIdOrKey 37 | * @param RequestComment $requestComment 38 | * 39 | * @throws JiraException 40 | * @throws \JsonMapper_Exception 41 | * 42 | * @return RequestComment 43 | */ 44 | public function addComment($issueIdOrKey, RequestComment $requestComment): RequestComment 45 | { 46 | $this->log->info("addComment=\n"); 47 | 48 | if (empty($requestComment->body)) { 49 | throw new JiraException('comment param must be an instance of RequestComment and have body text.'); 50 | } 51 | 52 | $data = json_encode($requestComment); 53 | 54 | $ret = $this->exec($this->uri."/$issueIdOrKey/comment", $data); 55 | 56 | $this->log->debug('add comment result='.var_export($ret, true)); 57 | $requestComment = $this->json_mapper->map( 58 | json_decode($ret), 59 | new RequestComment() 60 | ); 61 | 62 | return $requestComment; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/ServiceDesk/Attachment/AttachmentService.php: -------------------------------------------------------------------------------- 1 | client = $client; 22 | $this->jsonMapper = $client->getMapper(); 23 | } 24 | 25 | /** 26 | * @param Attachment[] $attachments 27 | * 28 | * @throws JiraException 29 | * 30 | * @return string[] 31 | */ 32 | public function createTemporaryFiles(array $attachments, string $serviceDeskId): array 33 | { 34 | $fileNames = $this->getFilenamesFromAttachments($attachments); 35 | 36 | return $this->client->upload( 37 | $this->client->createUrl('/servicedesk/%s/attachTemporaryFile', [$serviceDeskId]), 38 | $fileNames 39 | ); 40 | } 41 | 42 | /** 43 | * @throws JiraException|JsonException|JsonMapper_Exception 44 | * 45 | * @return Attachment[] 46 | */ 47 | public function addAttachmentToRequest(int $requestId, array $temporaryFiles): array 48 | { 49 | $attachment_ids = array_map(static function (string $upload) { 50 | $upload = json_decode($upload, true, 512, JSON_THROW_ON_ERROR); 51 | 52 | return $upload['temporaryAttachments'][0]['temporaryAttachmentId']; 53 | }, $temporaryFiles); 54 | 55 | $parameters = [ 56 | 'temporaryAttachmentIds' => $attachment_ids, 57 | 'public' => false, 58 | ]; 59 | 60 | $result = $this->client->exec( 61 | $this->client->createUrl('/request/%d/attachment', [$requestId]), 62 | json_encode($parameters, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE), 63 | 'POST' 64 | ); 65 | 66 | return $this->createAttachmentsFromJson($result); 67 | } 68 | 69 | /** 70 | * @param Attachment[] $attachments 71 | * 72 | * @return string[] 73 | */ 74 | private function getFilenamesFromAttachments(array $attachments): array 75 | { 76 | return array_map(static function (Attachment $attachment) { 77 | return $attachment->filename; 78 | }, $attachments); 79 | } 80 | 81 | /** 82 | * @throws JsonMapper_Exception|JsonException 83 | * 84 | * @return Attachment[] 85 | */ 86 | private function createAttachmentsFromJson(string $result): array 87 | { 88 | $attachmentData = json_decode($result, false, 512, JSON_THROW_ON_ERROR); 89 | 90 | $attachments = []; 91 | foreach ($attachmentData as $attachment) { 92 | $attachments[] = $this->jsonMapper->map($attachment, new Attachment()); 93 | } 94 | 95 | return $attachments; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/ServiceDesk/Comment/Comment.php: -------------------------------------------------------------------------------- 1 | id = (int) $id; 29 | } 30 | 31 | public function setAuthor(array $author): void 32 | { 33 | $this->author = new Reporter(); 34 | foreach ($author as $key => $value) { 35 | if (property_exists($this->author, $key)) { 36 | $this->author->$key = $value; 37 | } 38 | } 39 | } 40 | 41 | public function setCreated(array $created): void 42 | { 43 | $this->created = new DateTime($created['iso8601']); 44 | } 45 | 46 | public function setLinks(array $links): void 47 | { 48 | $this->_links = $links; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/ServiceDesk/Customer/Customer.php: -------------------------------------------------------------------------------- 1 | _links = $links; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/ServiceDesk/Customer/CustomerLinks.php: -------------------------------------------------------------------------------- 1 | _links = $links; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/ServiceDesk/Request/Request.php: -------------------------------------------------------------------------------- 1 | requestTypeId = $requestTypeId; 37 | 38 | return $this; 39 | } 40 | 41 | public function setServiceDeskId(string $serviceDeskId): self 42 | { 43 | $this->serviceDeskId = $serviceDeskId; 44 | 45 | return $this; 46 | } 47 | 48 | public function setCreatedDate(object $createdDate): void 49 | { 50 | if (!$createdDate instanceof DateTimeInterface) { 51 | $createdDate = new DateTime($createdDate->iso8601); 52 | } 53 | 54 | $this->createdDate = $createdDate; 55 | } 56 | 57 | public function setReporter(object $reporter): self 58 | { 59 | if (!$reporter instanceof Customer) { 60 | $reporter = $this->map($reporter, new Customer()); 61 | } 62 | 63 | $this->reporter = $reporter; 64 | 65 | return $this; 66 | } 67 | 68 | public function setSummary(string $summary): self 69 | { 70 | $this->requestFieldValues['summary'] = $summary; 71 | 72 | return $this; 73 | } 74 | 75 | public function setDescription(string $description): self 76 | { 77 | $this->requestFieldValues['description'] = $description; 78 | 79 | return $this; 80 | } 81 | 82 | public function addCustomField(string $key, $value): self 83 | { 84 | $this->requestFieldValues[$key] = $value; 85 | 86 | return $this; 87 | } 88 | 89 | public function setCurrentStatus(object $currentStatus): void 90 | { 91 | $this->currentStatus = $this->map($currentStatus, new RequestStatus()); 92 | } 93 | 94 | public function setLinks(object $links): void 95 | { 96 | $this->_links = $links; 97 | } 98 | 99 | /** 100 | * @param Customer[] $requestParticipants 101 | */ 102 | public function setRequestParticipants(array $requestParticipants): self 103 | { 104 | $this->requestParticipants = $requestParticipants; 105 | 106 | return $this; 107 | } 108 | 109 | public function jsonSerialize(): array 110 | { 111 | $data = get_object_vars($this); 112 | if ($this->reporter) { 113 | $data['raiseOnBehalfOf'] = $this->reporter->accountId ?? $this->reporter->emailAddress; 114 | } 115 | unset($data['reporter']); 116 | 117 | $data['requestParticipants'] = array_map(static function (Customer $customer): string { 118 | return $customer->accountId ?? $customer->emailAddress; 119 | }, $this->requestParticipants); 120 | 121 | return array_filter($data); 122 | } 123 | 124 | private function map(object $data, object $target) 125 | { 126 | $mapper = new JsonMapper(); 127 | 128 | // Adjust settings for JsonMapper v5.0 BC 129 | if (property_exists($mapper, 'bStrictNullTypesInArrays')) { 130 | $mapper->bStrictNullTypesInArrays = false; // if you want to allow nulls in arrays 131 | } 132 | $mapper->bStrictNullTypes = false; // if you want to allow nulls 133 | $mapper->bStrictObjectTypeChecking = false; // if you want to disable strict type checking 134 | 135 | return $mapper->map( 136 | $data, 137 | $target 138 | ); 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /src/ServiceDesk/Request/RequestStatus.php: -------------------------------------------------------------------------------- 1 | statusDate = new DateTime($statusDate['iso8601']); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/ServiceDesk/ServiceDeskClient.php: -------------------------------------------------------------------------------- 1 | json_mapper->bEnforceMapType = false; 22 | } 23 | 24 | /** 25 | * @inheritDoc 26 | */ 27 | protected function createUrlByContext(string $context): string 28 | { 29 | $host = $this->getConfiguration()->getJiraHost(); 30 | 31 | return sprintf('%s/rest/servicedeskapi/%s', $host, preg_replace('/\//', '', $context, 1)); 32 | } 33 | 34 | public function getLogger(): LoggerInterface 35 | { 36 | return $this->log; 37 | } 38 | 39 | public function getMapper(): JsonMapper 40 | { 41 | return $this->json_mapper; 42 | } 43 | 44 | public function createUrl(string $format, array $parameters, array $urlParameters = []): string 45 | { 46 | if (count($urlParameters) > 0) { 47 | $format .= '?%s'; 48 | $parameters[] = http_build_query($urlParameters); 49 | } 50 | 51 | array_unshift($parameters, $format); 52 | 53 | return call_user_func_array('sprintf', $parameters); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/ServiceDeskTrait.php: -------------------------------------------------------------------------------- 1 | setAPIUri($uri); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Sprint/Sprint.php: -------------------------------------------------------------------------------- 1 | name = $sprintName; 40 | 41 | return $this; 42 | } 43 | 44 | public function setGoalAsString(string $sprintGoal): self 45 | { 46 | $this->goal = $sprintGoal; 47 | 48 | return $this; 49 | } 50 | 51 | public function setOriginBoardIdAsStringOrInt(string|int $originBoardId): self 52 | { 53 | $this->originBoardId = strval($originBoardId); 54 | 55 | return $this; 56 | } 57 | 58 | public function setStartDateAsDateTime(\DateTimeInterface $startDate, string $format = 'Y-m-d'): static 59 | { 60 | $this->startDate = $startDate->format($format); 61 | 62 | return $this; 63 | } 64 | 65 | public function setStartDateAsString(string $startDate): static 66 | { 67 | $this->startDate = $startDate; 68 | 69 | return $this; 70 | } 71 | 72 | public function setEndDateAsDateTime(\DateTimeInterface $endDate, string $format = 'Y-m-d'): static 73 | { 74 | $this->endDate = $endDate->format($format); 75 | 76 | return $this; 77 | } 78 | 79 | public function setEndDateAsString(string $endDate): static 80 | { 81 | $this->endDate = $endDate; 82 | 83 | return $this; 84 | } 85 | 86 | public function setMoveIssues(array $issues): static 87 | { 88 | $this->issues = $issues; 89 | 90 | return $this; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/Sprint/SprintSearchResult.php: -------------------------------------------------------------------------------- 1 | startAt; 48 | } 49 | 50 | /** 51 | * @param int $startAt 52 | */ 53 | public function setStartAt($startAt) 54 | { 55 | $this->startAt = $startAt; 56 | } 57 | 58 | /** 59 | * @return int 60 | */ 61 | public function getMaxResults() 62 | { 63 | return $this->maxResults; 64 | } 65 | 66 | /** 67 | * @param int $maxResults 68 | */ 69 | public function setMaxResults($maxResults) 70 | { 71 | $this->maxResults = $maxResults; 72 | } 73 | 74 | /** 75 | * @return int 76 | */ 77 | public function getTotal() 78 | { 79 | return $this->total; 80 | } 81 | 82 | /** 83 | * @param int $total 84 | */ 85 | public function setTotal($total) 86 | { 87 | $this->total = $total; 88 | } 89 | 90 | /** 91 | * @return Sprint[] 92 | */ 93 | public function getSprints() 94 | { 95 | return $this->issues; 96 | } 97 | 98 | /** 99 | * @param Sprint[] $issues 100 | */ 101 | public function setSprints($issues) 102 | { 103 | $this->issues = $issues; 104 | } 105 | 106 | /** 107 | * @param int $ndx 108 | * 109 | * @return object 110 | */ 111 | public function getSprint($ndx) 112 | { 113 | return $this->issues[$ndx]; 114 | } 115 | 116 | /** 117 | * @return string 118 | */ 119 | public function getExpand() 120 | { 121 | return $this->expand; 122 | } 123 | 124 | /** 125 | * @param string $expand 126 | */ 127 | public function setExpand($expand) 128 | { 129 | $this->expand = $expand; 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /src/Sprint/SprintService.php: -------------------------------------------------------------------------------- 1 | setAPIUri('/rest/agile/1.0'); 21 | } 22 | 23 | /** 24 | * @param object $json JSON object structure from json_decode 25 | * 26 | * @throws \JsonMapper_Exception 27 | */ 28 | public function getSprintFromJSON(object $json): Sprint 29 | { 30 | $sprint = $this->json_mapper->map( 31 | $json, 32 | new Sprint() 33 | ); 34 | 35 | return $sprint; 36 | } 37 | 38 | public function getSprint(string|int $sprintId): Sprint 39 | { 40 | $ret = $this->exec($this->uri.'/'.$sprintId, null); 41 | 42 | $this->log->info("Result=\n".$ret); 43 | 44 | return $this->json_mapper->map( 45 | json_decode($ret), 46 | new Sprint() 47 | ); 48 | } 49 | 50 | /** 51 | * @throws JiraException 52 | * @throws \JsonMapper_Exception 53 | * 54 | * @return Issue[] array of Issue 55 | */ 56 | public function getSprintIssues(string|int $sprintId, array $paramArray = []) 57 | { 58 | $json = $this->exec($this->uri.'/'.$sprintId.'/issue'.$this->toHttpQueryParameter($paramArray), null); 59 | 60 | $issues = $this->json_mapper->mapArray( 61 | json_decode($json)->issues, 62 | new \ArrayObject(), 63 | Issue::class 64 | ); 65 | 66 | return $issues; 67 | } 68 | 69 | public function createSprint(Sprint $sprint): Sprint 70 | { 71 | $data = json_encode($sprint); 72 | 73 | $ret = $this->exec($this->uri, $data); 74 | 75 | $this->log->debug('createSprint result='.var_export($ret, true)); 76 | 77 | return $this->json_mapper->map( 78 | json_decode($ret), 79 | new Sprint() 80 | ); 81 | } 82 | 83 | /** 84 | * @see https://docs.atlassian.com/jira-software/REST/9.11.0/#agile/1.0/sprint-moveIssuesToSprint 85 | */ 86 | public function moveIssues2Sprint(int $sprintId, Sprint $sprint): bool 87 | { 88 | $data = json_encode($sprint); 89 | 90 | $ret = $this->exec($this->uri.'/'.$sprintId.'/issue', $data); 91 | 92 | $this->log->debug('moveIssues2Sprint result='.var_export($ret, true)); 93 | 94 | return $ret; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/Status/Status.php: -------------------------------------------------------------------------------- 1 | exec($this->uri.'/', null); 23 | $this->log->info("Result=\n".$ret); 24 | 25 | return $this->json_mapper->mapArray( 26 | json_decode($ret, false), 27 | new \ArrayObject(), 28 | \JiraRestApi\Status\Status::class 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/StatusCategory/StatusCategoryService.php: -------------------------------------------------------------------------------- 1 | exec($this->uri.'/', null); 24 | $this->log->info("Result=\n".$ret); 25 | 26 | return $this->json_mapper->mapArray( 27 | json_decode($ret, false), 28 | new \ArrayObject(), 29 | \JiraRestApi\Issue\Statuscategory::class 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/User/User.php: -------------------------------------------------------------------------------- 1 | $value) { 28 | $this->{$key} = $value; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /test-data/comment.json: -------------------------------------------------------------------------------- 1 | { 2 | "self": "https://jira.example.com/rest/api/2/issue/13332/comment/12312", 3 | "id": "12312", 4 | "author": { 5 | "self": "https://jira.example.com/rest/api/2/user?username=lesstif", 6 | "name": "John Doe", 7 | "key": "lesstif", 8 | "emailAddress": "johndoe@example.com", 9 | "avatarUrls": { 10 | "48x48": "https://jira.example.com/secure/useravatar?avatarId=10122", 11 | "24x24": "https://jira.example.com/secure/useravatar?size=small&avatarId=10122", 12 | "16x16": "https://jira.example.com/secure/useravatar?size=xsmall&avatarId=10122", 13 | "32x32": "https://jira.example.com/secure/useravatar?size=medium&avatarId=10122" 14 | }, 15 | "displayName": "John Doe", 16 | "active": true, 17 | "timeZone": "ROK" 18 | }, 19 | "body": "Adds a new comment to an issue.\\r\\n* Bullet 1\\r\\n* Bullet 2\\r\\n** sub Bullet 1\\r\\n** sub Bullet 2", 20 | "updateAuthor": { 21 | "self": "https://jira.example.com/rest/api/2/user?username=lesstif", 22 | "name": "KwangSeob Jeong", 23 | "key": "lesstif", 24 | "emailAddress": "lesstif@gmail.com", 25 | "avatarUrls": { 26 | "48x48": "https://jira.example.com/secure/useravatar?avatarId=10122", 27 | "24x24": "https://jira.example.com/secure/useravatar?size=small&avatarId=10122", 28 | "16x16": "https://jira.example.com/secure/useravatar?size=xsmall&avatarId=10122", 29 | "32x32": "https://jira.example.com/secure/useravatar?size=medium&avatarId=10122" 30 | }, 31 | "displayName": "정광섭", 32 | "active": true, 33 | "timeZone": "ROK" 34 | }, 35 | "created": "2017-12-20T09:00:05.752+0900", 36 | "updated": "2017-12-20T09:00:05.752+0900", 37 | "visibility": { 38 | "type": "role", 39 | "value": "Users" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /test-data/issueFieldV3.json: -------------------------------------------------------------------------------- 1 | { 2 | "update": { 3 | "worklog": [ 4 | { 5 | "add": { 6 | "timeSpent": "60m", 7 | "started": "2011-07-05T11:05:00.000+0000" 8 | } 9 | } 10 | ] 11 | }, 12 | "fields": { 13 | "summary": "something's wrong", 14 | "issuetype": { 15 | "id": "10000" 16 | }, 17 | "components": [ 18 | { 19 | "id": "10000" 20 | } 21 | ], 22 | "customfield_20000": "06/Jul/11 3:25 PM", 23 | "customfield_40000": "this is a text field", 24 | "customfield_70000": [ 25 | "jira-administrators", 26 | "jira-software-users" 27 | ], 28 | "project": { 29 | "id": "10000" 30 | }, 31 | "description": { 32 | "type": "doc", 33 | "version": 1, 34 | "content": [ 35 | { 36 | "type": "paragraph", 37 | "content": [ 38 | { 39 | "text": "description", 40 | "type": "text" 41 | } 42 | ] 43 | } 44 | ] 45 | }, 46 | "reporter": { 47 | "id": "557058:d6b5955a-e193-41e1-b051-79cdb0755d68" 48 | }, 49 | "fixVersions": [ 50 | { 51 | "id": "10001" 52 | } 53 | ], 54 | "customfield_10000": "09/Jun/81", 55 | "priority": { 56 | "id": "20000" 57 | }, 58 | "labels": [ 59 | "bugfix", 60 | "blitz_test" 61 | ], 62 | "timetracking": { 63 | "remainingEstimate": "5", 64 | "originalEstimate": "10" 65 | }, 66 | "customfield_30000": [ 67 | "10000", 68 | "10002" 69 | ], 70 | "customfield_80000": { 71 | "value": "red" 72 | }, 73 | "security": { 74 | "id": "10000" 75 | }, 76 | "environment": { 77 | "type": "doc", 78 | "version": 1, 79 | "content": [ 80 | { 81 | "type": "paragraph", 82 | "content": [ 83 | { 84 | "text": "environment", 85 | "type": "text" 86 | } 87 | ] 88 | } 89 | ] 90 | }, 91 | "versions": [ 92 | { 93 | "id": "10000" 94 | } 95 | ], 96 | "duedate": "2011-03-11T00:00:00.000Z", 97 | "customfield_60000": "jira-software-users", 98 | "customfield_50000": "this is a text area. big text.", 99 | "assignee": { 100 | "id": "5b10a2844c20165700ede21f" 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /test-data/reporter-no-email-address.json: -------------------------------------------------------------------------------- 1 | { 2 | "reporter": { 3 | "self": "https://jira.example.com/rest/api/2/user?username=lesstif", 4 | "name": "lesstif", 5 | "key": "lesstif", 6 | "avatarUrls": { 7 | "48x48": "https://secure.gravatar.com/avatar/9f1705ef1d8c977eba04f00556e02922?d=mm&s=48", 8 | "24x24": "https://secure.gravatar.com/avatar/9f1705ef1d8c977eba04f00556e02922?d=mm&s=24", 9 | "16x16": "https://secure.gravatar.com/avatar/9f1705ef1d8c977eba04f00556e02922?d=mm&s=16", 10 | "32x32": "https://secure.gravatar.com/avatar/9f1705ef1d8c977eba04f00556e02922?d=mm&s=32" 11 | }, 12 | "displayName": "정광섭", 13 | "active": true, 14 | "timeZone": "Asia/Seoul" 15 | } 16 | } -------------------------------------------------------------------------------- /tests/AssigneeTest.php: -------------------------------------------------------------------------------- 1 | mapper = new JsonMapper(); 21 | $this->mapper->undefinedPropertyHandler = [new \JiraRestApi\JsonMapperHelper(), 'setUndefinedProperty']; 22 | $this->mapper->classMap['\\'.\DateTimeInterface::class] = \DateTime::class; 23 | } 24 | 25 | public function tearDown(): void 26 | { 27 | $this->mapper = null; 28 | m::close(); 29 | } 30 | 31 | public function testAssigneeFieldNull() 32 | { 33 | $issueField = new IssueField(); 34 | 35 | $issueField->setProjectKey('TEST') 36 | ->setIssueTypeAsString('Bug') 37 | ; 38 | 39 | $js = $issueField->jsonSerialize(); 40 | 41 | $this->assertArrayNotHasKey('assignee', $js); 42 | } 43 | 44 | public function testUnassigned() 45 | { 46 | $issueField = new IssueField(); 47 | 48 | $issueField->setProjectKey('TEST') 49 | ->setIssueTypeAsString('Bug') 50 | ->setAssigneeToUnassigned() 51 | ; 52 | 53 | $js = $issueField->jsonSerialize(); 54 | 55 | $this->assertArrayHasKey('assignee', $js); 56 | 57 | $assignee = $js['assignee']; 58 | 59 | $this->assertEquals(true, property_exists($assignee, 'name'), "Reporter class has not 'name' property"); 60 | $this->assertEquals(null, $assignee->name, "name field not equal to 'null'"); 61 | } 62 | 63 | public function testAssigneeFieldDefault() 64 | { 65 | $issueField = new IssueField(); 66 | 67 | $issueField->setProjectKey('TEST') 68 | ->setIssueTypeAsString('Bug') 69 | ->setAssigneeToDefault() 70 | ; 71 | 72 | $js = $issueField->jsonSerialize(); 73 | 74 | $this->assertArrayHasKey('assignee', $js); 75 | 76 | $assignee = $js['assignee']; 77 | 78 | $this->assertEquals(true, property_exists($assignee, 'name'), "Reporter class has not 'name' property"); 79 | $this->assertEquals("-1", $assignee->name, "name field not equal to '-1'"); 80 | } 81 | 82 | public function testAssigneeFieldHasAssignee() 83 | { 84 | $issueField = new IssueField(); 85 | 86 | $issueField->setProjectKey('TEST') 87 | ->setIssueTypeAsString('Bug') 88 | ->setAssigneeNameAsString('lesstif') 89 | ; 90 | 91 | $js = $issueField->jsonSerialize(); 92 | 93 | $this->assertArrayHasKey('assignee', $js); 94 | 95 | $assignee = $js['assignee']; 96 | 97 | $this->assertEquals(true, property_exists($assignee, 'name'), "Reporter class has not 'name' property"); 98 | $this->assertEquals("lesstif", $assignee->name, "name field not equal to "); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /tests/AttachmentTest.php: -------------------------------------------------------------------------------- 1 | get($attachmentId, "output", true); 19 | 20 | dump($att); 21 | 22 | return $attachmentId; 23 | } catch (JiraException $e) { 24 | $this->assertTrue(false, 'Create Failed : '.$e->getMessage()); 25 | } 26 | } 27 | 28 | /** 29 | * @depends testGetAttachment 30 | */ 31 | public function testRemoveAttachment($attachmentId) 32 | { 33 | try { 34 | $atts = new AttachmentService(); 35 | 36 | $atts->remove($attachmentId); 37 | 38 | $this->assertGreaterThan(0, count(1)); 39 | 40 | } catch (HTTPException $e) { 41 | $this->assertTrue(false, $e->getMessage()); 42 | } 43 | } 44 | 45 | 46 | } 47 | -------------------------------------------------------------------------------- /tests/BoardTest.php: -------------------------------------------------------------------------------- 1 | getBoardList(); 28 | $this->assertInstanceOf(ArrayObject::class, $board_list, 'We receive a board list.'); 29 | 30 | $last_board_id = null; 31 | foreach ($board_list as $board) { 32 | $this->assertInstanceOf(Board::class, $board, 'Each element of the list is a Board instance.'); 33 | $this->assertNotNull($board->self, 'self must not null'); 34 | $this->assertNotNull($board->name, 'name must not null'); 35 | $this->assertNotNull($board->type, 'type must not null'); 36 | // $this->assertNotNull($board->location, 'location must not null'); 37 | 38 | $last_board_id = $board->id; 39 | } 40 | 41 | return $last_board_id; 42 | } 43 | 44 | /** 45 | * @test 46 | * 47 | * Test we can obtain the paginated board list. 48 | */ 49 | public function get_boards() : string 50 | { 51 | $board_service = new BoardService(); 52 | 53 | $board_list = $board_service->getBoards(); 54 | $this->assertInstanceOf(BoardResult::class, $board_list, 'We receive a board list.'); 55 | 56 | $last_board_id = null; 57 | foreach ($board_list->getBoards() as $board) { 58 | $this->assertInstanceOf(Board::class, $board, 'Each element of the list is a Board instance.'); 59 | $this->assertNotNull($board->self, 'self must not null'); 60 | $this->assertNotNull($board->name, 'name must not null'); 61 | $this->assertNotNull($board->type, 'type must not null'); 62 | 63 | $last_board_id = $board->id; 64 | } 65 | 66 | return $last_board_id; 67 | } 68 | 69 | /** 70 | * @test 71 | * 72 | * @depends get_all_boards 73 | * 74 | * Test we can obtain a single board. 75 | */ 76 | public function get_last_board(string $last_board_id) 77 | { 78 | $board_service = new BoardService(); 79 | 80 | $board = $board_service->getBoard($last_board_id); 81 | 82 | /** @var \JiraRestApi\Board\Board $board */ 83 | $this->assertInstanceOf(Board::class, $board, 'We receive a board instance'); 84 | $this->assertNotEmpty($board->getId(), 'Check board id.'); 85 | $this->assertNotEmpty($board->getName(), 'Check board name.'); 86 | $this->assertNotEmpty($board->getType(), 'Check board type.'); 87 | $this->assertNotEmpty($board->getSelf(), 'Check board self.'); 88 | //$this->assertInstanceOf(Location::class, $board->getLocation(), 'Check board location.'); 89 | 90 | return $last_board_id; 91 | } 92 | 93 | /** 94 | * @test 95 | * 96 | * @depends get_last_board 97 | * Test we can obtain board issues. 98 | */ 99 | public function testGetBoardIssues(string $last_board_id) 100 | { 101 | $board_service = new BoardService(); 102 | $board_issues = $board_service->getBoardIssues($last_board_id); 103 | $this->assertInstanceOf(ArrayObject::class, $board_issues, 'We receive a board issue list.'); 104 | 105 | foreach ($board_issues as $issue) { 106 | $this->assertInstanceOf(Issue::class, $issue); 107 | $this->assertNotEmpty($issue->id); 108 | } 109 | } 110 | 111 | } 112 | -------------------------------------------------------------------------------- /tests/ComponentTest.php: -------------------------------------------------------------------------------- 1 | setProjectKey('TEST') 27 | ->setName($name) 28 | ->setLeadUserName('lesstif') 29 | ->setAssigneeTypeAsEnum(AssigneeTypeEnum::PROJECT_LEAD) 30 | ->setDescription('describe your component here'); 31 | 32 | $c = $cs->create($comp); 33 | 34 | $this->assertNotNull($c->id); 35 | $this->assertNotNull($c->project); 36 | 37 | return $c->id; 38 | } catch (\Exception $e) { 39 | $this->fail('create_component_on_project failed' . $e->getMessage()); 40 | } 41 | } 42 | 43 | /** 44 | * @test 45 | * @depends create_component_on_project 46 | * @param string $component_id 47 | * @return void 48 | */ 49 | public function get_component_on_project(string $component_id): void 50 | { 51 | try { 52 | $cs = new ComponentService(); 53 | 54 | $c = $cs->get($component_id); 55 | 56 | $this->assertNotNull($c->id); 57 | $this->assertNotNull($c->project); 58 | } catch (\Exception $e) { 59 | $this->fail('get_component_on_project failed' . $e->getMessage()); 60 | } 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /tests/CurlTest.php: -------------------------------------------------------------------------------- 1 | markTestIncomplete(); 13 | try { 14 | $config = getHostConfig(); 15 | 16 | $config['host'] = 'http://requestb.in/vqid8qvq'; 17 | 18 | $j = new \JiraRestApi\JiraClient($config, getOptions()); 19 | 20 | $post_data = ['name' => 'value']; 21 | 22 | $http_status = 0; 23 | $ret = $j->exec('/', json_encode($post_data), $http_status); 24 | 25 | var_dump($ret); 26 | $this->assertTrue(true); 27 | } catch (HTTPException $e) { 28 | $this->assertTrue(false, $e->getMessage()); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/CustomFieldsTest.php: -------------------------------------------------------------------------------- 1 | 1, 26 | 'maxResults' => 50, 27 | 'search' => null, 28 | 'projectIds' => [1, 2, 3], 29 | 'screenIds' => null, 30 | 'types' => null, 31 | 32 | 'sortOrder' => null, 33 | 'sortColumn' => null, 34 | 'lastValueUpdate' => null, 35 | ]; 36 | $customerFieldSearchResult = $iss->getCustomFields($paramArray); 37 | 38 | $this->assertLessThan(1, $customerFieldSearchResult->total); 39 | 40 | } catch (JiraException $e) { 41 | $this->assertTrue(false, 'testSearch Failed : '.$e->getMessage()); 42 | } 43 | } 44 | 45 | public function testGetFields() 46 | { 47 | try { 48 | $fieldService = new FieldService(); 49 | 50 | $ret = $fieldService->getAllFields(Field::CUSTOM); 51 | Dumper::dump($ret); 52 | 53 | file_put_contents("custom-field.json", json_encode($ret, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT)); 54 | 55 | $ids = array_map(function($cf) { 56 | // extract custom field id 57 | preg_match('/\d+/', $cf->id, $matches); 58 | return $matches[0]; 59 | }, $ret); 60 | 61 | $this->assertTrue(true); 62 | return $ids; 63 | 64 | } catch (JiraException $e) { 65 | $this->assertTrue(false, 'testSearch Failed : '.$e->getMessage()); 66 | } 67 | } 68 | 69 | /** 70 | * @depends testGetFields 71 | * 72 | * @param $ids 73 | */ 74 | public function testGetFieldOptions($ids) 75 | { 76 | try { 77 | $fieldService = new FieldService(); 78 | 79 | foreach ($ids as $id) { 80 | try { 81 | $ret = $fieldService->getCustomFieldOption($id); 82 | Dumper::dump($ret); 83 | }catch (JiraException $e) {} 84 | } 85 | $this->assertTrue(true); 86 | } catch (JiraException $e) { 87 | $this->assertTrue(false, 'testGetFieldOptions Failed : '.$e->getMessage()); 88 | } 89 | } 90 | 91 | public function testCreateFields() 92 | { 93 | //$this->markTestSkipped(); 94 | try { 95 | $field = new Field(); 96 | 97 | $field->setName('다중 선택이') 98 | ->setDescription('Custom field for picking groups') 99 | ->setType("com.atlassian.jira.plugin.system.customfieldtypes:cascadingselect") 100 | // ->setSearcherKey('com.atlassian.jira.plugin.system.customfieldtypes:grouppickersearcher') 101 | ; 102 | 103 | $fieldService = new FieldService(); 104 | 105 | $ret = $fieldService->create($field); 106 | 107 | $this->assertTrue(true); 108 | 109 | Dumper::dump($ret); 110 | } catch (JiraException $e) { 111 | $this->assertTrue(false, 'Field Create Failed : '.$e->getMessage()); 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /tests/EpicTest.php: -------------------------------------------------------------------------------- 1 | setProjectKey('EPICTEST') 29 | ->setAssigneeNameAsString('lesstif') 30 | ->setPriorityNameAsString('Critical') 31 | ->setIssueTypeAsString('Epic') 32 | // some jira instance need localization Epic name like below. 33 | //->setIssueTypeAsString('큰틀') 34 | 35 | // Create Epic always need epic names custom field, 36 | // unfortunately is custom field name different each systems. 37 | ->addCustomField('customfield_10403', 'My Big Epic name') 38 | ->setSummary("My Big Epic") // Don't confused epic name with summary. 39 | ; 40 | 41 | $issueService = new IssueService(); 42 | 43 | $ret = $issueService->create($issueField); 44 | 45 | //If success, Returns a link to the created issue. 46 | print_r($ret); 47 | 48 | $issueKey = $ret->{'key'}; 49 | 50 | $this->assertNotNull($issueKey); 51 | 52 | return $issueKey; 53 | } catch (Exception $e) { 54 | $this->fail('create_new_epic : ' . $e->getMessage()); 55 | } 56 | } 57 | 58 | /** 59 | * @test 60 | * 61 | * @depends create_new_epic 62 | * 63 | * @return string|void 64 | * @throws \JsonMapper_Exception 65 | */ 66 | public function get_epic(string $epicKey) 67 | { 68 | try { 69 | $es = new EpicService(); 70 | 71 | $epic = $es->getEpic($epicKey); 72 | 73 | $this->assertNotNull($epicKey); 74 | //Dumper::dump($epic); 75 | } catch (JiraException $e) { 76 | $this->fail('get_epic Failed : '.$e->getMessage()); 77 | } 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /tests/GroupTest.php: -------------------------------------------------------------------------------- 1 | markTestSkipped(); 16 | try { 17 | $g = new Group(); 18 | 19 | $g->name = 'Test 한글 group for REST API q'; 20 | 21 | $gs = new GroupService(); 22 | 23 | $ret = $gs->createGroup($g); 24 | 25 | Dumper::dump($ret); 26 | 27 | $groupName = $g->name; 28 | 29 | return $groupName; 30 | } catch (JiraException $e) { 31 | $this->assertTrue(false, 'testCreateGroup Failed : '.$e->getMessage()); 32 | } 33 | } 34 | 35 | /** 36 | * @depends testCreateGroup 37 | */ 38 | public function testGetUsersFromGroup($groupName) 39 | { 40 | try { 41 | $queryParam = [ 42 | 'groupname' => $groupName, 43 | 'includeInactiveUsers' => true, // default false 44 | 'startAt' => 0, 45 | 'maxResults' => 50, 46 | ]; 47 | 48 | $gs = new GroupService(); 49 | 50 | $ret = $gs->getMembers($queryParam); 51 | 52 | // print all users in the group 53 | foreach ($ret->values as $user) { 54 | print_r($user); 55 | } 56 | 57 | return $groupName; 58 | } catch (JiraException $e) { 59 | $this->assertTrue(false, 'testCreateGroup Failed : '.$e->getMessage()); 60 | } 61 | } 62 | 63 | /** 64 | * @depends testCreateGroup 65 | */ 66 | public function testAddUserToGroup($groupName) 67 | { 68 | try { 69 | $userName = 'lesstif'; 70 | 71 | $gs = new GroupService(); 72 | 73 | $ret = $gs->addUserToGroup($groupName, $userName); 74 | 75 | // print all users in the group 76 | print_r($ret); 77 | } catch (JiraException $e) { 78 | $this->assertTrue(false, 'testAddUserToGroup Failed : '.$e->getMessage()); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /tests/IssueSecuritySechemTest.php: -------------------------------------------------------------------------------- 1 | getAllIssueSecuritySchemes(); 24 | 25 | $this->assertGreaterThan(1, count($securitySchemes), 'security scheme must greater than 1'); 26 | $this->assertEquals(true, array_key_exists('id', $securitySchemes[0]), 'security id not found'); 27 | 28 | return $securitySchemes; 29 | } catch (HTTPException $e) { 30 | $this->assertTrue(false, $e->getMessage()); 31 | } 32 | } 33 | 34 | /** 35 | * @depends testGetAllSecuritySchemes 36 | * 37 | * @param $securitySchem 38 | * @throws Exception 39 | * @throws JiraException 40 | * @throws JsonMapper_Exception 41 | */ 42 | public function testGetSecurityScheme($securitySchemes) 43 | { 44 | $securityId = 0; 45 | 46 | try { 47 | $issueService = new IssueService(); 48 | 49 | foreach ($securitySchemes as $s) { 50 | $ss = $issueService->getIssueSecuritySchemes($s->id); 51 | 52 | $this->assertObjectHasAttribute('id', $ss, 'security id not found'); 53 | $this->assertObjectHasAttribute('levels', $ss, 'security level not found'); 54 | 55 | if ($securityId === 0) 56 | $securityId = $ss->id; 57 | } 58 | 59 | return $securityId; 60 | } catch (HTTPException $e) { 61 | $this->assertTrue(false, $e->getMessage()); 62 | } 63 | } 64 | 65 | /** 66 | * @depends testGetSecurityScheme 67 | * 68 | * @param $schemeId 69 | * @return mixed 70 | * @throws Exception 71 | * @throws JsonMapper_Exception 72 | */ 73 | public function testCreateIssueWithSecurityScheme($securityId) 74 | { 75 | try { 76 | $issueField = new IssueField(); 77 | 78 | $issueField->setProjectKey('TEST') 79 | ->setSummary("issue security level test") 80 | ->setAssigneeName('lesstif') 81 | ->setPriorityName('Critical') 82 | ->setIssueType('Bug') 83 | ->setDescription('Full description for issue') 84 | ->addVersion(['1.0.1', '1.0.3']) 85 | ->addComponents(['Component-1', 'Component-2']) 86 | ->setSecurity($securityId) 87 | ; 88 | 89 | $issueService = new IssueService(); 90 | 91 | $ret = $issueService->create($issueField); 92 | 93 | $this->assertInstanceOf(Issue::class, $ret); 94 | 95 | } catch (JiraException $e) { 96 | $this->assertTrue(false, 'Create Failed : '.$e->getMessage()); 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /tests/MapperTest.php: -------------------------------------------------------------------------------- 1 | mapper = new JsonMapper(); 22 | $this->mapper->undefinedPropertyHandler = [new \JiraRestApi\JsonMapperHelper(), 'setUndefinedProperty']; 23 | $this->mapper->classMap['\\'.\DateTimeInterface::class] = \DateTime::class; 24 | } 25 | 26 | public function tearDown(): void 27 | { 28 | $this->mapper = null; 29 | m::close(); 30 | } 31 | 32 | public function testComment() 33 | { 34 | $ret = file_get_contents('test-data/comment.json'); 35 | 36 | $comment = $this->mapper->map( 37 | json_decode($ret), new Comment() 38 | ); 39 | 40 | $this->assertInstanceOf(Comment::class, $comment); 41 | 42 | $this->assertEquals('johndoe@example.com', $comment->author->emailAddress); 43 | $this->assertEquals('KwangSeob Jeong', $comment->updateAuthor->name); 44 | } 45 | 46 | public function testIssueField() 47 | { 48 | $ret = file_get_contents('test-data/issueField.json'); 49 | 50 | $issueField = $this->mapper->map( 51 | json_decode($ret), new IssueField() 52 | ); 53 | 54 | $this->assertInstanceOf(IssueField::class, $issueField); 55 | 56 | $this->assertInstanceOf(Reporter::class, $issueField->assignee); 57 | $this->assertEquals('lesstif@gmail.com', $issueField->assignee->emailAddress); 58 | 59 | $this->assertInstanceOf(SecurityScheme::class, $issueField->security); 60 | $this->assertEquals(12345, $issueField->security->id); 61 | } 62 | 63 | public function testIssue() 64 | { 65 | $ret = file_get_contents('test-data/issue.json'); 66 | 67 | $is = new \JiraRestApi\Issue\IssueService(); 68 | $issue = $this->mapper->map( 69 | json_decode($ret), new Issue() 70 | ); 71 | 72 | $this->assertInstanceOf(Issue::class, $issue); 73 | 74 | $this->assertTrue(is_array($issue->renderedFields)); 75 | $this->assertArrayHasKey('description', $issue->renderedFields); 76 | $this->assertEquals(10000, $issue->renderedFields['attachment'][0]->id); 77 | 78 | $this->assertTrue(is_array($issue->names)); 79 | $this->assertArrayHasKey('issuetype', $issue->names); 80 | $this->assertArrayHasKey('timespent', $issue->names); 81 | 82 | $this->assertTrue(is_array($issue->schema)); 83 | $this->assertArrayHasKey('fixVersions', $issue->schema); 84 | $this->assertEquals('array', $issue->schema['fixVersions']->type); 85 | 86 | $this->assertTrue(is_array($issue->transitions)); 87 | $this->assertLessThan(3, count($issue->transitions)); 88 | $this->assertEquals('작업 시작', $issue->transitions[0]->name); 89 | 90 | } 91 | 92 | public function testReporterField() 93 | { 94 | $ret = file_get_contents('test-data/reporter-no-email-address.json'); 95 | 96 | $reporter = $this->mapper->map( 97 | json_decode($ret), new Reporter() 98 | ); 99 | 100 | $this->assertInstanceOf(Reporter::class, $reporter); 101 | 102 | $this->assertEquals('lesstif@gmail.com', $reporter->emailAddress); 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /tests/PriorityTest.php: -------------------------------------------------------------------------------- 1 | getAll(); 19 | 20 | $this->assertGreaterThan(1, count($pl)); 21 | 22 | var_dump($pl); 23 | 24 | $priority = $pl[count($pl) - 1]; 25 | 26 | return $priority; 27 | 28 | } catch (JiraException $e) { 29 | $this->assertTrue(FALSE, "add Comment Failed : " . $e->getMessage()); 30 | } 31 | } 32 | 33 | /** 34 | * @depends testAllPriority 35 | * 36 | */ 37 | public function testPriority($priority) 38 | { 39 | try { 40 | $ps = new PriorityService(); 41 | 42 | $pl = $ps->get($priority->id); 43 | 44 | $this->assertEquals($priority->id, $pl->id); 45 | $this->assertEquals($priority->description, $pl->description); 46 | 47 | } catch (JiraException $e) { 48 | $this->assertTrue(FALSE, "add Comment Failed : " . $e->getMessage()); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tests/RemoteIssueLinkTest.php: -------------------------------------------------------------------------------- 1 | setUrl('http://www.mycompany.com/support?id=1') 23 | ->setTitle('Remote Link Title') 24 | ->setRelationship('causes') 25 | ->setSummary('Crazy customer support issue') 26 | ; 27 | 28 | $issueService->createOrUpdateRemoteIssueLink($issueKey, $ril); 29 | 30 | return $issueKey; 31 | } catch (JiraException $e) { 32 | $this->assertTrue(false, 'Create Failed : '.$e->getMessage()); 33 | } 34 | } 35 | 36 | /** 37 | * @depends testCreateRemoteIssueLink 38 | */ 39 | public function testGetRemoteIssue($issueKey) 40 | { 41 | 42 | try { 43 | $issueService = new IssueService(); 44 | 45 | $rils = $issueService->getRemoteIssueLink($issueKey); 46 | 47 | $this->assertGreaterThan(0, count($rils)); 48 | 49 | $this->assertInstanceOf(RemoteIssueLink::class, $rils[0]); 50 | 51 | return $issueKey; 52 | } catch (HTTPException $e) { 53 | $this->assertTrue(false, $e->getMessage()); 54 | } 55 | } 56 | 57 | 58 | /** 59 | * @depends testGetRemoteIssue 60 | */ 61 | public function testDeleteRemoteIssueLink($issueKey) 62 | { 63 | try { 64 | $issueService = new IssueService(); 65 | 66 | $rils = $issueService->getRemoteIssueLink($issueKey); 67 | $countBefore = count($rils); 68 | 69 | /** @var RemoteIssueLink $firstRil */ 70 | $firstRil = $rils[0]; 71 | 72 | $ret = $issueService->removeRemoteIssueLink($issueKey, $firstRil->globalId); 73 | 74 | $this->assertTrue($ret); 75 | 76 | $rilsAfter = $issueService->getRemoteIssueLink($issueKey); 77 | 78 | $this->assertLessThan($countBefore, count($rilsAfter)); 79 | 80 | return $issueKey; 81 | } catch (JiraException $e) { 82 | $this->assertTrue(false, 'Remove Failed : '.$e->getMessage()); 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /tests/SPrintTest.php: -------------------------------------------------------------------------------- 1 | add(DateInterval::createFromDateString('1 month 5 day')); 23 | 24 | $sp = (new Sprint()) 25 | ->setNameAsString("My Sprint 1") 26 | ->setGoalAsString("goal") 27 | ->setOriginBoardIdAsStringOrInt(3) 28 | ->setStartDateAsDateTime($start) 29 | ->setEndDateAsDateTime($start->add(DateInterval::createFromDateString('3 week'))) 30 | ; 31 | 32 | try { 33 | $sps = new SprintService(); 34 | 35 | $sprint = $sps->createSprint($sp); 36 | 37 | $this->assertNotNull($sprint->name); 38 | 39 | return $sprint->id; 40 | 41 | } catch (Exception $e) { 42 | $this->fail('testSearch Failed : '.$e->getMessage()); 43 | } 44 | } 45 | 46 | /** 47 | * @test 48 | * 49 | * @depends create_sprint 50 | * 51 | * @throws \JsonMapper_Exception 52 | */ 53 | public function get_sprints(int $sprintId) : int 54 | { 55 | try { 56 | $sps = new SprintService(); 57 | 58 | $sprint = $sps->getSprint($sprintId); 59 | 60 | $this->assertNotNull($sprint->name); 61 | Dumper::dump($sprint); 62 | 63 | return $sprintId; 64 | } catch (Exception $e) { 65 | $this->fail('testSearch Failed : '.$e->getMessage()); 66 | } 67 | } 68 | 69 | /** 70 | * @test 71 | * @depends get_sprints 72 | * 73 | * @param int $sprintId 74 | * @return int 75 | */ 76 | public function get_issues_in_sprints(int $sprintId) : int 77 | { 78 | try { 79 | $sps = new SprintService(); 80 | 81 | $sprint = $sps->getSprintIssues($sprintId); 82 | 83 | $this->assertNotNull($sprint); 84 | Dumper::dump($sprint); 85 | 86 | return $sprintId; 87 | } catch (Exception $e) { 88 | $this->fail('testSearch Failed : '.$e->getMessage()); 89 | } 90 | } 91 | 92 | /** 93 | * @test 94 | * @depends get_issues_in_sprints 95 | * 96 | * @param int $sprintId 97 | * @return int 98 | */ 99 | public function move_issues_to_sprints(int $sprintId) : int 100 | { 101 | try { 102 | $sp = (new Sprint()) 103 | ->setMoveIssues([ 104 | "MOBL-1", 105 | "MOBL-5", 106 | ]) 107 | 108 | ; 109 | 110 | $sps = new SprintService(); 111 | 112 | $sprint = $sps->moveIssues2Sprint($sprintId, $sp); 113 | 114 | $this->assertNotNull($sprint); 115 | 116 | return $sprintId; 117 | } catch (Exception $e) { 118 | $this->fail('move_issues_to_sprints Failed : '.$e->getMessage()); 119 | } 120 | } 121 | } -------------------------------------------------------------------------------- /tests/SearchTest.php: -------------------------------------------------------------------------------- 1 | markTestSkipped(); 16 | 17 | $jql = 'project not in (TEST) and assignee = currentUser() and status in (Resolved, closed)'; 18 | try { 19 | $issueService = new IssueService(); 20 | 21 | $ret = $issueService->search($jql); 22 | 23 | foreach ($ret as $issue) { 24 | Dumper::dump($issue); 25 | } 26 | } catch (JiraException $e) { 27 | $this->assertTrue(false, 'testSearch Failed : '.$e->getMessage()); 28 | } 29 | } 30 | 31 | public function testGetIssue() 32 | { 33 | $issueKey = 'TEST-155'; 34 | try { 35 | $issueService = new IssueService(); 36 | 37 | $queryParam = [ 38 | 'fields' => [ // default: '*all' 39 | 'summary', 40 | 'comment', 41 | ], 42 | 'expand' => [ 43 | 'renderedFields', 44 | 'names', 45 | 'schema', 46 | 'transitions', 47 | 'operations', 48 | 'editmeta', 49 | 'changelog', 50 | ], 51 | ]; 52 | 53 | $issue = $issueService->get($issueKey, $queryParam); 54 | 55 | Dumper::dump($issue); 56 | } catch (JiraException $e) { 57 | $this->assertTrue(false, 'testSearch Failed : '.$e->getMessage()); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /tests/SerializeTest.php: -------------------------------------------------------------------------------- 1 | name = '-1'; 19 | $r->emailAddress = 'user@example.com'; 20 | $r->avatarUrls = ''; 21 | 22 | $d = $r->jsonSerialize(); 23 | 24 | // passing a name value of '' then serialized array has 'name' key and empty value. 25 | // $this->assertEquals(true, array_key_exists('name', $d), 'Can\'t found "name" key.'); 26 | $this->assertEquals(false, array_key_exists('avatarUrls', $d)); 27 | } 28 | 29 | public function testSerialize() 30 | { 31 | $r = new Reporter(); 32 | 33 | $r->name = 'KwangSeob Jeong'; 34 | $r->emailAddress = 'user@example.com'; 35 | $r->avatarUrls = 'http://my.avatar.com/avatarUrls'; 36 | $r->displayName = 'lesstif'; 37 | 38 | $d = $r->toArray(['name', 'emailAddress'], $excludeMode = true); 39 | Dumper::dump($d); 40 | 41 | // serialized array have not 'name' and 'emailAddress' keys. 42 | $this->assertEquals(false, array_key_exists('name', $d), '"name" key is exists!.'); 43 | $this->assertEquals(false, array_key_exists('emailAddress', $d)); 44 | 45 | $d = $r->toArray(['name', 'emailAddress'], $excludeMode = false); 46 | 47 | // serialized array must have only 'name' and 'emailAddress' keys. 48 | $this->assertEquals(true, array_key_exists('name', $d), '"name" key is not exists!.'); 49 | $this->assertEquals(true, array_key_exists('emailAddress', $d)); 50 | $this->assertEquals(2, count($d)); 51 | Dumper::dump($d); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /tests/ServiceDesk/Attachment/AttachmentServiceTest.php: -------------------------------------------------------------------------------- 1 | createClient(); 19 | $attachments = [ 20 | $this->createAttachment('image_1.png'), 21 | $this->createAttachment('image_2.png'), 22 | $this->createAttachment('image_3.png'), 23 | ]; 24 | 25 | $expected = [ 26 | 'temporaryAttachments' => [ 27 | ['temporaryAttachmentId' => '83rhfdkshgd213213'], 28 | ['temporaryAttachmentId' => '3j4erljfdsn34123d'], 29 | ['temporaryAttachmentId' => 'dsldwejnhrewrwer21'], 30 | ], 31 | ]; 32 | 33 | $url = 'https://example.com/upload'; 34 | $serviceDeskId = '15'; 35 | 36 | $client->method('createUrl') 37 | ->with('/servicedesk/%d/attachTemporaryFile', [$serviceDeskId]) 38 | ->willReturn($url); 39 | $client->method('upload') 40 | ->with($url, ['image_1.png', 'image_2.png', 'image_3.png']) 41 | ->willReturn($expected); 42 | 43 | $uut = new AttachmentService($client); 44 | 45 | $result = $uut->createTemporaryFiles($attachments, $serviceDeskId); 46 | 47 | self::assertSame($expected, $result); 48 | } 49 | 50 | public function testAddAttachmentToRequest(): void 51 | { 52 | $temporaryFiles = [ 53 | json_encode(['temporaryAttachments' => [['temporaryAttachmentId' => '83rhfdkshgd213213']]]), 54 | json_encode(['temporaryAttachments' => [['temporaryAttachmentId' => '3j4erljfdsn34123d']]]), 55 | json_encode(['temporaryAttachments' => [['temporaryAttachmentId' => 'dsldwejnhrewrwer21']]]), 56 | ]; 57 | 58 | $attachments = [ 59 | ['id' => 10, 'filename' => 'http://example.com/uploads/image_1.png'], 60 | ['id' => 23, 'filename' => 'http://example.com/uploads/image_2.png'], 61 | ['id' => 65, 'filename' => 'http://example.com/uploads/image_3.png'], 62 | ]; 63 | 64 | $url = 'https://example.com/upload'; 65 | 66 | $client = $this->createClient(); 67 | $client->method('createUrl') 68 | ->with('/request/%d/attachment', [52]) 69 | ->willReturn($url); 70 | $client->method('exec') 71 | ->with( 72 | $url, 73 | '{"temporaryAttachmentIds":["83rhfdkshgd213213","3j4erljfdsn34123d","dsldwejnhrewrwer21"],"public":false}', 74 | 'POST' 75 | ) 76 | ->willReturn(json_encode($attachments)); 77 | 78 | $uut = new AttachmentService($client); 79 | 80 | $result = $uut->addAttachmentToRequest(52, $temporaryFiles); 81 | 82 | self::assertCount(3, $result); 83 | self::assertSame($attachments[0]['id'], $result[0]->id); 84 | self::assertSame($attachments[0]['filename'], $result[0]->filename); 85 | self::assertSame($attachments[1]['id'], $result[1]->id); 86 | self::assertSame($attachments[1]['filename'], $result[1]->filename); 87 | self::assertSame($attachments[2]['id'], $result[2]->id); 88 | self::assertSame($attachments[2]['filename'], $result[2]->filename); 89 | } 90 | 91 | /** 92 | * @return ServiceDeskClient|MockObject 93 | */ 94 | private function createClient(): MockObject|ServiceDeskClient 95 | { 96 | $mapper = new JsonMapper(); 97 | 98 | $client = $this->createMock(ServiceDeskClient::class); 99 | $client->method('getMapper')->willReturn($mapper); 100 | 101 | return $client; 102 | } 103 | 104 | private function createAttachment(string $fileName): Attachment 105 | { 106 | $attachment = new Attachment(); 107 | $attachment->filename = $fileName; 108 | 109 | return $attachment; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /tests/ServiceDesk/Comment/CommentServiceTest.php: -------------------------------------------------------------------------------- 1 | expectException(JiraException::class); 22 | 23 | $uut = new CommentService( 24 | $this->createClient() 25 | ); 26 | 27 | $uut->addComment('10', new Comment()); 28 | } 29 | 30 | public function testAddComment(): void 31 | { 32 | $comment = new Comment(); 33 | $comment->body = 'test comment'; 34 | $comment->id = 15; 35 | 36 | $url = 'https://example.com/add-comment'; 37 | 38 | $item = $this->createItem($comment->body, $comment->id); 39 | $client = $this->createClient(); 40 | $client->method('createUrl') 41 | ->with('%s/%d/comment', [$this->uri, 10]) 42 | ->willReturn($url); 43 | $client->method('exec') 44 | ->with($url, '{"id":15,"body":"test comment","public":true}') 45 | ->willReturn($item); 46 | 47 | $uut = new CommentService($client); 48 | $result = $uut->addComment('10', $comment); 49 | 50 | self::assertSame($comment->body, $result->body); 51 | self::assertSame($comment->id, $result->id); 52 | } 53 | 54 | public function testGetComment(): void 55 | { 56 | $url = 'https://example.com/get-comment'; 57 | 58 | $item = $this->createItem('test comment', 123); 59 | $client = $this->createClient(); 60 | $client->method('createUrl') 61 | ->with('%s/%d/comment/%d', [$this->uri, 42, 123]) 62 | ->willReturn($url); 63 | $client->method('exec') 64 | ->with($url) 65 | ->willReturn($item); 66 | 67 | $uut = new CommentService($client); 68 | $result = $uut->getComment('42', 123); 69 | 70 | self::assertSame('test comment', $result->body); 71 | self::assertSame(123, $result->id); 72 | } 73 | 74 | public function testGetCommentsForRequest(): void 75 | { 76 | $items = json_encode([ 77 | ['body' => 'item 1', 'id' => 15], 78 | ['body' => 'item 3', 'id' => 45], 79 | ['body' => 'item 10', 'id' => 65], 80 | ]); 81 | $url = 'https://example.com/get-comments'; 82 | $searchParameters = [ 83 | 'public' => true, 84 | 'internal' => true, 85 | 'start' => 0, 86 | 'limit' => 50, 87 | ]; 88 | 89 | $client = $this->createClient(); 90 | $client->method('createUrl') 91 | ->with('%s/%d/comment', [$this->uri, 43], $searchParameters) 92 | ->willReturn($url); 93 | $client->method('exec') 94 | ->with($url) 95 | ->willReturn($items); 96 | 97 | $uut = new CommentService($client); 98 | $results = $uut->getCommentsForRequest('43'); 99 | 100 | self::assertCount(3, $results); 101 | self::assertSame('item 1', $results[0]->body); 102 | self::assertSame(15, $results[0]->id); 103 | self::assertSame('item 3', $results[1]->body); 104 | self::assertSame(45, $results[1]->id); 105 | self::assertSame('item 10', $results[2]->body); 106 | self::assertSame(65, $results[2]->id); 107 | } 108 | 109 | /** 110 | * @return ServiceDeskClient|MockObject 111 | */ 112 | private function createClient(): MockObject|ServiceDeskClient 113 | { 114 | $mapper = new JsonMapper(); 115 | 116 | $client = $this->createMock(ServiceDeskClient::class); 117 | $client->method('getMapper')->willReturn($mapper); 118 | 119 | return $client; 120 | } 121 | 122 | private function createItem(string $body, int $id): string 123 | { 124 | return json_encode([ 125 | 'body' => $body, 126 | 'id' => $id, 127 | ]); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /tests/ServiceDesk/Comment/CommentTest.php: -------------------------------------------------------------------------------- 1 | setId($id); 20 | 21 | self::assertSame((int)$id, $uut->id); 22 | } 23 | 24 | public function testSetAuthor(): void 25 | { 26 | $author = [ 27 | 'name' => 'test reporter', 28 | 'active' => '1', 29 | 'emailAddress' => 'reporter@example.com', 30 | 'not_real' => 'true', 31 | ]; 32 | 33 | $uut = new Comment(); 34 | $uut->setAuthor($author); 35 | 36 | self::assertInstanceOf(Reporter::class, $uut->author); 37 | self::assertSame($author['name'], $uut->author->name); 38 | self::assertSame($author['active'], $uut->author->active); 39 | self::assertSame($author['emailAddress'], $uut->author->emailAddress); 40 | } 41 | 42 | public function testSetCreated(): void 43 | { 44 | $created = [ 45 | 'timestamp' => 21543521312311, 46 | 'iso8601' => '2022/05/21', 47 | ]; 48 | 49 | $uut = new Comment(); 50 | $uut->setCreated($created); 51 | 52 | self::assertInstanceOf(DateTimeInterface::class, $uut->created); 53 | self::assertSame('2022/05/21', $uut->created->format('Y/m/d')); 54 | } 55 | 56 | public function testSetLinks(): void 57 | { 58 | $links = [ 59 | ['url' => 'https://example.com/images/image_1.jpeg'], 60 | ['url' => 'https://example.com/images/image_3.jpeg'], 61 | ['url' => 'https://example.com/images/image_6.jpeg'], 62 | ]; 63 | 64 | $uut = new Comment(); 65 | $uut->setLinks($links); 66 | 67 | self::assertSame($links, $uut->_links); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /tests/ServiceDesk/Customer/CustomerTest.php: -------------------------------------------------------------------------------- 1 | jiraRest = 'http://example.com'; 18 | $links->avatarUrls = new stdClass(); 19 | 20 | $uut = new Customer(); 21 | $uut->setLinks($links); 22 | 23 | self::assertInstanceOf(CustomerLinks::class, $uut->_links); 24 | self::assertSame($links->jiraRest, $uut->_links->jiraRest); 25 | self::assertSame($links->avatarUrls, $uut->_links->avatarUrls); 26 | } 27 | 28 | public function testSetLinks(): void 29 | { 30 | $customerLinks = new CustomerLinks(); 31 | $customerLinks->jiraRest = 'http://example.com'; 32 | $customerLinks->avatarUrls = new stdClass(); 33 | 34 | $uut = new Customer(); 35 | $uut->setLinks($customerLinks); 36 | 37 | self::assertSame($customerLinks, $uut->_links); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /tests/ServiceDesk/Organisation/OrganisationTest.php: -------------------------------------------------------------------------------- 1 | setLinks($links); 21 | 22 | self::assertSame($links, $uut->_links); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/ServiceDesk/Participant/ParticipantServiceTest.php: -------------------------------------------------------------------------------- 1 | client = $this->createMock(ServiceDeskClient::class); 22 | $this->client->method('getMapper')->willReturn(new JsonMapper()); 23 | 24 | $this->uut = new ParticipantService($this->client); 25 | } 26 | 27 | public function tearDown(): void 28 | { 29 | $this->client = null; 30 | $this->uut = null; 31 | } 32 | 33 | public function testGetParticipant(): void 34 | { 35 | $customerData = [ 36 | 'accountId' => '1234', 37 | 'displayName' => 'Foo Bar', 38 | ]; 39 | 40 | $this->client->method('exec')->willReturn(json_encode(['values' => [$customerData]])); 41 | 42 | $result = $this->uut->getParticipantOfRequest('K-123'); 43 | 44 | $this->assertEquals([$this->createCustomer($customerData)], $result); 45 | } 46 | 47 | public function testAddParticipant(): void 48 | { 49 | $customerData = [ 50 | [ 51 | 'accountId' => '1234', 52 | 'displayName' => 'Foo Bar', 53 | ], 54 | [ 55 | 'accountId' => '12345', 56 | 'displayName' => 'Foo Bar2', 57 | ], 58 | ]; 59 | 60 | $this->client->method('exec')->willReturn(json_encode(['values' => $customerData])); 61 | 62 | $result = $this->uut->addParticipantToRequest('K-123', [$this->createCustomer($customerData[1])]); 63 | 64 | $this->assertEquals([$this->createCustomer($customerData[0]), $this->createCustomer($customerData[1])], $result); 65 | } 66 | 67 | public function testRemoveParticipant(): void 68 | { 69 | $customerData = [ 70 | [ 71 | 'accountId' => '1234', 72 | 'displayName' => 'Foo Bar', 73 | ], 74 | [ 75 | 'accountId' => '12345', 76 | 'displayName' => 'Foo Bar2', 77 | ], 78 | ]; 79 | 80 | $this->client->method('exec')->willReturn(json_encode(['values' => $customerData])); 81 | 82 | $result = $this->uut->removeParticipantFromRequest('K-123', [$this->createCustomer(['accountId' => 'la-la'])]); 83 | 84 | $this->assertEquals([$this->createCustomer($customerData[0]), $this->createCustomer($customerData[1])], $result); 85 | } 86 | 87 | private function createCustomer(array $data): Customer 88 | { 89 | $customer = new Customer(); 90 | foreach ($data as $key => $value) { 91 | $customer->$key = $value; 92 | } 93 | 94 | return $customer; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /tests/ServiceDesk/Request/RequestStatusTest.php: -------------------------------------------------------------------------------- 1 | '2022/11/30', 17 | ]; 18 | 19 | $uut = new RequestStatus(); 20 | $uut->setStatusDate($statusDate); 21 | 22 | self::assertInstanceOf(DateTime::class, $uut->statusDate); 23 | self::assertSame($statusDate['iso8601'], $uut->statusDate->format('Y/m/d')); 24 | } 25 | } -------------------------------------------------------------------------------- /tests/ServiceDesk/Request/RequestTest.php: -------------------------------------------------------------------------------- 1 | setRequestTypeId($requestTypeId); 22 | 23 | self::assertSame($requestTypeId, $uut->requestTypeId); 24 | } 25 | 26 | public function testSetCreatedDate(): void 27 | { 28 | $createdDate = new stdClass(); 29 | $createdDate->iso8601 = '2022/05/10'; 30 | 31 | $uut = new Request(); 32 | $uut->setCreatedDate($createdDate); 33 | 34 | self::assertInstanceOf(DateTime::class, $uut->createdDate); 35 | self::assertSame($createdDate->iso8601, $uut->createdDate->format('Y/m/d')); 36 | } 37 | 38 | public function testSetReporter(): void 39 | { 40 | $reporter = new stdClass(); 41 | $reporter->key = '12334221dsf'; 42 | $reporter->name = 'Test reporter'; 43 | 44 | $uut = new Request(); 45 | $uut->setReporter($reporter); 46 | 47 | self::assertInstanceOf(Customer::class, $uut->reporter); 48 | self::assertSame($reporter->key, $uut->reporter->key); 49 | self::assertSame($reporter->name, $uut->reporter->name); 50 | } 51 | 52 | public function testSetSummary(): void 53 | { 54 | $summary = 'Test summary'; 55 | 56 | $uut = new Request(); 57 | $uut->setSummary($summary); 58 | 59 | self::assertArrayHasKey('summary', $uut->requestFieldValues); 60 | self::assertSame($summary, $uut->requestFieldValues['summary']); 61 | } 62 | 63 | public function testSetDescription(): void 64 | { 65 | $description = 'Test description'; 66 | 67 | $uut = new Request(); 68 | $uut->setDescription($description); 69 | 70 | self::assertArrayHasKey('description', $uut->requestFieldValues); 71 | self::assertSame($description, $uut->requestFieldValues['description']); 72 | } 73 | 74 | public function testAddCustomField(): void 75 | { 76 | $key = 'Custom key'; 77 | $value = 'Custom value'; 78 | 79 | $uut = new Request(); 80 | $uut->addCustomField($key, $value); 81 | 82 | self::assertArrayHasKey($key, $uut->requestFieldValues); 83 | self::assertSame($value, $uut->requestFieldValues[$key]); 84 | } 85 | 86 | public function testSetCurrentStatus(): void 87 | { 88 | $currentStatus = new stdClass(); 89 | $currentStatus->status = 'Updated'; 90 | 91 | $uut = new Request(); 92 | $uut->setCurrentStatus($currentStatus); 93 | 94 | self::assertInstanceOf(RequestStatus::class, $uut->currentStatus); 95 | self::assertSame($currentStatus->status, $uut->currentStatus->status); 96 | } 97 | 98 | public function testSetLinks(): void 99 | { 100 | $links = new stdClass(); 101 | $links->values = ['Test link']; 102 | 103 | $uut = new Request(); 104 | $uut->setLinks($links); 105 | 106 | self::assertSame($links, $uut->_links); 107 | } 108 | } -------------------------------------------------------------------------------- /tests/ServiceDesk/ServiceDeskClientTest.php: -------------------------------------------------------------------------------- 1 | createMock(ConfigurationInterface::class); 24 | $configuration->method('getJiraLogEnabled')->willReturn(true); 25 | 26 | $this->logger = $this->createMock(LoggerInterface::class); 27 | 28 | $this->uut = new ServiceDeskClient( 29 | $configuration, 30 | $this->logger 31 | ); 32 | } 33 | 34 | public function tearDown(): void 35 | { 36 | $this->uut = null; 37 | $this->logger = null; 38 | } 39 | 40 | public function testGetLogger(): void 41 | { 42 | $logger = $this->uut->getLogger(); 43 | 44 | self::assertSame($this->logger, $logger); 45 | } 46 | 47 | public function testGetMapper(): void 48 | { 49 | $mapper = $this->uut->getMapper(); 50 | 51 | self::assertInstanceOf(JsonMapper::class, $mapper); 52 | self::assertInstanceOf(JsonMapperHelper::class, $mapper->undefinedPropertyHandler[0]); 53 | self::assertSame('setUndefinedProperty', $mapper->undefinedPropertyHandler[1]); 54 | self::assertSame(DateTime::class, $mapper->classMap['\\' . DateTimeInterface::class]); 55 | } 56 | 57 | public function testCreateUrl(): void 58 | { 59 | $format = 'https://example.com/api/v%d/user/%s'; 60 | $parameters = [ 61 | 1, 62 | 'get', 63 | ]; 64 | 65 | $result = $this->uut->createUrl($format, $parameters); 66 | $expected = 'https://example.com/api/v1/user/get'; 67 | 68 | self::assertSame($expected, $result); 69 | } 70 | 71 | public function testCreateUrlWithUrlParameters(): void 72 | { 73 | $format = 'https://example.com/api/v%d/user/%s'; 74 | $parameters = [ 75 | 1, 76 | 'get', 77 | ]; 78 | $urlParameters = [ 79 | 'start' => 1, 80 | 'amount' => 10, 81 | ]; 82 | 83 | $result = $this->uut->createUrl($format, $parameters, $urlParameters); 84 | $expected = 'https://example.com/api/v1/user/get?start=1&amount=10'; 85 | 86 | self::assertSame($expected, $result); 87 | } 88 | } -------------------------------------------------------------------------------- /tests/StatusTest.php: -------------------------------------------------------------------------------- 1 | getAll(); 15 | foreach ($statuses as $s) { 16 | $this->assertTrue($s instanceof Status); 17 | $this->assertTrue(!empty($s->name) > 0); 18 | $this->assertTrue(!empty($s->id)); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tests/SubTaskTest.php: -------------------------------------------------------------------------------- 1 | setProjectKey('TEST') 20 | ->setSummary("Subtask - something's wrong") 21 | ->setAssigneeName('lesstif') 22 | ->setPriorityName('Critical') 23 | ->setIssueType('Sub-task') 24 | ->setDescription('Subtask - Full description for issue') 25 | ->addVersion('1.0.1') 26 | ->addVersion('1.0.3') 27 | ->setParentKeyOrId($this->issueKey); 28 | 29 | $issueService = new IssueService(); 30 | 31 | $ret = $issueService->create($issueField); 32 | 33 | //If success, Returns a link to the created issue. 34 | print_r($ret); 35 | 36 | $issueKey = $ret->{'key'}; 37 | 38 | return $issueKey; 39 | } catch (JiraException $e) { 40 | $this->assertTrue(false, 'Create Failed : '.$e->getMessage()); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /tests/TimeTrackingTest.php: -------------------------------------------------------------------------------- 1 | getTimeTracking($this->issueKey); 20 | var_dump($ret); 21 | } catch (JiraException $e) { 22 | $this->assertTrue(false, 'testGetTimeTracking Failed : '.$e->getMessage()); 23 | } 24 | } 25 | 26 | public function testPostTimeTracking() 27 | { 28 | $timeTracking = new TimeTracking(); 29 | 30 | $timeTracking->setOriginalEstimate('3w 4d 6h'); 31 | $timeTracking->setRemainingEstimate('1w 2d 3h'); 32 | 33 | try { 34 | $issueService = new IssueService(); 35 | 36 | $ret = $issueService->timeTracking($this->issueKey, $timeTracking); 37 | var_dump($ret); 38 | } catch (JiraException $e) { 39 | $this->assertTrue(false, 'testPostTimeTracking Failed : '.$e->getMessage()); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/UserTest.php: -------------------------------------------------------------------------------- 1 | 'charlie', 24 | 'password' => 'abracadabra', 25 | 'emailAddress' => 'charlie@atlassian.com', 26 | 'displayName' => 'Charlie of Atlassian', 27 | ]; 28 | 29 | // create new user 30 | $user = $us->create($ar); 31 | 32 | $this->assertEquals($user->name, $ar['name']); 33 | $this->assertEquals($user->emailAddress, $ar['emailAddress']); 34 | 35 | } catch (JiraException $e) { 36 | $this->fail('testGetUser Failed : '.$e->getMessage()); 37 | } 38 | 39 | return $user; 40 | } 41 | 42 | /** 43 | * @test 44 | * @depends create_user 45 | */ 46 | public function get_user_info(User $user) : User 47 | { 48 | try { 49 | $us = new UserService(); 50 | 51 | // get the user info. 52 | $user = $us->get(['username' => $user->name]); 53 | 54 | $this->assertNotNull($user); 55 | 56 | 57 | } catch (JiraException $e) { 58 | $this->fail('testGetUser Failed : '.$e->getMessage()); 59 | } 60 | 61 | return $user; 62 | } 63 | 64 | /** 65 | * @test 66 | * @depends get_user_info 67 | */ 68 | public function testAddUser(User $user) : User 69 | { 70 | $this->markTestSkipped('not yet implemented'); 71 | } 72 | 73 | /** 74 | * @test 75 | * @depends get_user_info 76 | */ 77 | public function search_user(User $user) : User 78 | { 79 | try { 80 | $us = new UserService(); 81 | 82 | $paramArray = [ 83 | 'username' => '.', // . means all users 84 | 'startAt' => 0, 85 | 'maxResults' => 1000, 86 | 'includeInactive' => true, 87 | //'property' => '*', 88 | ]; 89 | 90 | // get the user info. 91 | $users = $us->findUsers($paramArray); 92 | 93 | $this->assertIsArray($users); 94 | 95 | } catch (JiraException $e) { 96 | $this->fail('testGetUser Failed : '.$e->getMessage()); 97 | } 98 | 99 | return $user; 100 | } 101 | 102 | /** 103 | * @test 104 | * @depends search_user 105 | */ 106 | public function search_assignable(User $user) : User 107 | { 108 | try { 109 | $us = new UserService(); 110 | 111 | $paramArray = [ 112 | //'username' => null, 113 | 'project' => 'TEST', 114 | //'issueKey' => 'TEST-1', 115 | 'startAt' => 0, 116 | 'maxResults' => 1000, 117 | //'actionDescriptorId' => 1, 118 | ]; 119 | 120 | // get the user info. 121 | $users = $us->findAssignableUsers($paramArray); 122 | 123 | $this->assertIsArray($users); 124 | $this->assertGreaterThan(1, count($users)); 125 | 126 | } catch (JiraException $e) { 127 | $this->fail('testSearchAssignable Failed : '.$e->getMessage()); 128 | } 129 | 130 | return $user; 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /tests/VersionTest.php: -------------------------------------------------------------------------------- 1 | get($this->project); 26 | 27 | $versionService = new VersionService(); 28 | 29 | $version = new Version(); 30 | 31 | $version->setName($versionName) 32 | ->setDescription('Generated by script') 33 | ->setReleased(false) 34 | ->setUserStartDateAsDateTime(new \DateTime()) 35 | ->setReleaseDateAsDateTime((new \DateTime())->add(date_interval_create_from_date_string('2 weeks 3 days'))) 36 | ->setProjectId($project->id); 37 | 38 | $res = $versionService->create($version); 39 | 40 | $this->assertEquals($res->name, $versionName); 41 | } catch (JiraException $e) { 42 | $this->fail("Error Occurred! " . $e->getMessage()); 43 | } 44 | 45 | return $versionName; 46 | } 47 | 48 | /** 49 | * @test 50 | * @depends create_version 51 | * 52 | */ 53 | public function update_project_version(string $versionName) : string 54 | { 55 | $newVersionName = null; 56 | try { 57 | $versionService = new VersionService(); 58 | $projectService = new ProjectService(); 59 | 60 | $ver = $projectService->getVersion($this->project, $versionName); 61 | 62 | // update version 63 | $ver->setName($ver->name . ' Updated name') 64 | ->setDescription($ver->description . ' Updated description') 65 | ->setReleased(false) 66 | ->setStartDateAsDateTime(new \DateTime()) 67 | ->setReleaseDateAsDateTime( 68 | (new \DateTime())->add(date_interval_create_from_date_string('1 months 3 days')) 69 | ) 70 | ; 71 | 72 | $res = $versionService->update($ver); 73 | 74 | $this->assertEquals($res->name, $ver->name); 75 | 76 | $newVersionName = $res->name; 77 | } catch (JiraException $e) { 78 | $this->fail("Error Occurred! " . $e->getMessage()); 79 | } 80 | 81 | return $newVersionName; 82 | } 83 | 84 | /** 85 | * @test 86 | * @depends update_project_version 87 | */ 88 | public function delete_project_version(string $versionName) : string 89 | { 90 | try { 91 | $versionService = new VersionService(); 92 | $projectService = new ProjectService(); 93 | 94 | $ver = $projectService->getVersion($this->project, $versionName); 95 | 96 | $res = $versionService->delete($ver); 97 | 98 | $this->assertEquals(true, $res); 99 | } catch (JiraException $e) { 100 | $this->fail("Error Occurred! " . $e->getMessage()); 101 | } 102 | 103 | return $versionName; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /tests/WatcherLogTest.php: -------------------------------------------------------------------------------- 1 | addWatcher($this->issueKey, 'lesstif'); 21 | 22 | Dumper::dump($ret); 23 | } catch (JiraException $e) { 24 | $this->assertTrue(false, 'testAddWatcherLog Failed : '.$e->getMessage()); 25 | } 26 | } 27 | 28 | public function testRemoveWatcherLog() 29 | { 30 | try { 31 | $issueService = new IssueService(); 32 | 33 | // remove issue watcher 34 | $ret = $issueService->removeWatcher($this->issueKey, 'lesstif'); 35 | 36 | Dumper::dump($ret); 37 | } catch (JiraException $e) { 38 | $this->assertTrue(false, 'testRemoveWatcherLog Failed : '.$e->getMessage()); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tests/WorkLogTest.php: -------------------------------------------------------------------------------- 1 | getWorklog($this->issueKey); 22 | $worklogs = $pwl->getWorklogs(); 23 | 24 | Dumper::dump($worklogs); 25 | } catch (JiraException $e) { 26 | $this->assertTrue(false, 'testGetWorkLog Failed : '.$e->getMessage()); 27 | } 28 | } 29 | 30 | /** 31 | * @depends testGetWorkLog 32 | */ 33 | public function testAddWorkLogInIssue() 34 | { 35 | try { 36 | $workLog = new Worklog(); 37 | 38 | $workLog->setComment('I did some work here.') 39 | ->setStarted('2016-05-28 12:35:54') 40 | ->setTimeSpent('1d 2h 3m'); 41 | 42 | $issueService = new IssueService(); 43 | 44 | $ret = $issueService->addWorklog($this->issueKey, $workLog); 45 | 46 | Dumper::dump($ret); 47 | 48 | $workLogid = $ret->{'id'}; 49 | 50 | return $workLogid; 51 | } catch (JiraException $e) { 52 | $this->assertTrue(false, 'Create Failed : '.$e->getMessage()); 53 | } 54 | } 55 | 56 | /** 57 | * @depends testAddWorkLogInIssue 58 | */ 59 | public function testEditWorkLogInIssue($workLogid) 60 | { 61 | try { 62 | $workLog = new Worklog(); 63 | 64 | $workLog->setComment('I did edit previous worklog here.') 65 | ->setStarted('2016-05-29 13:41:12') 66 | ->setTimeSpent('2d 7h 5m'); 67 | 68 | $issueService = new IssueService(); 69 | 70 | $ret = $issueService->editWorklog($this->issueKey, $workLog, $workLogid); 71 | 72 | Dumper::dump($ret); 73 | 74 | $workLogid = $ret->{'id'}; 75 | 76 | return $workLogid; 77 | } catch (JiraException $e) { 78 | $this->assertTrue(false, 'Create Failed : '.$e->getMessage()); 79 | } 80 | } 81 | 82 | /** 83 | * @depends testUpdateWorkLogInIssue 84 | */ 85 | public function testGetWorkLogById($workLogid) 86 | { 87 | try { 88 | $issueService = new IssueService(); 89 | 90 | $worklog = $issueService->getWorklogById($this->issueKey, $workLogid); 91 | 92 | Dumper::dump($worklog); 93 | } catch (JiraException $e) { 94 | $this->assertTrue(false, 'testGetWorkLogById Failed : '.$e->getMessage()); 95 | } 96 | } 97 | 98 | /** 99 | * @depends testUpdateWorkLogInIssue 100 | */ 101 | public function testGetWorkLogsByIds($workLogid) 102 | { 103 | try { 104 | $issueService = new IssueService(); 105 | 106 | $worklogs = $issueService->getWorklogsByIds([$workLogid]); 107 | 108 | Dumper::dump($worklogs); 109 | } catch (JiraException $e) { 110 | $this->assertTrue(false, 'testGetWorkLogsByIds Failed : '.$e->getMessage()); 111 | } 112 | } 113 | 114 | /** 115 | * @depends testUpdateWorkLogInIssue 116 | */ 117 | public function testDeleteWorkLogById($workLogid) 118 | { 119 | try { 120 | $issueService = new IssueService(); 121 | 122 | $worklog = $issueService->deleteWorklog($this->issueKey, $workLogid); 123 | 124 | Dumper::dump($worklog); 125 | } catch (JiraException $e) { 126 | $this->assertTrue(false, 'testDeleteWorkLogById Failed : '.$e->getMessage()); 127 | } 128 | } 129 | } 130 | --------------------------------------------------------------------------------