Skip to content

Commit af6a478

Browse files
authored
refactor: fix phpstan errors in Config (#10482)
1 parent e650a71 commit af6a478

16 files changed

Lines changed: 86 additions & 245 deletions

system/Config/BaseConfig.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class BaseConfig
3737
* An optional array of classes that will act as Registrars
3838
* for rapidly setting config class properties.
3939
*
40-
* @var array
40+
* @var list<class-string|object>
4141
*/
4242
public static $registrars = [];
4343

@@ -70,6 +70,9 @@ class BaseConfig
7070
*/
7171
protected static $moduleConfig;
7272

73+
/**
74+
* @param array<string, mixed> $array
75+
*/
7376
public static function __set_state(array $array)
7477
{
7578
static::$override = false;

system/Config/BaseService.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@
134134
* @method static Security security(App $config = null, $getShared = true)
135135
* @method static Session session(ConfigSession $config = null, $getShared = true)
136136
* @method static SiteURIFactory siteurifactory(App $config = null, Superglobals $superglobals = null, $getShared = true)
137-
* @method static Superglobals superglobals(array $server = null, array $get = null, bool $getShared = true)
137+
* @method static Superglobals superglobals(array<string, mixed> $server = null, array<string, mixed> $get = null, bool $getShared = true)
138138
* @method static Throttler throttler($getShared = true)
139139
* @method static Timer timer($getShared = true)
140140
* @method static Toolbar toolbar(ConfigToolbar $config = null, $getShared = true)
@@ -178,7 +178,7 @@ class BaseService
178178
/**
179179
* A cache of other service classes we've found.
180180
*
181-
* @var array
181+
* @var array{}
182182
*
183183
* @deprecated 4.5.0 No longer used.
184184
*/
@@ -317,6 +317,8 @@ public static function locator(bool $getShared = true)
317317
* Provides the ability to perform case-insensitive calling of service
318318
* names.
319319
*
320+
* @param array<array-key, mixed> $arguments
321+
*
320322
* @return object|null
321323
*/
322324
public static function __callStatic(string $name, array $arguments)

system/Config/DotEnv.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ public function load(): bool
5151

5252
/**
5353
* Parse the .env file into an array of key => value
54+
*
55+
* @return array<string, string>|null
5456
*/
5557
public function parse(): ?array
5658
{
@@ -119,6 +121,8 @@ protected function setVariable(string $name, string $value = '')
119121
/**
120122
* Parses for assignment, cleans the $name and $value, and ensures
121123
* that nested variables are handled.
124+
*
125+
* @return array{string, string}
122126
*/
123127
public function normaliseVariable(string $name, string $value = ''): array
124128
{

system/Config/Factories.php

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
* instantiation checks.
2828
*
2929
* @method static BaseConfig|null config(...$arguments)
30-
* @method static Model|null models(string $alias, array $options = [], ?ConnectionInterface &$conn = null)
30+
* @method static Model|null models(string $alias, array<string, bool|string|null> $options = [], ?ConnectionInterface &$conn = null)
3131
* @see \CodeIgniter\Config\FactoriesTest
3232
*/
3333
final class Factories
@@ -127,6 +127,8 @@ public static function define(string $component, string $alias, string $classnam
127127
* Loads instances based on the method component name. Either
128128
* creates a new instance or returns an existing shared instance.
129129
*
130+
* @param array<array-key, mixed> $arguments
131+
*
130132
* @return object|null
131133
*/
132134
public static function __callStatic(string $component, array $arguments)
@@ -140,7 +142,7 @@ public static function __callStatic(string $component, array $arguments)
140142
// Determine the component-specific options
141143
$options = array_merge(self::getOptions($component), $options);
142144

143-
if (! $options['getShared']) {
145+
if (! (bool) $options['getShared']) {
144146
if (isset(self::$aliases[$options['component']][$alias])) {
145147
$class = self::$aliases[$options['component']][$alias];
146148

@@ -192,6 +194,9 @@ public static function get(string $component, string $alias): ?object
192194
/**
193195
* Gets the defined instance. If not exists, creates new one.
194196
*
197+
* @param array<string, bool|string|null> $options
198+
* @param array<array-key, mixed> $arguments
199+
*
195200
* @return object|null
196201
*/
197202
private static function getDefinedInstance(array $options, string $alias, array $arguments)
@@ -230,6 +235,8 @@ private static function getDefinedInstance(array $options, string $alias, array
230235

231236
/**
232237
* Creates the shared instance.
238+
*
239+
* @param array<array-key, mixed> $arguments
233240
*/
234241
private static function createInstance(string $component, string $class, array $arguments): void
235242
{
@@ -264,8 +271,8 @@ private static function isConfig(string $component): bool
264271
/**
265272
* Finds a component class
266273
*
267-
* @param array $options The array of component-specific directives
268-
* @param string $alias Class alias. See the $aliases property.
274+
* @param array<string, bool|string|null> $options The array of component-specific directives
275+
* @param string $alias Class alias. See the $aliases property.
269276
*/
270277
private static function locateClass(array $options, string $alias): ?string
271278
{
@@ -341,8 +348,8 @@ private static function isNamespaced(string $alias): bool
341348
/**
342349
* Verifies that a class & config satisfy the "preferApp" option
343350
*
344-
* @param array $options The array of component-specific directives
345-
* @param string $alias Class alias. See the $aliases property.
351+
* @param array<string, bool|string|null> $options The array of component-specific directives
352+
* @param string $alias Class alias. See the $aliases property.
346353
*/
347354
private static function verifyPreferApp(array $options, string $alias): bool
348355
{
@@ -362,8 +369,8 @@ private static function verifyPreferApp(array $options, string $alias): bool
362369
/**
363370
* Verifies that a class & config satisfy the "instanceOf" option
364371
*
365-
* @param array $options The array of component-specific directives
366-
* @param string $alias Class alias. See the $aliases property.
372+
* @param array<string, bool|string|null> $options The array of component-specific directives
373+
* @param string $alias Class alias. See the $aliases property.
367374
*/
368375
private static function verifyInstanceOf(array $options, string $alias): bool
369376
{
@@ -408,8 +415,8 @@ public static function getOptions(string $component): array
408415
/**
409416
* Normalizes, stores, and returns the configuration for a specific component
410417
*
411-
* @param string $component Lowercase, plural component name
412-
* @param array $values option values
418+
* @param string $component Lowercase, plural component name
419+
* @param array<string, bool|string|null> $values Option values
413420
*
414421
* @return array<string, bool|string|null> The result after applying defaults and normalization
415422
*/
@@ -541,6 +548,12 @@ public static function getComponentInstances(string $component): array
541548
/**
542549
* Sets component data
543550
*
551+
* @param array{
552+
* options: array<string, bool|string|null>,
553+
* aliases: array<string, class-string>,
554+
* instances: array<class-string, object>,
555+
* } $data
556+
*
544557
* @internal For caching only
545558
*/
546559
public static function setComponentInstances(string $component, array $data): void

system/Config/Factory.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class Factory extends BaseConfig
2828
* Supplies a default set of options to merge for
2929
* all unspecified factory components.
3030
*
31-
* @var array
31+
* @var array<string, bool|string|null>
3232
*/
3333
public static $default = [
3434
'component' => null,
@@ -42,7 +42,7 @@ class Factory extends BaseConfig
4242
* Specifies that Models should always favor child
4343
* classes to allow easy extension of module Models.
4444
*
45-
* @var array
45+
* @var array<string, bool|string|null>
4646
*/
4747
public $models = [
4848
'preferApp' => true,

system/Config/Services.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,8 @@ public static function csp(?CSPConfig $config = null, bool $getShared = true)
198198
* The CURL Request class acts as a simple HTTP client for interacting
199199
* with other servers, typically through APIs.
200200
*
201+
* @param array<string, mixed> $options
202+
*
201203
* @return CURLRequest
202204
*/
203205
public static function curlrequest(array $options = [], ?ResponseInterface $response = null, ?App $config = null, bool $getShared = true)
@@ -220,7 +222,7 @@ public static function curlrequest(array $options = [], ?ResponseInterface $resp
220222
/**
221223
* The Email class allows you to send email via mail, sendmail, SMTP.
222224
*
223-
* @param array|EmailConfig|null $config
225+
* @param array<string, mixed>|EmailConfig|null $config
224226
*
225227
* @return Email
226228
*/
@@ -739,6 +741,13 @@ public static function siteurifactory(
739741
/**
740742
* Superglobals.
741743
*
744+
* @param array<string, mixed>|null $server
745+
* @param array<string, mixed>|null $get
746+
* @param array<string, mixed>|null $post
747+
* @param array<string, mixed>|null $cookie
748+
* @param array<string, mixed>|null $files
749+
* @param array<string, mixed>|null $request
750+
*
742751
* @return Superglobals
743752
*/
744753
public static function superglobals(

tests/system/Config/DotEnvTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ public function testLoadsVars(string $expected, string $varname): void
7373
$this->assertSame($expected, getenv($varname));
7474
}
7575

76+
/**
77+
* @return iterable<array{string, string}>
78+
*/
7679
public static function provideLoadsVars(): iterable
7780
{
7881
yield from [

tests/system/Config/FactoriesTest.php

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ protected function setUp(): void
4141
Factories::reset();
4242
}
4343

44-
protected function getFactoriesStaticProperty(...$params): mixed
44+
protected function getFactoriesStaticProperty(string ...$params): mixed
4545
{
4646
// First parameter is the actual property
4747
$name = array_shift($params);
@@ -158,14 +158,14 @@ public function testGetsBasenameInvalid(): void
158158

159159
public function testCreatesByBasename(): void
160160
{
161-
$result = Factories::widgets('SomeWidget', ['getShared' => false]);
161+
$result = Factories::widgets('SomeWidget', ['getShared' => false]); // @phpstan-ignore staticMethod.notFound
162162

163163
$this->assertInstanceOf(SomeWidget::class, $result);
164164
}
165165

166166
public function testCreatesByClassname(): void
167167
{
168-
$result = Factories::widgets(SomeWidget::class, ['getShared' => false]);
168+
$result = Factories::widgets(SomeWidget::class, ['getShared' => false]); // @phpstan-ignore staticMethod.notFound
169169

170170
$this->assertInstanceOf(SomeWidget::class, $result);
171171
}
@@ -179,22 +179,22 @@ public function testCreatesByAbsoluteClassname(): void
179179

180180
public function testCreatesInvalid(): void
181181
{
182-
$result = Factories::widgets('gfnusvjai', ['getShared' => false]);
182+
$result = Factories::widgets('gfnusvjai', ['getShared' => false]); // @phpstan-ignore staticMethod.notFound
183183

184184
$this->assertNull($result);
185185
}
186186

187187
public function testIgnoresNonClass(): void
188188
{
189-
$result = Factories::widgets('NopeWidget', ['getShared' => false]);
189+
$result = Factories::widgets('NopeWidget', ['getShared' => false]); // @phpstan-ignore staticMethod.notFound
190190

191191
$this->assertNull($result);
192192
}
193193

194194
public function testReturnsSharedInstance(): void
195195
{
196-
$widget1 = Factories::widgets('SomeWidget');
197-
$widget2 = Factories::widgets(SomeWidget::class);
196+
$widget1 = Factories::widgets('SomeWidget'); // @phpstan-ignore staticMethod.notFound
197+
$widget2 = Factories::widgets(SomeWidget::class); // @phpstan-ignore staticMethod.notFound
198198

199199
$this->assertSame($widget1, $widget2);
200200
}
@@ -203,7 +203,7 @@ public function testInjection(): void
203203
{
204204
Factories::injectMock('widgets', 'Banana', new stdClass());
205205

206-
$result = Factories::widgets('Banana');
206+
$result = Factories::widgets('Banana'); // @phpstan-ignore staticMethod.notFound
207207

208208
$this->assertInstanceOf('stdClass', $result);
209209
}
@@ -212,7 +212,7 @@ public function testRespectsComponentAlias(): void
212212
{
213213
Factories::setOptions('tedwigs', ['component' => 'widgets']);
214214

215-
$result = Factories::tedwigs('SomeWidget');
215+
$result = Factories::tedwigs('SomeWidget'); // @phpstan-ignore staticMethod.notFound
216216
$this->assertInstanceOf(SomeWidget::class, $result);
217217
}
218218

@@ -228,26 +228,26 @@ public function testRespectsInstanceOf(): void
228228
{
229229
Factories::setOptions('widgets', ['instanceOf' => 'stdClass']);
230230

231-
$result = Factories::widgets('SomeWidget');
231+
$result = Factories::widgets('SomeWidget'); // @phpstan-ignore staticMethod.notFound
232232
$this->assertInstanceOf(SomeWidget::class, $result);
233233

234-
$result = Factories::widgets('OtherWidget');
234+
$result = Factories::widgets('OtherWidget'); // @phpstan-ignore staticMethod.notFound
235235
$this->assertNull($result);
236236
}
237237

238238
public function testSharedRespectsInstanceOf(): void
239239
{
240240
Factories::injectMock('widgets', 'SomeWidget', new OtherWidget());
241241

242-
$result = Factories::widgets('SomeWidget', ['instanceOf' => 'stdClass']);
242+
$result = Factories::widgets('SomeWidget', ['instanceOf' => 'stdClass']); // @phpstan-ignore staticMethod.notFound
243243
$this->assertInstanceOf(SomeWidget::class, $result);
244244
}
245245

246246
public function testPrioritizesParameterOptions(): void
247247
{
248248
Factories::setOptions('widgets', ['instanceOf' => 'stdClass']);
249249

250-
$result = Factories::widgets(OtherWidget::class, ['instanceOf' => null]);
250+
$result = Factories::widgets(OtherWidget::class, ['instanceOf' => null]); // @phpstan-ignore staticMethod.notFound
251251
$this->assertInstanceOf(OtherWidget::class, $result);
252252
}
253253

@@ -259,7 +259,7 @@ public function testFindsAppFirst(): void
259259
class_alias(SomeWidget::class, $class);
260260
}
261261

262-
$result = Factories::widgets('OtherWidget');
262+
$result = Factories::widgets('OtherWidget'); // @phpstan-ignore staticMethod.notFound
263263
$this->assertInstanceOf(SomeWidget::class, $result);
264264
}
265265

@@ -277,6 +277,7 @@ class TestRegistrar
277277

278278
$result = Factories::config('TestRegistrar');
279279

280+
// @phpstan-ignore argument.type (Config\TestRegistrar is created at runtime by this test)
280281
$this->assertInstanceOf('Config\TestRegistrar', $result);
281282

282283
// Delete the config class in App
@@ -317,14 +318,14 @@ public function testPreferAppIsIgnored(): void
317318
class_alias(SomeWidget::class, $class);
318319
}
319320

320-
$result = Factories::widgets(OtherWidget::class);
321+
$result = Factories::widgets(OtherWidget::class); // @phpstan-ignore staticMethod.notFound
321322
$this->assertInstanceOf(OtherWidget::class, $result);
322323
}
323324

324325
public function testCanLoadTwoCellsWithSameShortName(): void
325326
{
326-
$cell1 = Factories::cells('\\' . SampleClass::class);
327-
$cell2 = Factories::cells('\\' . \Tests\Support\View\OtherCells\SampleClass::class);
327+
$cell1 = Factories::cells('\\' . SampleClass::class); // @phpstan-ignore staticMethod.notFound
328+
$cell2 = Factories::cells('\\' . \Tests\Support\View\OtherCells\SampleClass::class); // @phpstan-ignore staticMethod.notFound
328329

329330
$this->assertNotSame($cell1, $cell2);
330331
}
@@ -369,6 +370,7 @@ public function testDefineSameAliasAndSameClassTwice(): void
369370
UserModel::class,
370371
);
371372

373+
// @phpstan-ignore codeigniter.modelArgumentType (aliased to Tests\Support\Models\UserModel above)
372374
$model = model('CodeIgniter\Shield\Models\UserModel');
373375

374376
$this->assertInstanceOf(UserModel::class, $model);
@@ -382,7 +384,7 @@ public function testDefineNonExistentClass(): void
382384
Factories::define(
383385
'models',
384386
'CodeIgniter\Shield\Models\UserModel',
385-
'App\Models\UserModel',
387+
'App\Models\UserModel', // @phpstan-ignore argument.type (deliberately does not exist)
386388
);
387389
}
388390

@@ -398,7 +400,7 @@ public function testDefineAfterLoading(): void
398400
Factories::define(
399401
'models',
400402
UserModel::class,
401-
'App\Models\UserModel',
403+
'App\Models\UserModel', // @phpstan-ignore argument.type (deliberately does not exist)
402404
);
403405
}
404406

0 commit comments

Comments
 (0)