Skip to content
Open
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
1 change: 1 addition & 0 deletions system/Config/Factories.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
* large performance boost and helps keep code clean of lengthy
* instantiation checks.
*
* @method static object|null cells(string $alias, array<string, bool|string|null> $options = [])
* @method static BaseConfig|null config(...$arguments)
* @method static Model|null models(string $alias, array $options = [], ?ConnectionInterface &$conn = null)
* @see \CodeIgniter\Config\FactoriesTest
Expand Down
4 changes: 4 additions & 0 deletions system/Traits/PropertiesTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ trait PropertiesTrait
{
/**
* Attempts to set the values of public class properties.
*
* @param array<string, mixed> $params
*/
final public function fill(array $params): self
{
Expand Down Expand Up @@ -61,6 +63,8 @@ public function getProperties(object $obj): array

/**
* Get the protected and private properties of the class and return as an array.
*
* @return list<ReflectionProperty>
*/
final public function getNonPublicProperties(): array
{
Expand Down
16 changes: 11 additions & 5 deletions system/View/Cell.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,7 @@ public function render(string $library, $params = null, int $ttl = 0, ?string $c
{
[$instance, $method] = $this->determineClass($library);

$class = is_object($instance)
? $instance::class
: null;
$class = $instance::class;

$params = $this->prepareParams($params);

Expand Down Expand Up @@ -160,6 +158,8 @@ public function prepareParams($params)
/**
* Given the library string, attempts to determine the class and method
* to call.
*
* @return array{object, string}
*/
protected function determineClass(string $library): array
{
Expand Down Expand Up @@ -198,6 +198,8 @@ protected function determineClass(string $library): array

/**
* Renders a cell that extends the BaseCell class.
*
* @param array<string, mixed> $params
*/
final protected function renderCell(BaseCell $instance, string $method, array $params): string
{
Expand Down Expand Up @@ -234,6 +236,10 @@ final protected function renderCell(BaseCell $instance, string $method, array $p
* Returns the values from $params that match the parameters
* for a method, in the order they are defined. This allows
* them to be passed directly into the method.
*
* @param array<string, mixed> $params
*
* @return list<mixed>
*/
private function getMethodParams(BaseCell $instance, string $method, array $params): array
{
Expand Down Expand Up @@ -262,9 +268,9 @@ private function getMethodParams(BaseCell $instance, string $method, array $para
*
* @todo Determine if this can be refactored to use $this-getMethodParams().
*
* @param object $instance
* @param array<string, mixed> $params
*/
final protected function renderSimpleClass($instance, string $method, array $params, string $class): string
final protected function renderSimpleClass(object $instance, string $method, array $params, string $class): string
{
// Try to match up the parameter list we were provided
// with the parameter name in the callback method.
Expand Down
6 changes: 6 additions & 0 deletions system/View/Cells/Cell.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ public function setView(string $view)
* current scope and captures the output buffer instead of
* relying on the view service.
*
* @param array<string, mixed> $data
*
* @throws LogicException
*/
final protected function view(?string $view, array $data = []): string
Expand Down Expand Up @@ -129,6 +131,10 @@ public function __toString(): string
/**
* Allows the developer to define computed properties
* as methods with `get` prefixed to the protected/private property name.
*
* @param array<string, mixed> $properties
*
* @return array<string, mixed>
*/
private function includeComputedProperties(array $properties): array
{
Expand Down
6 changes: 3 additions & 3 deletions system/View/Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -543,9 +543,9 @@ public function setConditionalDelimiters($leftDelimiter = '{', $rightDelimiter =
* Handles replacing a pseudo-variable with the actual content. Will double-check
* for escaping brackets.
*
* @param array|string $pattern
* @param string $content
* @param string $template
* @param array<array-key, string>|string $pattern
* @param string $content
* @param string $template
*/
protected function replaceSingle($pattern, $content, $template, bool $escape = false): string
{
Expand Down
7 changes: 5 additions & 2 deletions tests/system/View/ParserPluginTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,11 @@ protected function setUp(): void

Services::reset(true);

$this->parser = service('parser');
$this->validator = service('validation');
$this->parser = service('parser');

$validator = service('validation');
$this->assertInstanceOf(Validation::class, $validator);
$this->validator = $validator;
}

public function testCurrentURL(): void
Expand Down
9 changes: 6 additions & 3 deletions tests/system/View/ParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,9 @@ public function testEscHandling($value, $expected = null): void
$this->assertSame($expected, \esc($value));
}

/**
* @return iterable<string, list<mixed>>
*/
public static function provideEscHandling(): iterable
{
return [
Expand Down Expand Up @@ -543,20 +546,20 @@ public function testNoEscapingSetData(): void
{
$template = '{ foo | noescape}';

$this->parser->setData(['foo' => 'http://foo.com'], 'unknown');
$this->parser->setData(['foo' => 'http://foo.com'], 'unknown'); // @phpstan-ignore argument.type (deliberately invalid context)
$this->assertSame('http://foo.com', $this->parser->renderString($template));
}

public function testAutoEscaping(): void
{
$this->parser->setData(['foo' => 'http://foo.com'], 'unknown');
$this->parser->setData(['foo' => 'http://foo.com'], 'unknown'); // @phpstan-ignore argument.type (deliberately invalid context)

$this->assertSame('html', $this->parser->shouldAddEscaping('{ foo | this | that }'));
}

public function testAutoEscapingNot(): void
{
$this->parser->setData(['foo' => 'http://foo.com'], 'unknown');
$this->parser->setData(['foo' => 'http://foo.com'], 'unknown'); // @phpstan-ignore argument.type (deliberately invalid context)
$this->assertFalse($this->parser->shouldAddEscaping('{ foo | noescape }'));
}

Expand Down
35 changes: 23 additions & 12 deletions tests/system/View/TableTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ public function testPrepArgs(): void

$this->assertSame(
$expected,
$this->table->prepArgs(['name', 'color', 'size']),
$this->table->prepArgs(['name', 'color', 'size']), // @phpstan-ignore method.notFound (Testing MockTable::__call() fallback)
);

// with cell attributes
Expand All @@ -213,7 +213,7 @@ public function testPrepArgs(): void

$this->assertSame(
$expected,
$this->table->prepArgs(['name', 'color', 'size', ['data' => 'weight', 'class' => 'awesome']]),
$this->table->prepArgs(['name', 'color', 'size', ['data' => 'weight', 'class' => 'awesome']]), // @phpstan-ignore method.notFound (Testing MockTable::__call() fallback)
);
}

Expand Down Expand Up @@ -241,7 +241,7 @@ public function testDefaultTemplateKeys(): void
];

foreach ($keys as $key) {
$this->assertArrayHasKey($key, $this->table->defaultTemplate());
$this->assertArrayHasKey($key, $this->table->defaultTemplate()); // @phpstan-ignore method.notFound (Testing MockTable::__call() fallback)
}
}

Expand All @@ -251,14 +251,14 @@ public function testCompileTemplate(): void

// non default key
$this->table->setTemplate(['nonsense' => 'foo']);
$this->table->compileTemplate();
$this->table->compileTemplate(); // @phpstan-ignore method.notFound (Testing MockTable::__call() fallback)

$this->assertArrayHasKey('nonsense', $this->table->template);
$this->assertSame('foo', $this->table->template['nonsense']);

// override default
$this->table->setTemplate(['table_close' => '</table junk>']);
$this->table->compileTemplate();
$this->table->compileTemplate(); // @phpstan-ignore method.notFound (Testing MockTable::__call() fallback)

$this->assertArrayHasKey('table_close', $this->table->template);
$this->assertSame('</table junk>', $this->table->template['table_close']);
Expand All @@ -267,9 +267,9 @@ public function testCompileTemplate(): void
public function testMakeColumns(): void
{
// Test bogus parameters
$this->assertFalse($this->table->makeColumns('invalid_junk'));
$this->assertFalse($this->table->makeColumns('invalid_junk')); // @phpstan-ignore argument.type (deliberately wrong type)
$this->assertFalse($this->table->makeColumns([]));
$this->assertFalse($this->table->makeColumns(['one', 'two'], '2.5'));
$this->assertFalse($this->table->makeColumns(['one', 'two'], '2.5')); // @phpstan-ignore argument.type (deliberately wrong type)

// Now on to the actual column creation

Expand Down Expand Up @@ -345,12 +345,12 @@ public function testSetFromArray(): void
];

$this->table->autoHeading = false;
$this->table->setFromArray($data);
$this->table->setFromArray($data); // @phpstan-ignore method.notFound (Testing MockTable::__call() fallback)
$this->assertEmpty($this->table->heading);

$this->table->clear();

$this->table->setFromArray($data);
$this->table->setFromArray($data); // @phpstan-ignore method.notFound (Testing MockTable::__call() fallback)
$this->assertCount(2, $this->table->rows);

$expected = [
Expand All @@ -376,9 +376,9 @@ public function testSetFromObject(): void
$dummy->connID = null;
$dummy->resultID = null;

$DBResult = new DBResultDummy($dummy->connID, $dummy->resultID);
$DBResult = new DBResultDummy($dummy->connID, $dummy->resultID); // @phpstan-ignore argument.type, argument.type (deliberately null, exercising the fallback path)

$this->table->setFromDBResult($DBResult);
$this->table->setFromDBResult($DBResult); // @phpstan-ignore method.notFound (Testing MockTable::__call() fallback)

$expected = [
['data' => 'name'],
Expand Down Expand Up @@ -733,7 +733,7 @@ public function testGenerateFromDBResult(): void
$dummy = new stdClass();
$dummy->connID = null;
$dummy->resultID = null;
$DBResult = new DBResultDummy($dummy->connID, $dummy->resultID);
$DBResult = new DBResultDummy($dummy->connID, $dummy->resultID); // @phpstan-ignore argument.type, argument.type (deliberately null, exercising the fallback path)

$table = $this->table->generate($DBResult);

Expand Down Expand Up @@ -780,6 +780,10 @@ public function testInvalidCallback(): void
$this->assertStringContainsString('<td>Fred</td><td><strong>Blue</strong></td><td>Small</td>', $generated);
}

/**
* @param array<string, string> $heading
* @param array<string, int|string> $row
*/
#[DataProvider('orderedColumnUsecases')]
public function testAddRowAndGenerateOrderedColumns(array $heading, array $row, string $expectContainsString): void
{
Expand All @@ -792,6 +796,10 @@ public function testAddRowAndGenerateOrderedColumns(array $heading, array $row,
$this->assertStringContainsString($expectContainsString, $generated);
}

/**
* @param array<string, string> $heading
* @param array<string, int|string> $row
*/
#[DataProvider('orderedColumnUsecases')]
public function testGenerateOrderedColumns(array $heading, array $row, string $expectContainsString): void
{
Expand All @@ -803,6 +811,9 @@ public function testGenerateOrderedColumns(array $heading, array $row, string $e
$this->assertStringContainsString($expectContainsString, $generated);
}

/**
* @return iterable<string, array{heading: array<string, string>, row: array<string, int|string>, expectContainsString: string}>
*/
public static function orderedColumnUsecases(): iterable
{
yield from [
Expand Down
27 changes: 1 addition & 26 deletions utils/phpstan-baseline/argument.type.neon
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# total 25 errors
# total 16 errors

parameters:
ignoreErrors:
Expand Down Expand Up @@ -66,28 +66,3 @@ parameters:
message: '#^Parameter \#1 \$format of method CodeIgniter\\RESTful\\ResourceController\:\:setFormat\(\) expects ''json''\|''xml'', ''Nonsense'' given\.$#'
count: 1
path: ../../tests/system/RESTful/ResourceControllerTest.php

-
message: '#^Parameter \#2 \$context of method CodeIgniter\\View\\Parser\:\:setData\(\) expects ''attr''\|''css''\|''html''\|''js''\|''raw''\|''url''\|null, ''unknown'' given\.$#'
count: 3
path: ../../tests/system/View/ParserTest.php

-
message: '#^Parameter \#1 \$array of method CodeIgniter\\View\\Table\:\:makeColumns\(\) expects list\<string\>, ''invalid_junk'' given\.$#'
count: 1
path: ../../tests/system/View/TableTest.php

-
message: '#^Parameter \#1 \$connID of class CodeIgniter\\View\\DBResultDummy constructor expects mysqli, null given\.$#'
count: 2
path: ../../tests/system/View/TableTest.php

-
message: '#^Parameter \#2 \$columnLimit of method CodeIgniter\\View\\Table\:\:makeColumns\(\) expects int, string given\.$#'
count: 1
path: ../../tests/system/View/TableTest.php

-
message: '#^Parameter \#2 \$resultID of class CodeIgniter\\View\\DBResultDummy constructor expects mysqli_result, null given\.$#'
count: 2
path: ../../tests/system/View/TableTest.php
7 changes: 1 addition & 6 deletions utils/phpstan-baseline/assign.propertyType.neon
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# total 20 errors
# total 19 errors

parameters:
ignoreErrors:
Expand Down Expand Up @@ -61,8 +61,3 @@ parameters:
message: '#^Property Config\\Cookie\:\:\$samesite \(''''\|''Lax''\|''None''\|''Strict''\) does not accept ''Invalid''\.$#'
count: 1
path: ../../tests/system/Session/SessionTest.php

-
message: '#^Property CodeIgniter\\View\\ParserPluginTest\:\:\$validator \(CodeIgniter\\Validation\\Validation\) does not accept CodeIgniter\\Validation\\ValidationInterface\.$#'
count: 1
path: ../../tests/system/View/ParserPluginTest.php
2 changes: 1 addition & 1 deletion utils/phpstan-baseline/loader.neon
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# total 419 errors
# total 381 errors

includes:
- argument.type.neon
Expand Down
27 changes: 1 addition & 26 deletions utils/phpstan-baseline/method.notFound.neon
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# total 20 errors
# total 12 errors

parameters:
ignoreErrors:
Expand Down Expand Up @@ -41,28 +41,3 @@ parameters:
message: '#^Call to an undefined method CodeIgniter\\HTTP\\ResponseInterface\:\:pretend\(\)\.$#'
count: 1
path: ../../tests/system/RESTful/ResourceControllerTest.php

-
message: '#^Call to an undefined method CodeIgniter\\View\\Table\:\:compileTemplate\(\)\.$#'
count: 2
path: ../../tests/system/View/TableTest.php

-
message: '#^Call to an undefined method CodeIgniter\\View\\Table\:\:defaultTemplate\(\)\.$#'
count: 1
path: ../../tests/system/View/TableTest.php

-
message: '#^Call to an undefined method CodeIgniter\\View\\Table\:\:prepArgs\(\)\.$#'
count: 2
path: ../../tests/system/View/TableTest.php

-
message: '#^Call to an undefined method CodeIgniter\\View\\Table\:\:setFromArray\(\)\.$#'
count: 2
path: ../../tests/system/View/TableTest.php

-
message: '#^Call to an undefined method CodeIgniter\\View\\Table\:\:setFromDBResult\(\)\.$#'
count: 1
path: ../../tests/system/View/TableTest.php
Loading
Loading