WikiPages::all()   A
last analyzed

Complexity

Conditions 5
Paths 5

Size

Total Lines 24
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 13
nc 5
nop 1
dl 0
loc 24
rs 9.5222
c 1
b 0
f 0
1
<?php
2
3
namespace Blackmine\Repository\Projects;
4
5
use Blackmine\Client\ClientOptions;
6
use Blackmine\Collection\HierarchyCollection;
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\Issue\Attachment;
12
use Blackmine\Model\Project\Project;
13
use Blackmine\Model\Project\WikiPage;
14
use Blackmine\Repository\AbstractRepository;
15
use Blackmine\Repository\Uploads;
16
use Doctrine\Common\Collections\ArrayCollection;
17
use Error;
18
use JsonException;
19
20
class WikiPages extends AbstractRepository
21
{
22
    public const API_ROOT = "wiki_pages";
23
24
    protected Project $project;
25
26
    public const WIKI_PAGES_RELATION_ATTACHMENTS = "attachments";
27
    public const WIKI_PAGES_RELATION_REVISIONS = "revisions";
28
    public const WIKI_PAGES_RELATION_CHILDREN = "children";
29
30
    protected static array $relation_class_map = [
31
        self::WIKI_PAGES_RELATION_ATTACHMENTS => Attachment::class,
32
        self::WIKI_PAGES_RELATION_REVISIONS => WikiPage::class,
33
        self::WIKI_PAGES_RELATION_CHILDREN => WikiPage::class
34
    ];
35
36
    public function getModelClass(): string
37
    {
38
        return WikiPage::class;
39
    }
40
41
    public function create(AbstractModel $model): ?AbstractModel
42
    {
43
        if (!$model instanceof WikiPage) {
44
            throw new InvalidModelException(
45
                'Wrong model class for ' . $this->getEndpoint() . " api. Expected " . $this->getModelClass()
46
            );
47
        }
48
49
        $api_response = $this->client->put(
50
            endpoint: $this->getEndpoint() . "/" . $model->getTitle() . "." . $this->client->getFormat(),
51
            body: json_encode($model->getPayload(), JSON_THROW_ON_ERROR),
52
            headers: $this->options[ClientOptions::CLIENT_OPTION_REQUEST_HEADERS] ?? []
53
        );
54
55
        if ($api_response->isSuccess()) {
56
            $model_data = $api_response->getData()[$model->getEntityName()] ?? null;
57
58
            if ($model_data) {
59
                $model->fromArray($model_data);
60
                $this->hydrateRelations($model);
61
62
                return $model;
63
            }
64
        }
65
66
        throw AbstractApiException::fromApiResponse($api_response);
67
    }
68
69
    /**
70
     * @throws AbstractApiException
71
     * @throws JsonException
72
     */
73
    public function all(?string $endpoint = null): ArrayCollection
74
    {
75
        if (is_initialized($this, "project")) {
76
            $endpoint = $endpoint ?? $this->getEndpoint() . "/index." . $this->client->getFormat();
77
            $response = $this->client->get($endpoint);
78
79
            if ($response->isSuccess()) {
80
                $collection = new HierarchyCollection(parent_field: "title");
81
82
                foreach ($response->getData()[self::API_ROOT] as $relation_data) {
83
                    $wiki_page = $this->getWikiPage($relation_data["title"]);
84
                    if (in_array(self::WIKI_PAGES_RELATION_REVISIONS, $this->getFetchRelations(), true)) {
85
                        $wiki_page->setRevisions($this->getRevisions($wiki_page));
86
                    }
87
                    $collection->add($wiki_page);
88
                }
89
90
                return $collection;
91
            }
92
93
            throw AbstractApiException::fromApiResponse($response);
94
        }
95
96
        throw new Error("Mandatory class property project not initialized");
97
    }
98
99
    /**
100
     * @throws AbstractApiException
101
     * @throws JsonException
102
     */
103
    protected function getWikiPage(string $title, ?int $revision = null): WikiPage
104
    {
105
        if ($revision !== null) {
106
            $endpoint = $this->getEndpoint() . "/" . $title . "/" . $revision . "." . $this->client->getFormat() . "?include=attachments";
107
        } else {
108
            $endpoint = $this->getEndpoint() . "/" . $title . "." . $this->client->getFormat() . "?include=attachments";
109
        }
110
111
        $response = $this->client->get($endpoint);
112
113
        if ($response->isSuccess()) {
114
            return (new WikiPage())->fromArray($response->getData()["wiki_page"]);
115
        }
116
117
        throw AbstractApiException::fromApiResponse($response);
118
    }
119
120
    /**
121
     * @throws AbstractApiException
122
     * @throws JsonException
123
     */
124
    protected function getRevisions(WikiPage $wiki_page): IdentityCollection
125
    {
126
        $collection = new IdentityCollection();
127
        $max_revision = $wiki_page->getVersion();
128
        for ($i = 1; $i <= $max_revision; $i++) {
129
            $collection->add($this->getWikiPage($wiki_page->getTitle(), $i));
130
        }
131
132
        return $collection;
133
    }
134
135
    /**
136
     * @throws AbstractApiException
137
     * @throws JsonException
138
     * @throws InvalidModelException
139
     */
140
    public function addAttachment(WikiPage $wiki_page, Attachment $attachment): WikiPage
141
    {
142
        $attachment = $this->client->getRepository(Uploads::API_ROOT)?->create($attachment);
143
        if ($attachment) {
144
            $wiki_page->addAttachment($attachment);
145
        }
146
        return $wiki_page;
147
    }
148
149
    /**
150
     * @param Project $project
151
     * @return WikiPages
152
     */
153
    public function setProject(Project $project): self
154
    {
155
        $this->project = $project;
156
        return $this;
157
    }
158
159
    public function getEndpoint(): string
160
    {
161
        return "projects/" . $this->project->getId() . "/wiki";
162
    }
163
}
164