Skip to content

Commit 9e7809f

Browse files
committed
add cdragon support
1 parent 775ca9c commit 9e7809f

351 files changed

Lines changed: 9889 additions & 24 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
3+
namespace Phizz\Generator\Definitions;
4+
5+
use Nette\PhpGenerator\ClassType;
6+
use Phizz\Generator\Interfaces\Writable;
7+
use Phizz\Generator\Traits\HasWrite;
8+
use Phizz\Support\StaticApi;
9+
use Phizz\Support\StaticClient;
10+
11+
/**
12+
* Generates CDragonClient — a thin wrapper that exposes $lol and $tft sub-clients.
13+
*
14+
* @extends Definition<ClassType>
15+
*/
16+
class CDragonClientDefinition extends Definition implements Writable
17+
{
18+
use HasWrite;
19+
20+
public function namespace(): string
21+
{
22+
return $this->resolveNamespace('CDragon');
23+
}
24+
25+
public function directory(): string
26+
{
27+
return $this->resolvePath('CDragon');
28+
}
29+
30+
public function imports(): array
31+
{
32+
return [
33+
StaticApi::class,
34+
StaticClient::class,
35+
];
36+
}
37+
38+
public function definition(): ClassType
39+
{
40+
$class = (new ClassType('CDragonClient'))
41+
->setExtends(StaticApi::class);
42+
43+
$class->addProperty('lol')
44+
->setType($this->resolveNamespace('CDragon').'\\LolClient')
45+
->setPublic()
46+
->setReadOnly();
47+
48+
$class->addProperty('tft')
49+
->setType($this->resolveNamespace('CDragon').'\\TftClient')
50+
->setPublic()
51+
->setReadOnly();
52+
53+
$ctor = $class->addMethod('__construct')
54+
->setPublic();
55+
$ctor->addParameter('version')->setType('string');
56+
$ctor->addParameter('http')->setType(StaticClient::class);
57+
$ctor->setBody(
58+
'parent::__construct($version, $http);'."\n".
59+
'$this->lol = new LolClient($version, $http);'."\n".
60+
'$this->tft = new TftClient($version, $http);'
61+
);
62+
63+
$class->addMethod('version')
64+
->setReturnType('string')
65+
->addComment('Returns the CommunityDragon patch version this client is scoped to.')
66+
->setBody('return $this->version;');
67+
68+
return $class;
69+
}
70+
}
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
<?php
2+
3+
namespace Phizz\Generator\Definitions;
4+
5+
use Illuminate\Support\Collection;
6+
use Illuminate\Support\Str;
7+
use InvalidArgumentException;
8+
use Nette\PhpGenerator\ClassType;
9+
use Phizz\Generator\Interfaces\Writable;
10+
use Phizz\Generator\Objects\CDragonEndpoint;
11+
use Phizz\Generator\Traits\HasWrite;
12+
use Phizz\Support\StaticApi;
13+
14+
/**
15+
* Generates a static API class for one JSON endpoint.
16+
* Produces: all(), get(id), and a cached fetch().
17+
*
18+
* @extends Definition<ClassType>
19+
*/
20+
class StaticApiDefinition extends Definition implements Writable
21+
{
22+
use HasWrite;
23+
24+
public function __construct(
25+
private readonly CDragonEndpoint $endpoint,
26+
private readonly StaticDataDefinition $dataDefinition,
27+
) {}
28+
29+
public function namespace(): string
30+
{
31+
return $this->resolveNamespace('CDragon\\'.Str::studly($this->endpoint->slug));
32+
}
33+
34+
public function directory(): string
35+
{
36+
return $this->resolvePath('CDragon/'.Str::studly($this->endpoint->slug));
37+
}
38+
39+
public function imports(): array
40+
{
41+
$imports = [
42+
StaticApi::class,
43+
$this->dataDefinition->className(),
44+
];
45+
46+
if (! $this->endpoint->isDirectory) {
47+
$imports[] = Collection::class;
48+
49+
if ($this->endpoint->idField !== null) {
50+
$imports[] = InvalidArgumentException::class;
51+
}
52+
}
53+
54+
return $imports;
55+
}
56+
57+
public function definition(): ClassType
58+
{
59+
$dataShort = $this->dataShortName();
60+
$class = (new ClassType($this->shortClassName()))
61+
->setExtends(StaticApi::class);
62+
63+
if ($this->endpoint->isDirectory) {
64+
$this->buildDirectoryEndpoint($class, $dataShort);
65+
} else {
66+
$this->buildFlatEndpoint($class, $dataShort);
67+
}
68+
69+
return $class;
70+
}
71+
72+
/**
73+
* Flat-file endpoint (e.g. items.json): all(), get(id), cached fetch().
74+
*/
75+
private function buildFlatEndpoint(ClassType $class, string $dataShort): void
76+
{
77+
// Cache property (single array for the whole list)
78+
$class->addProperty('cache')
79+
->setPrivate()
80+
->setType('?array')
81+
->setValue(null);
82+
83+
// all()
84+
$allMethod = $class->addMethod('all')
85+
->setReturnType(Collection::class)
86+
->addComment("@return Collection<int, {$dataShort}>");
87+
$allMethod->setBody(
88+
"return collect(\$this->fetch())->map(fn (\$item) => new {$dataShort}(\$item, \$this->version));"
89+
);
90+
91+
// get(id) — only if an id field exists
92+
if ($this->endpoint->idField !== null) {
93+
$idField = $this->endpoint->idField;
94+
$getMethod = $class->addMethod('get')
95+
->setReturnType($this->dataDefinition->className())
96+
->addComment("@return {$dataShort}");
97+
$getMethod->addParameter('id')->setType('int');
98+
$getMethod->setBody(
99+
"\$item = collect(\$this->fetch())->firstWhere('{$idField}', \$id);\n\n".
100+
"if (\$item === null) {\n".
101+
" throw new InvalidArgumentException(\"Item '{\$id}' not found.\");\n".
102+
"}\n\n".
103+
"return new {$dataShort}(\$item, \$this->version);"
104+
);
105+
}
106+
107+
// private fetch()
108+
$fetchMethod = $class->addMethod('fetch')
109+
->setPrivate()
110+
->setReturnType('array');
111+
$jsonPath = "/{$this->endpoint->slug}.json";
112+
$fetchMethod->setBody(
113+
"return \$this->cache ??= \$this->http->cdragon(\n".
114+
" \"/{$this->versionPlaceholder()}/\".self::PLUGIN_BASE.\"/v1{$jsonPath}\"\n".
115+
');'
116+
);
117+
}
118+
119+
/**
120+
* Directory endpoint (e.g. champions/{id}.json): get(id), per-ID fetch().
121+
*/
122+
private function buildDirectoryEndpoint(ClassType $class, string $dataShort): void
123+
{
124+
$slug = $this->endpoint->slug;
125+
126+
// get(int $id): XxxData
127+
$getMethod = $class->addMethod('get')
128+
->setReturnType($this->dataDefinition->className())
129+
->addComment("@return {$dataShort}");
130+
$getMethod->addParameter('id')->setType('int');
131+
$getMethod->setBody("return new {$dataShort}(\$this->fetch(\$id), \$this->version);");
132+
133+
// private fetch(int $id): array — no in-memory cache (each id is different)
134+
$fetchMethod = $class->addMethod('fetch')
135+
->setPrivate()
136+
->setReturnType('array');
137+
$fetchMethod->addParameter('id')->setType('int');
138+
$fetchMethod->setBody(
139+
"return \$this->http->cdragon(\n".
140+
" \"/{$this->versionPlaceholder()}/\".self::PLUGIN_BASE.\"/v1/{$slug}/{\$id}.json\"\n".
141+
');'
142+
);
143+
}
144+
145+
public function className(): string
146+
{
147+
return $this->namespace().'\\'.$this->shortClassName();
148+
}
149+
150+
private function shortClassName(): string
151+
{
152+
return Str::studly($this->endpoint->slug).'Api';
153+
}
154+
155+
private function dataShortName(): string
156+
{
157+
return Str::studly(Str::singular($this->endpoint->slug)).'Data';
158+
}
159+
160+
private function versionPlaceholder(): string
161+
{
162+
return '{$this->version}';
163+
}
164+
}

0 commit comments

Comments
 (0)