- Add In/InArray support - Add ORDER BY support for `Find` functions - Update dependencies - Implement fixes identified via static analysis Reviewed-on: #5
54 lines
1.7 KiB
PHP
54 lines
1.7 KiB
PHP
<?php
|
|
/**
|
|
* @author Daniel J. Summers <daniel@bitbadger.solutions>
|
|
* @license MIT
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace BitBadger\PDODocument\Mapper;
|
|
|
|
use BitBadger\PDODocument\DocumentException;
|
|
use Exception;
|
|
use JsonMapper;
|
|
|
|
/**
|
|
* Map domain class instances from JSON documents
|
|
*
|
|
* @template TDoc The type of document returned by this mapper
|
|
* @implements Mapper<TDoc> Provide a mapping from JSON
|
|
*/
|
|
class DocumentMapper implements Mapper
|
|
{
|
|
/**
|
|
* Constructor
|
|
*
|
|
* @param class-string<TDoc> $className The type of class to be returned by this mapping
|
|
* @param string $fieldName The name of the field (optional; defaults to `data`)
|
|
*/
|
|
public function __construct(public string $className, public string $fieldName = 'data') {}
|
|
|
|
/**
|
|
* Map a result to a domain class instance
|
|
*
|
|
* @param array<string|int, mixed> $result An associative array representing a single database result
|
|
* @return TDoc The document, deserialized from its JSON representation
|
|
* @throws DocumentException If the JSON cannot be deserialized
|
|
*/
|
|
public function map(array $result): mixed
|
|
{
|
|
try {
|
|
if (method_exists($this->className, 'fromJsonString')) {
|
|
return $this->className::fromJsonString($result[$this->fieldName]);
|
|
}
|
|
$json = json_decode($result[$this->fieldName]);
|
|
if (is_null($json)) {
|
|
throw new DocumentException("Could not map document for $this->className: " . json_last_error_msg());
|
|
}
|
|
return (new JsonMapper())->map($json, $this->className);
|
|
} catch (Exception $ex) {
|
|
throw new DocumentException("Could not map document for $this->className", previous: $ex);
|
|
}
|
|
}
|
|
}
|