Update some types

* Remove empty values from types for serialization, so that empty values
are not sent with API requests
* Allow use of explicit setters for more complex types
This commit is contained in:
Timothy Warren 2018-08-09 11:34:02 -04:00
parent 6f7d94641e
commit 1dc1370115
9 changed files with 57 additions and 18 deletions

View File

@ -25,7 +25,7 @@ use Aviat\AnimeClient\API\{
HummingbirdClient,
ListItemInterface
};
use Aviat\AnimeClient\Types\AbstractType;
use Aviat\AnimeClient\Types\FormItemData;
use Aviat\Ion\Di\ContainerAware;
use Aviat\Ion\Json;
@ -112,7 +112,7 @@ final class ListItem implements ListItemInterface {
return Json::decode(wait($response->getBody()));
}
public function update(string $id, AbstractType $data): Request
public function update(string $id, FormItemData $data): Request
{
$authHeader = $this->getAuthHeader();
$requestData = [

View File

@ -40,6 +40,7 @@ use Aviat\AnimeClient\Types\{
AbstractType,
Anime,
FormItem,
FormItemData,
AnimeListItem,
MangaPage
};

View File

@ -125,13 +125,13 @@ final class AnimeListTransformer extends AbstractTransformer {
$untransformed = new AnimeFormItem([
'id' => $item['id'],
'mal_id' => $item['mal_id'] ?? NULL,
'data' => new AnimeFormItemData([
'data' => [
'status' => $item['watching_status'],
'reconsuming' => $rewatching,
'reconsumeCount' => $item['rewatched'],
'notes' => $item['notes'],
'private' => $privacy
])
]
]);
if (is_numeric($item['episodes_watched']) && $item['episodes_watched'] > 0)

View File

@ -17,7 +17,7 @@
namespace Aviat\AnimeClient\API;
use Amp\Artax\Request;
use Aviat\AnimeClient\Types\AbstractType;
use Aviat\AnimeClient\Types\FormItemData;
/**
* Common interface for anime and manga list item CRUD
@ -44,10 +44,10 @@ interface ListItemInterface {
* Update a list item
*
* @param string $id - The id of the list item to update
* @param AbstractType $data - The data with which to update the list item
* @param FormItemData $data - The data with which to update the list item
* @return Request
*/
public function update(string $id, AbstractType $data): Request;
public function update(string $id, FormItemData $data): Request;
/**
* Delete a list item

View File

@ -20,6 +20,7 @@ use Aviat\AnimeClient\Controller as BaseController;
use Aviat\AnimeClient\API\Kitsu\Transformer\AnimeListTransformer;
use Aviat\AnimeClient\API\Enum\AnimeWatchingStatus\Kitsu as KitsuWatchingStatus;
use Aviat\AnimeClient\API\Mapping\AnimeWatchingStatus;
use Aviat\AnimeClient\Types\AnimeFormItem;
use Aviat\Ion\Di\ContainerInterface;
use Aviat\Ion\Json;
use Aviat\Ion\StringWrapper;
@ -201,7 +202,7 @@ final class Anime extends BaseController {
// large form-based updates
$transformer = new AnimeListTransformer();
$postData = $transformer->untransform($data);
$fullResult = $this->model->updateLibraryItem($postData);
$fullResult = $this->model->updateLibraryItem(new AnimeFormItem($postData));
if ($fullResult['statusCode'] === 200)
{
@ -232,7 +233,7 @@ final class Anime extends BaseController {
$data = $this->request->getParsedBody();
}
$response = $this->model->updateLibraryItem($data);
$response = $this->model->updateLibraryItem(new AnimeFormItem($data));
$this->cache->clear();
$this->outputJSON($response['body'], $response['statusCode']);

View File

@ -34,12 +34,24 @@ abstract class AbstractType implements ArrayAccess {
/**
* Sets the properties by using the constructor
*
* @param array $data
* @param mixed $data
*/
public function __construct(array $data = [])
public function __construct($data = [])
{
foreach ($data as $key => $value) {
$this->$key = $value;
$typeKeys = array_keys((array)$this);
$dataKeys = array_keys((array)$data);
$unsetKeys = array_diff($typeKeys, $dataKeys);
foreach ($data as $key => $value)
{
$this->__set($key, $value);
}
// Remove unset keys so that they aren't serialized
foreach ($unsetKeys as $k)
{
unset($this->$k);
}
}
@ -63,7 +75,16 @@ abstract class AbstractType implements ArrayAccess {
*/
public function __set($name, $value): void
{
if (!property_exists($this, $name)) {
$setterMethod = 'set' . ucfirst($name);
if (method_exists($this, $setterMethod))
{
$this->$setterMethod($value);
return;
}
if (!property_exists($this, $name))
{
$existing = json_encode($this);
throw new LogicException("Trying to set non-existent property: '$name'. Existing properties: $existing");
@ -80,7 +101,8 @@ abstract class AbstractType implements ArrayAccess {
*/
public function __get($name)
{
if (property_exists($this, $name)) {
if (property_exists($this, $name))
{
return $this->$name;
}
@ -127,6 +149,9 @@ abstract class AbstractType implements ArrayAccess {
*/
public function offsetUnset($offset): void
{
// Do nothing!
if ($this->offsetExists($offset))
{
unset($this->$offset);
}
}
}

View File

@ -19,4 +19,9 @@ namespace Aviat\AnimeClient\Types;
/**
* Type representing an Anime object for display
*/
final class AnimeFormItem extends FormItem { }
final class AnimeFormItem extends FormItem {
public function setData($value): void
{
$this->data = new AnimeFormItemData($value);
}
}

View File

@ -23,5 +23,7 @@ abstract class FormItem extends AbstractType {
public $id;
public $mal_id;
public $data;
abstract public function setData($value): void;
}

View File

@ -19,5 +19,10 @@ namespace Aviat\AnimeClient\Types;
/**
* Form data for updating a Manga List item
*/
final class MangaFormItem extends FormItem { }
final class MangaFormItem extends FormItem {
public function setData($value): void
{
$this->data = new MangaFormItemData($value);
}
}