Issues   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 111
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 62
dl 0
loc 111
rs 10
c 1
b 0
f 0
wmc 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A getModelClass() 0 3 1
A addChild() 0 10 2
A create() 0 18 4
A addAttachment() 0 9 2
A getChildren() 0 6 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Blackmine\Repository\Issues;
6
7
use Blackmine\Collection\IdentityCollection;
8
use Blackmine\Exception\Api\AbstractApiException;
9
use Blackmine\Exception\InvalidModelException;
10
use Blackmine\Model\AbstractModel;
11
use Blackmine\Model\User\User;
12
use Blackmine\Repository\RepositoryTrait;
13
use Blackmine\Repository\Uploads;
14
use Carbon\CarbonInterface;
15
use Blackmine\Model\CustomField;
16
use Blackmine\Repository\AbstractRepository;
17
use Blackmine\Model\Issue\Attachment;
18
use Blackmine\Model\Issue\Changeset;
19
use Blackmine\Model\Issue\Issue;
20
use Blackmine\Model\Issue\Journal;
21
use Blackmine\Model\Issue\Relation;
22
use Blackmine\Repository\RepositoryInterface;
23
use Doctrine\Common\Collections\ArrayCollection;
24
use JsonException;
25
26
class Issues extends AbstractRepository
27
{
28
    use RepositoryTrait;
29
30
    public const API_ROOT = "issues";
31
32
    public const ISSUE_RELATION_CHILDREN = "children";
33
    public const ISSUE_RELATION_ATTACHMENTS = "attachments";
34
    public const ISSUE_RELATION_RELATIONS = "relations";
35
    public const ISSUE_RELATION_JOURNALS = "journals";
36
    public const ISSUE_RELATION_CHANGESETS = "changesets";
37
    public const ISSUE_RELATION_WATCHERS = "watchers";
38
    public const ISSUE_RELATION_CUSTOM_FIELDS = "custom_fields";
39
40
    public const ISSUE_FILTER_ISSUE_ID = "issue_id";
41
    public const ISSUE_FILTER_PARENT_ID = "parent_id";
42
    public const ISSUE_FILTER_PROJECT_ID = "project_id";
43
    public const ISSUE_FILTER_SUBPROJECT_ID = "subproject_id";
44
    public const ISSUE_FILTER_TRACKER_ID = "tracker_id";
45
    public const ISSUE_FILTER_STATUS_ID = "status_id";
46
    public const ISSUE_FILTER_ASSIGNED_TO_ID = "assigned_to_id";
47
    public const ISSUE_FILTER_QUERY_ID = "query_id";
48
49
50
    protected static array $relation_class_map = [
51
        self::ISSUE_RELATION_CHILDREN => Issue::class,
52
        self::ISSUE_RELATION_ATTACHMENTS => Attachment::class,
53
        self::ISSUE_RELATION_RELATIONS => Relation::class,
54
        self::ISSUE_RELATION_JOURNALS => Journal::class,
55
        self::ISSUE_RELATION_CHANGESETS => Changeset::class,
56
        self::ISSUE_RELATION_WATCHERS => User::class,
57
        self::ISSUE_RELATION_CUSTOM_FIELDS => CustomField::class
58
    ];
59
60
    protected static array $allowed_filters = [
61
        self::ISSUE_FILTER_ISSUE_ID => RepositoryInterface::SEARCH_PARAM_TYPE_INT_ARRAY,
62
        self::ISSUE_FILTER_PROJECT_ID => RepositoryInterface::SEARCH_PARAM_TYPE_INT,
63
        self::ISSUE_FILTER_SUBPROJECT_ID => RepositoryInterface::SEARCH_PARAM_TYPE_INT,
64
        self::ISSUE_FILTER_TRACKER_ID => RepositoryInterface::SEARCH_PARAM_TYPE_INT,
65
        self::ISSUE_FILTER_STATUS_ID => RepositoryInterface::SEARCH_PARAM_TYPE_STRING,
66
        self::ISSUE_FILTER_PARENT_ID => RepositoryInterface::SEARCH_PARAM_TYPE_INT,
67
        self::ISSUE_FILTER_QUERY_ID => RepositoryInterface::SEARCH_PARAM_TYPE_INT,
68
        self::ISSUE_FILTER_ASSIGNED_TO_ID => RepositoryInterface::SEARCH_PARAM_TYPE_INT,
69
        self::COMMON_FILTER_CREATED_ON => CarbonInterface::class,
70
        self::COMMON_FILTER_UPDATED_ON => CarbonInterface::class,
71
        self::COMMON_FILTER_CUSTOM_FIELDS => RepositoryInterface::SEARCH_PARAM_TYPE_CF_ARRAY
72
    ];
73
74
    public function getModelClass(): string
75
    {
76
        return Issue::class;
77
    }
78
79
    public function create(AbstractModel $model): ?AbstractModel
80
    {
81
        /** @var Issue $model */
82
        $model = parent::create($model);
83
        if ($model && !$model->getAttachments()->isEmpty()) {
84
            $api_response = $this->client->put(
85
                $this->getEndpoint() . "/" . $model->getId() . "." . $this->client->getFormat(),
86
                json_encode($model->getPayload(), JSON_THROW_ON_ERROR)
87
            );
88
89
            if ($api_response->isSuccess()) {
90
                return $model;
91
            }
92
93
            throw AbstractApiException::fromApiResponse($api_response);
94
        }
95
96
        return $model;
97
    }
98
99
    public function addChild(Issue $issue, Issue $child): Issue
100
    {
101
        if (!$child->isPersisted()) { // Issue already exists
102
            $child->setParentIssue($issue);
103
            $child = $this->create($child);
104
        }
105
106
        $issue->addChild($child);
107
108
        return $issue;
109
    }
110
111
    /**
112
     * @throws JsonException
113
     */
114
    public function getChildren(Issue $issue): IdentityCollection | ArrayCollection
115
    {
116
        return $this->client->getRepository(self::API_ROOT)
117
            ?->addFilter(self::ISSUE_FILTER_PARENT_ID, $issue->getId())
118
            ->addFilter(self::ISSUE_FILTER_STATUS_ID, "*")
119
            ->search();
120
    }
121
122
123
    /**
124
     * @throws AbstractApiException
125
     * @throws JsonException
126
     * @throws InvalidModelException
127
     */
128
    public function addAttachment(Issue $issue, Attachment $attachment): Issue
129
    {
130
        $attachment = $this->client->getRepository(Uploads::API_ROOT)?->create($attachment);
131
        /** @var Attachment $attachment */
132
        if ($attachment !== null) {
133
            $attachment->setVersion($issue->getFixedVersion());
134
            $issue->addAttachment($attachment);
135
        }
136
        return $issue;
137
    }
138
}
139