Completed
Push — master ( 9d6cd2...1aa205 )
by KwangSeob
15s queued 12s
created

IssueService::removeRemoteIssueLink()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 10
nc 1
nop 2
dl 0
loc 18
rs 9.9332
c 0
b 0
f 0
1
<?php
2
3
namespace JiraRestApi\Issue;
4
5
use JiraRestApi\JiraException;
6
7
class IssueService extends \JiraRestApi\JiraClient
8
{
9
    private $uri = '/issue';
10
11
    /**
12
     * @param $json
13
     *
14
     * @throws \JsonMapper_Exception
15
     *
16
     * @return Issue|object
17
     */
18
    public function getIssueFromJSON($json)
19
    {
20
        $issue = $this->json_mapper->map(
21
            $json, new Issue()
22
        );
23
24
        return $issue;
25
    }
26
27
    /**
28
     *  get all project list.
29
     *
30
     * @param string|int $issueIdOrKey
31
     * @param array      $paramArray   Query Parameter key-value Array.
32
     * @param Issue      $issueObject
33
     *
34
     * @throws JiraException
35
     * @throws \JsonMapper_Exception
36
     *
37
     * @return Issue|object class
38
     */
39
    public function get($issueIdOrKey, $paramArray = [], $issueObject = null)
40
    {
41
        $issueObject = ($issueObject) ? $issueObject : new Issue();
42
43
        $ret = $this->exec($this->uri.'/'.$issueIdOrKey.$this->toHttpQueryParameter($paramArray), null);
44
45
        $this->log->info("Result=\n".$ret);
46
47
        return $issue = $this->json_mapper->map(
0 ignored issues
show
Unused Code introduced by
The assignment to $issue is dead and can be removed.
Loading history...
48
            json_decode($ret), $issueObject
49
        );
50
    }
51
52
    /**
53
     * create new issue.
54
     *
55
     * @param IssueField $issueField
56
     *
57
     * @throws JiraException
58
     * @throws \JsonMapper_Exception
59
     *
60
     * @return Issue|object created issue key
61
     */
62
    public function create($issueField)
63
    {
64
        $issue = new Issue();
65
66
        // serilize only not null field.
67
        $issue->fields = $issueField;
68
69
        $data = json_encode($issue);
70
71
        $this->log->info("Create Issue=\n".$data);
72
73
        $ret = $this->exec($this->uri, $data, 'POST');
74
75
        return $this->getIssueFromJSON(json_decode($ret));
76
    }
77
78
    /**
79
     * Create multiple issues using bulk insert.
80
     *
81
     * @param IssueField[] $issueFields Array of IssueField objects
82
     * @param int          $batchSize   Maximum number of issues to send in each request
83
     *
84
     * @throws JiraException
85
     * @throws \JsonMapper_Exception
86
     *
87
     * @return array Array of results, where each result represents one batch of insertions
88
     */
89
    public function createMultiple($issueFields, $batchSize = 50)
90
    {
91
        $issues = [];
92
93
        foreach ($issueFields as $issueField) {
94
            $issue = new Issue();
95
            $issue->fields = $issueField;
96
            $issues[] = $issue;
97
        }
98
99
        $batches = array_chunk($issues, $batchSize);
100
101
        $results = [];
102
        foreach ($batches as $batch) {
103
            $results = array_merge($results, $this->bulkInsert($batch));
104
        }
105
106
        return $results;
107
    }
108
109
    /**
110
     * Makes API call to bulk insert issues.
111
     *
112
     * @param Issue[] $issues Array of issue arrays that are sent to Jira one by one in single create
113
     *
114
     * @throws JiraException
115
     * @throws \JsonMapper_Exception
116
     *
117
     * @return Issue[] Result of API call to insert many issues
118
     */
119
    private function bulkInsert($issues)
120
    {
121
        $data = json_encode(['issueUpdates' => $issues]);
122
123
        $this->log->info("Create Issues=\n".$data);
124
        $results = $this->exec($this->uri.'/bulk', $data, 'POST');
125
126
        $issues = [];
127
        foreach (json_decode($results)->issues as $result) {
128
            $issues[] = $this->getIssueFromJSON($result);
129
        }
130
131
        return $issues;
132
    }
133
134
    /**
135
     * Add one or more file to an issue.
136
     *
137
     * @param string|int   $issueIdOrKey  Issue id or key
138
     * @param array|string $filePathArray attachment file path.
139
     *
140
     * @throws JiraException
141
     * @throws \JsonMapper_Exception
142
     *
143
     * @return Attachment[]
144
     */
145
    public function addAttachments($issueIdOrKey, $filePathArray)
146
    {
147
        if (is_array($filePathArray) == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
148
            $filePathArray = [$filePathArray];
149
        }
150
151
        $results = $this->upload($this->uri."/$issueIdOrKey/attachments", $filePathArray);
0 ignored issues
show
Bug introduced by
It seems like $filePathArray can also be of type string; however, parameter $filePathArray of JiraRestApi\JiraClient::upload() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

151
        $results = $this->upload($this->uri."/$issueIdOrKey/attachments", /** @scrutinizer ignore-type */ $filePathArray);
Loading history...
152
153
        $this->log->info('addAttachments result='.var_export($results, true));
154
155
        $attachArr = [];
156
        foreach ($results as $ret) {
157
            $ret = json_decode($ret);
158
            if (is_array($ret)) {
159
                $tmpArr = $this->json_mapper->mapArray(
160
                    $ret, new \ArrayObject(), '\JiraRestApi\Issue\Attachment'
161
                );
162
163
                foreach ($tmpArr as $t) {
164
                    array_push($attachArr, $t);
165
                }
166
            } elseif (is_object($ret)) {
167
                array_push($attachArr, $this->json_mapper->map(
168
                    $ret, new Attachment()
169
                    )
170
                );
171
            }
172
        }
173
174
        return $attachArr;
175
    }
176
177
    /**
178
     * update issue.
179
     *
180
     * @param string|int $issueIdOrKey Issue Key
181
     * @param IssueField $issueField   object of Issue class
182
     * @param array      $paramArray   Query Parameter key-value Array.
183
     *
184
     * @throws JiraException
185
     *
186
     * @return string created issue key
187
     */
188
    public function update($issueIdOrKey, $issueField, $paramArray = [])
189
    {
190
        $issue = new Issue();
191
192
        // serilize only not null field.
193
        $issue->fields = $issueField;
194
195
        //$issue = $this->filterNullVariable((array)$issue);
196
197
        $data = json_encode($issue);
198
199
        $this->log->info("Update Issue=\n".$data);
200
201
        $queryParam = '?'.http_build_query($paramArray);
202
203
        $ret = $this->exec($this->uri."/$issueIdOrKey".$queryParam, $data, 'PUT');
204
205
        return $ret;
206
    }
207
208
    /**
209
     * Adds a new comment to an issue.
210
     *
211
     * @param string|int $issueIdOrKey Issue id or key
212
     * @param string     $comment
213
     *
214
     * @throws JiraException
215
     * @throws \JsonMapper_Exception
216
     *
217
     * @return Comment|object Comment class
218
     */
219
    public function addComment($issueIdOrKey, $comment)
220
    {
221
        $this->log->info("addComment=\n");
222
223
        $data = json_encode($comment);
224
225
        $ret = $this->exec($this->uri."/$issueIdOrKey/comment", $data);
226
227
        $this->log->debug('add comment result='.var_export($ret, true));
228
        $comment = $this->json_mapper->map(
229
           json_decode($ret), new Comment()
230
        );
231
232
        return $comment;
233
    }
234
235
    /**
236
     * Update a comment in issue.
237
     *
238
     * @param string|int $issueIdOrKey Issue id or key
239
     * @param string|int $id           Comment id
240
     * @param string     $comment
241
     *
242
     * @throws JiraException
243
     * @throws \JsonMapper_Exception
244
     *
245
     * @return Comment|object Comment class
246
     */
247
    public function updateComment($issueIdOrKey, $id, $comment)
248
    {
249
        $this->log->info("updateComment=\n");
250
251
        $data = json_encode($comment);
252
253
        $ret = $this->exec($this->uri."/$issueIdOrKey/comment/$id", $data, 'PUT');
254
255
        $this->log->debug('update comment result='.var_export($ret, true));
256
        $comment = $this->json_mapper->map(
257
            json_decode($ret), new Comment()
258
        );
259
260
        return $comment;
261
    }
262
263
    /**
264
     * Get a comment on an issue.
265
     *
266
     * @param string|int $issueIdOrKey Issue id or key
267
     * @param string|int $id           Comment id
268
     *
269
     * @throws JiraException
270
     * @throws \JsonMapper_Exception
271
     *
272
     * @return Comment|object Comment class
273
     */
274
    public function getComment($issueIdOrKey, $id)
275
    {
276
        $this->log->info("getComment=\n");
277
278
        $ret = $this->exec($this->uri."/$issueIdOrKey/comment/$id");
279
280
        $this->log->debug('get comment result='.var_export($ret, true));
281
        $comment = $this->json_mapper->map(
282
                json_decode($ret), new Comment()
283
                );
284
285
        return $comment;
286
    }
287
288
    /**
289
     * Get all comments on an issue.
290
     *
291
     * @param string|int $issueIdOrKey Issue id or key
292
     *
293
     * @throws JiraException
294
     * @throws \JsonMapper_Exception
295
     *
296
     * @return Comment|object Comment class
297
     */
298
    public function getComments($issueIdOrKey)
299
    {
300
        $this->log->info("getComments=\n");
301
302
        $ret = $this->exec($this->uri."/$issueIdOrKey/comment");
303
304
        $this->log->debug('get comments result='.var_export($ret, true));
305
        $comment = $this->json_mapper->map(
306
                json_decode($ret), new Comment()
307
                );
308
309
        return $comment;
310
    }
311
312
    /**
313
     * Delete a comment on an issue.
314
     *
315
     * @param string|int $issueIdOrKey Issue id or key
316
     * @param string|int $id           Comment id
317
     *
318
     * @throws JiraException
319
     *
320
     * @return string|bool
321
     */
322
    public function deleteComment($issueIdOrKey, $id)
323
    {
324
        $this->log->info("deleteComment=\n");
325
326
        $ret = $this->exec($this->uri."/$issueIdOrKey/comment/$id", '', 'DELETE');
327
328
        $this->log->info('delete comment '.$issueIdOrKey.' '.$id.' result='.var_export($ret, true));
329
330
        return $ret;
331
    }
332
333
    /**
334
     * Change a issue assignee.
335
     *
336
     * @param string|int  $issueIdOrKey
337
     * @param string|null $assigneeName Assigns an issue to a user.
338
     *                                  If the assigneeName is "-1" automatic assignee is used.
339
     *                                  A null name will remove the assignee.
340
     *
341
     * @throws JiraException
342
     *
343
     * @return string|bool
344
     */
345
    public function changeAssignee($issueIdOrKey, $assigneeName)
346
    {
347
        $this->log->info("changeAssignee=\n");
348
349
        $ar = ['name' => $assigneeName];
350
351
        $data = json_encode($ar);
352
353
        $ret = $this->exec($this->uri."/$issueIdOrKey/assignee", $data, 'PUT');
354
355
        $this->log->info('change assignee of '.$issueIdOrKey.' to '.$assigneeName.' result='.var_export($ret, true));
356
357
        return $ret;
358
    }
359
360
    /**
361
     * Delete a issue.
362
     *
363
     * @param string|int $issueIdOrKey Issue id or key
364
     * @param array      $paramArray   Query Parameter key-value Array.
365
     *
366
     * @throws JiraException
367
     *
368
     * @return string|bool
369
     */
370
    public function deleteIssue($issueIdOrKey, $paramArray = [])
371
    {
372
        $this->log->info("deleteIssue=\n");
373
374
        $queryParam = '?'.http_build_query($paramArray);
375
376
        $ret = $this->exec($this->uri."/$issueIdOrKey".$queryParam, '', 'DELETE');
377
378
        $this->log->info('delete issue '.$issueIdOrKey.' result='.var_export($ret, true));
379
380
        return $ret;
381
    }
382
383
    /**
384
     * Get a list of the transitions possible for this issue by the current user, along with fields that are required and their types.
385
     *
386
     * @param string|int $issueIdOrKey Issue id or key
387
     *
388
     * @throws JiraException
389
     *
390
     * @return Transition[] array of Transition class
391
     */
392
    public function getTransition($issueIdOrKey)
393
    {
394
        $ret = $this->exec($this->uri."/$issueIdOrKey/transitions");
395
396
        $this->log->debug('getTransitions result='.var_export($ret, true));
397
398
        $data = json_encode(json_decode($ret)->transitions);
399
400
        $transitions = $this->json_mapper->mapArray(
401
           json_decode($data), new \ArrayObject(), '\JiraRestApi\Issue\Transition'
402
        );
403
404
        return $transitions;
405
    }
406
407
    /**
408
     * find transition id by transition's to field name(aka 'Resolved').
409
     *
410
     * @param string|int $issueIdOrKey
411
     * @param string     $transitionToName
412
     *
413
     * @throws JiraException
414
     *
415
     * @return string
416
     */
417
    public function findTransitonId($issueIdOrKey, $transitionToName)
418
    {
419
        $this->log->debug('findTransitonId=');
420
421
        $ret = $this->getTransition($issueIdOrKey);
422
423
        foreach ($ret as $trans) {
424
            $toName = $trans->to->name;
425
426
            $this->log->debug('getTransitions result='.var_export($ret, true));
427
428
            if (strcmp($toName, $transitionToName) == 0) {
429
                return $trans->id;
430
            }
431
        }
432
433
        // transition keyword not found
434
        throw new JiraException("Transition name '$transitionToName' not found on JIRA Server.");
435
    }
436
437
    /**
438
     * Perform a transition on an issue.
439
     *
440
     * @param string|int $issueIdOrKey Issue id or key
441
     * @param Transition $transition
442
     *
443
     * @throws JiraException
444
     *
445
     * @return string|null nothing - if transition was successful return http 204(no contents)
446
     */
447
    public function transition($issueIdOrKey, $transition)
448
    {
449
        $this->log->debug('transition='.var_export($transition, true));
450
451
        if (!isset($transition->transition['id'])) {
452
            $transition->transition['id'] = $this->findTransitonId($issueIdOrKey, $transition->transition['name']);
453
        }
454
455
        $data = json_encode($transition);
456
457
        $this->log->debug("transition req=$data\n");
458
459
        $ret = $this->exec($this->uri."/$issueIdOrKey/transitions", $data, 'POST');
460
461
        $this->log->debug('getTransitions result='.var_export($ret, true));
462
463
        return $ret;
464
    }
465
466
    /**
467
     * Search issues.
468
     *
469
     * @param string $jql
470
     * @param int    $startAt
471
     * @param int    $maxResults
472
     * @param array  $fields
473
     * @param array  $expand
474
     * @param bool   $validateQuery
475
     *
476
     * @throws JiraException
477
     * @throws \JsonMapper_Exception
478
     *
479
     * @return IssueSearchResult|object
480
     */
481
    public function search($jql, $startAt = 0, $maxResults = 15, $fields = [], $expand = [], $validateQuery = true)
482
    {
483
        $data = json_encode([
484
            'jql'           => $jql,
485
            'startAt'       => $startAt,
486
            'maxResults'    => $maxResults,
487
            'fields'        => $fields,
488
            'expand'        => $expand,
489
            'validateQuery' => $validateQuery,
490
        ]);
491
492
        $ret = $this->exec('search', $data, 'POST');
493
        $json = json_decode($ret);
494
495
        $result = $this->json_mapper->map(
496
            $json, new IssueSearchResult()
497
        );
498
499
        return $result;
500
    }
501
502
    /**
503
     * get TimeTracking info.
504
     *
505
     * @param string|int $issueIdOrKey
506
     *
507
     * @throws JiraException
508
     * @throws \JsonMapper_Exception
509
     *
510
     * @return TimeTracking
511
     */
512
    public function getTimeTracking($issueIdOrKey)
513
    {
514
        $ret = $this->exec($this->uri."/$issueIdOrKey", null);
515
        $this->log->debug("getTimeTracking res=$ret\n");
516
517
        $issue = $this->json_mapper->map(
518
             json_decode($ret), new Issue()
519
        );
520
521
        return $issue->fields->timeTracking;
522
    }
523
524
    /**
525
     * TimeTracking issues.
526
     *
527
     * @param string|int   $issueIdOrKey Issue id or key
528
     * @param TimeTracking $timeTracking
529
     *
530
     * @throws JiraException
531
     *
532
     * @return string
533
     */
534
    public function timeTracking($issueIdOrKey, $timeTracking)
535
    {
536
        $array = [
537
            'update' => [
538
                'timetracking' => [
539
                    ['edit' => $timeTracking],
540
                ],
541
            ],
542
        ];
543
544
        $data = json_encode($array);
545
546
        $this->log->debug("TimeTracking req=$data\n");
547
548
        // if success, just return HTTP 201.
549
        $ret = $this->exec($this->uri."/$issueIdOrKey", $data, 'PUT');
550
551
        return $ret;
552
    }
553
554
    /**
555
     * get getWorklog.
556
     *
557
     * @param string|int $issueIdOrKey
558
     *
559
     * @throws JiraException
560
     * @throws \JsonMapper_Exception
561
     *
562
     * @return PaginatedWorklog|object
563
     */
564
    public function getWorklog($issueIdOrKey)
565
    {
566
        $ret = $this->exec($this->uri."/$issueIdOrKey/worklog");
567
        $this->log->debug("getWorklog res=$ret\n");
568
        $worklog = $this->json_mapper->map(
569
            json_decode($ret), new PaginatedWorklog()
570
        );
571
572
        return $worklog;
573
    }
574
575
    /**
576
     * get getWorklog by Id.
577
     *
578
     * @param string|int $issueIdOrKey
579
     * @param int        $workLogId
580
     *
581
     * @throws JiraException
582
     * @throws \JsonMapper_Exception
583
     *
584
     * @return Worklog|object PaginatedWorklog object
585
     */
586
    public function getWorklogById($issueIdOrKey, $workLogId)
587
    {
588
        $ret = $this->exec($this->uri."/$issueIdOrKey/worklog/$workLogId");
589
        $this->log->debug("getWorklogById res=$ret\n");
590
        $worklog = $this->json_mapper->map(
591
            json_decode($ret), new Worklog()
592
        );
593
594
        return $worklog;
595
    }
596
597
    /**
598
     * add work log to issue.
599
     *
600
     * @param string|int     $issueIdOrKey
601
     * @param Worklog|object $worklog
602
     *
603
     * @throws JiraException
604
     * @throws \JsonMapper_Exception
605
     *
606
     * @return Worklog|object Worklog Object
607
     */
608
    public function addWorklog($issueIdOrKey, $worklog)
609
    {
610
        $this->log->info("addWorklog=\n");
611
612
        $data = json_encode($worklog);
613
        $url = $this->uri."/$issueIdOrKey/worklog";
614
        $type = 'POST';
615
616
        $ret = $this->exec($url, $data, $type);
617
618
        $ret_worklog = $this->json_mapper->map(
619
           json_decode($ret), new Worklog()
620
        );
621
622
        return $ret_worklog;
623
    }
624
625
    /**
626
     * edit the worklog.
627
     *
628
     * @param string|int     $issueIdOrKey
629
     * @param Worklog|object $worklog
630
     * @param string|int     $worklogId
631
     *
632
     * @throws JiraException
633
     * @throws \JsonMapper_Exception
634
     *
635
     * @return Worklog|object
636
     */
637
    public function editWorklog($issueIdOrKey, $worklog, $worklogId)
638
    {
639
        $this->log->info("editWorklog=\n");
640
641
        $data = json_encode($worklog);
642
        $url = $this->uri."/$issueIdOrKey/worklog/$worklogId";
643
        $type = 'PUT';
644
645
        $ret = $this->exec($url, $data, $type);
646
647
        $ret_worklog = $this->json_mapper->map(
648
            json_decode($ret), new Worklog()
649
        );
650
651
        return $ret_worklog;
652
    }
653
654
    /**
655
     * Get all priorities.
656
     *
657
     * @throws JiraException
658
     *
659
     * @return Priority[] array of priority class
660
     */
661
    public function getAllPriorities()
662
    {
663
        $ret = $this->exec('priority', null);
664
665
        $priorities = $this->json_mapper->mapArray(
666
             json_decode($ret, false), new \ArrayObject(), '\JiraRestApi\Issue\Priority'
667
        );
668
669
        return $priorities;
670
    }
671
672
    /**
673
     * Get priority by id.
674
     * throws  HTTPException if the priority is not found, or the calling user does not have permission or view it.
675
     *
676
     * @param string|int $priorityId Id of priority.
677
     *
678
     * @throws JiraException
679
     * @throws \JsonMapper_Exception
680
     *
681
     * @return Priority|object priority
682
     */
683
    public function getPriority($priorityId)
684
    {
685
        $ret = $this->exec("priority/$priorityId", null);
686
687
        $this->log->info('Result='.$ret);
688
689
        $prio = $this->json_mapper->map(
690
             json_decode($ret), new Priority()
691
        );
692
693
        return $prio;
694
    }
695
696
    /**
697
     * Get priority by id.
698
     * throws HTTPException if the priority is not found, or the calling user does not have permission or view it.
699
     *
700
     * @param string|int $priorityId Id of priority.
701
     *
702
     * @throws JiraException
703
     * @throws \JsonMapper_Exception
704
     *
705
     * @return Priority|object priority
706
     */
707
    public function getCustomFields($priorityId)
708
    {
709
        $ret = $this->exec("priority/$priorityId", null);
710
711
        $this->log->info('Result='.$ret);
712
713
        $prio = $this->json_mapper->map(
714
            json_decode($ret), new Priority()
715
        );
716
717
        return $prio;
718
    }
719
720
    /**
721
     * get watchers.
722
     *
723
     * @param $issueIdOrKey
724
     *
725
     * @throws JiraException
726
     *
727
     * @return Reporter[]
728
     */
729
    public function getWatchers($issueIdOrKey)
730
    {
731
        $this->log->info("getWatchers=\n");
732
733
        $url = $this->uri."/$issueIdOrKey/watchers";
734
735
        $ret = $this->exec($url, null);
736
737
        $watchers = $this->json_mapper->mapArray(
738
            json_decode($ret, false)->watchers, new \ArrayObject(), '\JiraRestApi\Issue\Reporter'
739
        );
740
741
        return $watchers;
742
    }
743
744
    /**
745
     * add watcher to issue.
746
     *
747
     * @param string|int $issueIdOrKey
748
     * @param string     $watcher      watcher id
749
     *
750
     * @throws JiraException
751
     *
752
     * @return bool
753
     */
754
    public function addWatcher($issueIdOrKey, $watcher)
755
    {
756
        $this->log->info("addWatcher=\n");
757
758
        $data = json_encode($watcher);
759
        $url = $this->uri."/$issueIdOrKey/watchers";
760
        $type = 'POST';
761
762
        $this->exec($url, $data, $type);
763
764
        return $this->http_response == 204 ? true : false;
765
    }
766
767
    /**
768
     * remove watcher from issue.
769
     *
770
     * @param string|int $issueIdOrKey
771
     * @param string     $watcher      watcher id
772
     *
773
     * @throws JiraException
774
     *
775
     * @return bool
776
     */
777
    public function removeWatcher($issueIdOrKey, $watcher)
778
    {
779
        $this->log->addInfo("removeWatcher=\n");
780
781
        $ret = $this->exec($this->uri."/$issueIdOrKey/watchers/?username=$watcher", '', 'DELETE');
782
783
        $this->log->addInfo('remove watcher '.$issueIdOrKey.' result='.var_export($ret, true));
784
785
        return $this->http_response == 204 ? true : false;
786
    }
787
788
    /**
789
     * Get the meta data for creating issues.
790
     *
791
     * @param array $paramArray Possible keys for $paramArray: 'projectIds', 'projectKeys', 'issuetypeIds', 'issuetypeNames'.
792
     * @param bool  $expand     Retrieve all issue fields and values
793
     *
794
     * @throws JiraException
795
     *
796
     * @return object array of meta data for creating issues.
797
     */
798
    public function getCreateMeta($paramArray = [], $expand = true)
799
    {
800
        $paramArray['expand'] = ($expand) ? 'projects.issuetypes.fields' : null;
801
        $paramArray = array_filter($paramArray);
802
803
        $queryParam = '?'.http_build_query($paramArray);
804
805
        $ret = $this->exec($this->uri.'/createmeta'.$queryParam, null);
806
807
        return json_decode($ret);
808
    }
809
810
    /**
811
     * returns the metadata(include custom field) for an issue.
812
     *
813
     * @param string $idOrKey                issue id or key
814
     * @param bool   $overrideEditableFlag   Allows retrieving edit metadata for fields in non-editable status
815
     * @param bool   $overrideScreenSecurity Allows retrieving edit metadata for the fields hidden on Edit screen.
816
     *
817
     * @throws JiraException
818
     *
819
     * @return array of custom fields
820
     *
821
     * @see https://confluence.atlassian.com/jirakb/how-to-retrieve-available-options-for-a-multi-select-customfield-via-jira-rest-api-815566715.html How to retrieve available options for a multi-select customfield via JIRA REST API
822
     * @see https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-issue-issueIdOrKey-editmeta-get
823
     */
824
    public function getEditMeta($idOrKey, $overrideEditableFlag = false, $overrideScreenSecurity = false)
825
    {
826
        $queryParam = '?'.http_build_query([
827
            'overrideEditableFlag'   => $overrideEditableFlag,
828
            'overrideScreenSecurity' => $overrideScreenSecurity,
829
            ]);
830
831
        $uri = sprintf('%s/%s/editmeta', $this->uri, $idOrKey).$queryParam;
832
833
        $ret = $this->exec($uri, null);
834
835
        $metas = json_decode($ret, true);
836
837
        // extract only custom field(startWith customefield_XXXXX)
838
        $cfs = array_filter($metas['fields'], function ($key) {
839
            $pos = strpos($key, 'customfield');
840
841
            return $pos !== false;
842
        }, ARRAY_FILTER_USE_KEY);
843
844
        return $cfs;
845
    }
846
847
    /**
848
     * Sends a notification (email) to the list or recipients defined in the request.
849
     *
850
     * @param string|int $issueIdOrKey Issue id Or Key
851
     * @param Notify     $notify
852
     *
853
     * @throws JiraException
854
     *
855
     * @see https://docs.atlassian.com/software/jira/docs/api/REST/latest/#api/2/issue-notify
856
     */
857
    public function notify($issueIdOrKey, $notify)
858
    {
859
        $full_uri = $this->uri."/$issueIdOrKey/notify";
860
861
        // set self value
862
        foreach ($notify->to['groups'] as &$g) {
863
            $g['self'] = $this->getConfiguration()->getJiraHost().'/rest/api/2/group?groupname='.$g['name'];
864
        }
865
        foreach ($notify->restrict['groups'] as &$g) {
866
            $g['self'] = $this->getConfiguration()->getJiraHost().'/rest/api/2/group?groupname='.$g['name'];
867
        }
868
869
        $data = json_encode($notify, JSON_UNESCAPED_SLASHES);
870
871
        $this->log->debug("notify=$data\n");
872
873
        $ret = $this->exec($full_uri, $data, 'POST');
874
875
        if ($ret !== true) {
0 ignored issues
show
introduced by
The condition $ret !== true is always true.
Loading history...
876
            throw new JiraException('notify failed: response code='.$ret);
877
        }
878
    }
879
880
    /**
881
     * Get a remote issue links on the issue.
882
     *
883
     * @param string|int $issueIdOrKey Issue id Or Key
884
     *
885
     * @throws JiraException
886
     *
887
     * @return array array os RemoteIssueLink class
888
     *
889
     * @see https://developer.atlassian.com/server/jira/platform/jira-rest-api-for-remote-issue-links/
890
     * @see https://docs.atlassian.com/software/jira/docs/api/REST/latest/#api/2/issue-getRemoteIssueLinks
891
     */
892
    public function getRemoteIssueLink($issueIdOrKey)
893
    {
894
        $full_uri = $this->uri."/$issueIdOrKey/remotelink";
895
896
        $ret = $this->exec($full_uri, null);
897
898
        $rils = $this->json_mapper->mapArray(
899
            json_decode($ret, false), new \ArrayObject(), RemoteIssueLink::class
900
        );
901
902
        return $rils;
903
    }
904
905
    /**
906
     * @param string|int      $issueIdOrKey
907
     * @param RemoteIssueLink $ril
908
     *
909
     * @throws JiraException
910
     * @throws \JsonMapper_Exception
911
     *
912
     * @return object
913
     */
914
    public function createOrUpdateRemoteIssueLink($issueIdOrKey, RemoteIssueLink $ril)
915
    {
916
        $full_uri = $this->uri."/$issueIdOrKey/remotelink";
917
918
        $data = json_encode($ril, JSON_UNESCAPED_SLASHES);
919
920
        $this->log->debug("create remoteIssueLink=$data\n");
921
922
        $ret = $this->exec($full_uri, $data, 'POST');
923
924
        $res = $this->json_mapper->map(
925
            json_decode($ret), new RemoteIssueLink()
926
        );
927
928
        return $res;
929
    }
930
931
    /**
932
     * @param string|int $issueIdOrKey
933
     * @param string|int $globalId
934
     *
935
     * @throws JiraException
936
     *
937
     * @return string|bool
938
     */
939
    public function removeRemoteIssueLink($issueIdOrKey, $globalId)
940
    {
941
        $query = http_build_query(['globalId' => $globalId]);
942
943
        $full_uri = sprintf('%s/%s/remotelink?%s', $this->uri, $issueIdOrKey, $query);
944
945
        $ret = $this->exec($full_uri, '', 'DELETE');
946
947
        $this->log->info(
948
            sprintf(
949
                'delete remote issue link for issue "%s" with globalId "%s". Result=%s',
950
                $issueIdOrKey,
951
                $globalId,
952
                var_export($ret, true)
953
            )
954
        );
955
956
        return $ret;
957
    }
958
959
    /**
960
     * get all issue security schemes.
961
     *
962
     * @throws JiraException
963
     * @throws \JsonMapper_Exception
964
     *
965
     * @return SecurityScheme[] array of SecurityScheme class
966
     */
967
    public function getAllIssueSecuritySchemes()
968
    {
969
        $url = '/issuesecurityschemes';
970
971
        $ret = $this->exec($url);
972
973
        $data = json_decode($ret, true);
974
975
        // extract schem field
976
        $schemes = json_decode(json_encode($data['issueSecuritySchemes']), false);
977
978
        $res = $this->json_mapper->mapArray(
979
            $schemes, new \ArrayObject(), '\JiraRestApi\Issue\SecurityScheme'
980
        );
981
982
        return $res;
983
    }
984
985
    /**
986
     *  get issue security scheme.
987
     *
988
     * @param int $securityId security scheme id
989
     *
990
     * @throws JiraException
991
     * @throws \JsonMapper_Exception
992
     *
993
     * @return SecurityScheme SecurityScheme
994
     */
995
    public function getIssueSecuritySchemes($securityId)
996
    {
997
        $url = '/issuesecurityschemes/'.$securityId;
998
999
        $ret = $this->exec($url);
1000
1001
        $res = $this->json_mapper->map(
1002
            json_decode($ret), new SecurityScheme()
1003
        );
1004
1005
        return $res;
1006
    }
1007
1008
    /**
1009
     * convenient wrapper function for add or remove labels.
1010
     *
1011
     * @param string|int $issueIdOrKey
1012
     * @param array|null $addLablesParam
1013
     * @param array|null $removeLabelsParam
1014
     * @param bool       $notifyUsers
1015
     *
1016
     * @throws JiraException
1017
     *
1018
     * @return Issue|object class
1019
     */
1020
    public function updateLabels($issueIdOrKey, $addLablesParam, $removeLabelsParam, $notifyUsers = true)
1021
    {
1022
        $labels = [];
1023
        foreach ($addLablesParam as $a) {
1024
            array_push($labels, ['add' => $a]);
1025
        }
1026
1027
        foreach ($removeLabelsParam as $r) {
1028
            array_push($labels, ['remove' => $r]);
1029
        }
1030
1031
        $postData = json_encode([
1032
            'update' => [
1033
                'labels' => $labels,
1034
            ],
1035
        ], JSON_UNESCAPED_UNICODE);
1036
1037
        $this->log->info("Update labels=\n".$postData);
1038
1039
        $queryParam = '?'.http_build_query(['notifyUsers' => $notifyUsers]);
1040
1041
        $ret = $this->exec($this->uri."/$issueIdOrKey".$queryParam, $postData, 'PUT');
1042
1043
        return $ret;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $ret returns the type string which is incompatible with the documented return type JiraRestApi\Issue\Issue|object.
Loading history...
1044
    }
1045
1046
    /**
1047
     * convenient wrapper function for add or remove fix versions.
1048
     *
1049
     * @param string|int $issueIdOrKey
1050
     * @param array|null $addFixVersionsParam
1051
     * @param array|null $removeFixVersionsParam
1052
     * @param bool       $notifyUsers
1053
     *
1054
     * @throws JiraException
1055
     *
1056
     * @return Issue|object class
1057
     */
1058
    public function updateFixVersions($issueIdOrKey, $addFixVersionsParam, $removeFixVersionsParam, $notifyUsers = true)
1059
    {
1060
        $fixVersions = [];
1061
        foreach ($addFixVersionsParam as $a) {
1062
            array_push($fixVersions, ['add' => ['name' => $a]]);
1063
        }
1064
1065
        foreach ($removeFixVersionsParam as $r) {
1066
            array_push($fixVersions, ['remove' => ['name' => $r]]);
1067
        }
1068
1069
        $postData = json_encode([
1070
            'update' => [
1071
                'fixVersions' => $fixVersions,
1072
            ],
1073
        ], JSON_UNESCAPED_UNICODE);
1074
1075
        $this->log->info("Update fixVersions=\n".$postData);
1076
1077
        $queryParam = '?'.http_build_query(['notifyUsers' => $notifyUsers]);
1078
1079
        $ret = $this->exec($this->uri."/$issueIdOrKey".$queryParam, $postData, 'PUT');
1080
1081
        return $ret;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $ret returns the type string which is incompatible with the documented return type JiraRestApi\Issue\Issue|object.
Loading history...
1082
    }
1083
}
1084