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
31 changes: 27 additions & 4 deletions src/Database/Resource.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

namespace Minz\Database;

use Minz\Errors;
use Minz\Request;

/**
Expand Down Expand Up @@ -53,20 +54,42 @@ trait Resource
*/
public static function loadFromRequest(Request $request, string $parameter = 'id'): ?self
{
$pk_value = $request->parameters->getString($parameter, '');
$pk_column = self::primaryKeyColumn();
$column_declarations = self::databaseColumns();
$pk_column_declaration = $column_declarations[$pk_column];
$pk_type = $pk_column_declaration['type'];

if ($pk_type === 'int') {
$pk_value = $request->parameters->getInteger($parameter);
} elseif ($pk_type === 'string') {
$pk_value = $request->parameters->getString($parameter);
} else {
$pk_value = null;
}

if ($pk_value === null) {
return null;
}

return self::find($pk_value);
}

/**
* Return a Recordable model by using a request parameter as primary key
* value, or fail if none is found.
*
* @throws \Minz\Errors\MissingRecordError
* @throws Errors\MissingRecordError
* If the model doesn't exist.
*/
public static function requireFromRequest(Request $request, string $parameter = 'id'): self
{
$pk_value = $request->parameters->getString($parameter, '');
return self::require($pk_value);
$model = self::loadFromRequest($request, $parameter);

if ($model === null) {
$class = self::class;
throw new Errors\MissingRecordError("No {$class} model matching '{$parameter}' request parameter.");
}

return $model;
}
}
33 changes: 32 additions & 1 deletion tests/Database/ResourceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,21 @@ public function testLoadFromRequestWithWrongId(): void
$this->assertNull($friend);
}

public function testLoadFromRequestWithInvalidParameterType(): void
{
/** @var int $id */
$id = models\Friend::create([
'name' => 'Alix',
]);
$request = new Request('GET', '/', parameters: [
'id' => 'foo',
]);

$friend = models\Friend::loadFromRequest($request);

$this->assertNull($friend);
}

public function testRequireFromRequest(): void
{
/** @var int $id */
Expand All @@ -81,7 +96,7 @@ public function testRequireFromRequest(): void
public function testRequireFromRequestWithUnknownId(): void
{
$this->expectException(Errors\MissingRecordError::class);
$this->expectExceptionMessage("AppTest\\models\\Friend model #42 does not exist");
$this->expectExceptionMessage("No AppTest\\models\\Friend model matching 'id' request parameter");

/** @var int $id */
$id = models\Friend::create([
Expand All @@ -93,4 +108,20 @@ public function testRequireFromRequestWithUnknownId(): void

models\Friend::requireFromRequest($request);
}

public function testRequireFromRequestWithInvalidParameterType(): void
{
$this->expectException(Errors\MissingRecordError::class);
$this->expectExceptionMessage("No AppTest\\models\\Friend model matching 'id' request parameter");

/** @var int $id */
$id = models\Friend::create([
'name' => 'Alix',
]);
$request = new Request('GET', '/', parameters: [
'id' => 'foo',
]);

models\Friend::requireFromRequest($request);
}
}