Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,14 @@ $files = $client->getModFiles($options);
```
In this case the options are not optional as the mod id is required.

The latest files and the categories of a mod are included in the mod, so no request is needed.
They are returned as `File` and `Category` wrappers:
```php
$latestFiles = $mod->getLatestFiles();
$categories = $mod->getCategories();
$primaryCategory = $mod->getPrimaryCategory();
```

Just like with mods, you can fetch files individually or in bulk:
```php
$file = $client->getModFile(420561, 3787455);
Expand Down
32 changes: 30 additions & 2 deletions src/Client/Mod.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
use Aternos\CurseForgeApi\ApiException;
use Aternos\CurseForgeApi\Client\List\PaginatedFilesList;
use Aternos\CurseForgeApi\Client\Options\ModFilesOptions;
use Aternos\CurseForgeApi\Model\Category as CategoryModel;
use Aternos\CurseForgeApi\Model\File as FileModel;
use Aternos\CurseForgeApi\Model\Mod as ModModel;

class Mod extends ModModel
Expand Down Expand Up @@ -62,20 +64,46 @@ public function fetchGame(): Game
return $this->client->getGame($this->getGameId());
}

/**
* Get the categories of this mod
* @return Category[]|null
*/
public function getCategories(): ?array
{
$categories = parent::getCategories();
if ($categories === null) {
return null;
}
return array_map(fn(CategoryModel $category) => new Category($this->client, $category), $categories);
}

/**
* Get the primary category of this mod
* @return Category|null
*/
public function getPrimaryCategory(): ?Category
{
foreach ($this->getCategories() as $category) {
foreach ($this->getCategories() ?? [] as $category) {
if ($category->getId() === $this->getPrimaryCategoryId()) {
return new Category($this->client, $category);
return $category;
}
}
return null;
}

/**
* Get the latest files of this mod
* @return File[]|null
*/
public function getLatestFiles(): ?array
{
$files = parent::getLatestFiles();
if ($files === null) {
return null;
}
return array_map(fn(FileModel $file) => new File($this->client, $file), $files);
}

/**
* Fetch the category class of this mod
* This sends a request to the CurseForge API every time it is called.
Expand Down
4 changes: 4 additions & 0 deletions tests/Unit/Client/CurseForgeAPIClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,10 @@ public function testWrapperIsSerializedLikeModel(): void
$this->assertSame(420561, $json["id"]);
$this->assertSame("mclo-gs", $json["slug"]);
$this->assertArrayNotHasKey("client", $json);
$this->assertSame(435, $json["categories"][0]["id"]);
$this->assertArrayNotHasKey("client", $json["categories"][0]);
$this->assertSame(3553911, $json["latestFiles"][0]["id"]);
$this->assertArrayNotHasKey("client", $json["latestFiles"][0]);
}

/**
Expand Down
59 changes: 59 additions & 0 deletions tests/Unit/Client/ModTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,4 +139,63 @@ public function testGetPrimaryCategoryDoesNotSendRequest(): void
$this->assertSame(435, $category->getId());
$this->assertRequestCount(0);
}

/**
* @throws ApiException
*/
public function testGetCategoriesReturnsWrappers(): void
{
$client = $this->createClient([
new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/getMod.json")),
new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/getGame.json")),
]);
$mod = $client->getMod(420561);

$categories = $mod->getCategories();

$this->assertCount(1, $categories);
$this->assertContainsOnlyInstancesOf(Category::class, $categories);
$this->assertSame(435, $categories[0]->getId());
$this->assertRequestCount(1);

$categories[0]->fetchGame();
$this->assertGetRequest("/v1/games/432", [], 1);
}

public function testGetCategoriesWithoutCategoriesReturnsNull(): void
{
$mod = new Mod($this->createClient(), new ModModel(["id" => 420561]));

$this->assertNull($mod->getCategories());
$this->assertNull($mod->getPrimaryCategory());
}

/**
* @throws ApiException
*/
public function testGetLatestFilesReturnsWrappers(): void
{
$client = $this->createClient([
new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/getMod.json")),
new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/getMod.json")),
]);
$mod = $client->getMod(420561);

$files = $mod->getLatestFiles();

$this->assertCount(2, $files);
$this->assertContainsOnlyInstancesOf(File::class, $files);
$this->assertSame([3553911, 6235017], array_map(fn(File $file) => $file->getId(), $files));
$this->assertRequestCount(1);

$files[0]->fetchMod();
$this->assertGetRequest("/v1/mods/420561", [], 1);
}

public function testGetLatestFilesWithoutFilesReturnsNull(): void
{
$mod = new Mod($this->createClient(), new ModModel(["id" => 420561]));

$this->assertNull($mod->getLatestFiles());
}
}
Loading