[graphql] take post metadata as arbitrary key-value pairs
I don't want "tags" and "source" to be special things where we explicitly handle those and fail to handle anything else. Making all metadata fields {string:string} pairs seems nicer, and matches with HTTP POST syntax
This commit is contained in:
parent
b9c7d632fd
commit
91e1cf3abe
2 changed files with 73 additions and 28 deletions
|
@ -19,23 +19,24 @@ class MetadataInput
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
#[\GQLA\Field]
|
#[\GQLA\Field]
|
||||||
public string $tags,
|
public string $key,
|
||||||
#[\GQLA\Field]
|
#[\GQLA\Field]
|
||||||
public string $source,
|
public string $value,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[\GQLA\Mutation]
|
/**
|
||||||
public static function update_post_metadata(int $post_id, MetadataInput $metadata): Image
|
* @param array<MetadataInput> $metadata
|
||||||
|
*/
|
||||||
|
#[\GQLA\Mutation(args: ["post_id" => "Int!", "metadata" => "[MetadataInput!]!"])]
|
||||||
|
public static function update_post_metadata(int $post_id, array $metadata): Image
|
||||||
{
|
{
|
||||||
global $user;
|
|
||||||
$image = Image::by_id_ex($post_id);
|
$image = Image::by_id_ex($post_id);
|
||||||
if (!$image->is_locked() || $user->can(Permissions::EDIT_IMAGE_LOCK)) {
|
$pairs = [];
|
||||||
send_event(new ImageInfoSetEvent($image, 0, [
|
foreach ($metadata as $m) {
|
||||||
'tags' => $metadata->tags,
|
$pairs[$m->key] = $m->value;
|
||||||
'source' => $metadata->source,
|
|
||||||
]));
|
|
||||||
}
|
}
|
||||||
|
send_event(new ImageInfoSetEvent($image, 0, $pairs));
|
||||||
return Image::by_id_ex($post_id);
|
return Image::by_id_ex($post_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,8 +162,7 @@ class GraphQL extends Extension
|
||||||
return ["error" => "User cannot create posts"];
|
return ["error" => "User cannot create posts"];
|
||||||
}
|
}
|
||||||
|
|
||||||
$common_tags = $_POST['common_tags'];
|
$metadata = only_strings($_POST);
|
||||||
$common_source = $_POST['common_source'];
|
|
||||||
|
|
||||||
$results = [];
|
$results = [];
|
||||||
for ($n = 0; $n < 100; $n++) {
|
for ($n = 0; $n < 100; $n++) {
|
||||||
|
@ -173,7 +173,7 @@ class GraphQL extends Extension
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
$results[] = ["image_ids" => self::handle_upload($n, $common_tags, $common_source)];
|
$results[] = ["image_ids" => self::handle_upload($n, $metadata)];
|
||||||
} catch(\Exception $e) {
|
} catch(\Exception $e) {
|
||||||
$results[] = ["error" => $e->getMessage()];
|
$results[] = ["error" => $e->getMessage()];
|
||||||
}
|
}
|
||||||
|
@ -182,9 +182,10 @@ class GraphQL extends Extension
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param array<string, string> $metadata
|
||||||
* @return int[]
|
* @return int[]
|
||||||
*/
|
*/
|
||||||
private static function handle_upload(int $n, string $common_tags, string $common_source): array
|
private static function handle_upload(int $n, array $metadata): array
|
||||||
{
|
{
|
||||||
global $database;
|
global $database;
|
||||||
if (!empty($_POST["url$n"])) {
|
if (!empty($_POST["url$n"])) {
|
||||||
|
@ -199,20 +200,12 @@ class GraphQL extends Extension
|
||||||
case UPLOAD_ERR_INI_SIZE:
|
case UPLOAD_ERR_INI_SIZE:
|
||||||
throw new UploadException("File larger than PHP can handle");
|
throw new UploadException("File larger than PHP can handle");
|
||||||
default:
|
default:
|
||||||
throw new UploadException("Mystery error: $ec");
|
throw new UploadException("Mystery error: ".var_export($ec, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$tags = trim($common_tags . " " . $_POST["tags$n"]);
|
$event = $database->with_savepoint(function () use ($tmpname, $filename, $n, $metadata) {
|
||||||
$source = $common_source;
|
return send_event(new DataUploadEvent($tmpname, $filename, $n, $metadata));
|
||||||
if (!empty($_POST["source$n"])) {
|
|
||||||
$source = $_POST["source$n"];
|
|
||||||
}
|
|
||||||
$event = $database->with_savepoint(function () use ($tmpname, $filename, $n, $tags, $source) {
|
|
||||||
return send_event(new DataUploadEvent($tmpname, $filename, $n, [
|
|
||||||
'tags' => Tag::explode($tags),
|
|
||||||
'source' => $source,
|
|
||||||
]));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return array_map(fn ($im) => $im->id, $event->images);
|
return array_map(fn ($im) => $im->id, $event->images);
|
||||||
|
|
|
@ -56,13 +56,65 @@ class GraphQLTest extends ShimmiePHPUnitTestCase
|
||||||
],
|
],
|
||||||
'width' => 640,
|
'width' => 640,
|
||||||
'owner' => [
|
'owner' => [
|
||||||
'id' => 'user:'.$image->get_owner()->id,
|
'id' => 'user:' . $image->get_owner()->id,
|
||||||
'name' => self::$user_name,
|
'name' => self::$user_name,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
]
|
],
|
||||||
,
|
|
||||||
],
|
],
|
||||||
], $result, var_export($result, true));
|
], $result, var_export($result, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testMutation(): void
|
||||||
|
{
|
||||||
|
$this->log_in_as_user();
|
||||||
|
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "test");
|
||||||
|
|
||||||
|
$result = $this->graphql("mutation {
|
||||||
|
update_post_metadata(
|
||||||
|
post_id: $image_id,
|
||||||
|
metadata: [
|
||||||
|
{key: \"tags\", value: \"newtag\"},
|
||||||
|
{key: \"source\", value: \"https://example.com\"}
|
||||||
|
]
|
||||||
|
) {
|
||||||
|
id
|
||||||
|
tags
|
||||||
|
source
|
||||||
|
}
|
||||||
|
}");
|
||||||
|
|
||||||
|
$this->assertEquals([
|
||||||
|
'data' => [
|
||||||
|
'update_post_metadata' => [
|
||||||
|
'id' => "post:$image_id",
|
||||||
|
'tags' => [
|
||||||
|
'newtag',
|
||||||
|
],
|
||||||
|
'source' => "https://example.com",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
], $result, var_export($result, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUpload(): void
|
||||||
|
{
|
||||||
|
global $database;
|
||||||
|
|
||||||
|
$this->log_in_as_user();
|
||||||
|
$_FILES = [
|
||||||
|
'data0' => [
|
||||||
|
'name' => 'puppy-hugs.jpg',
|
||||||
|
'type' => 'image/jpeg',
|
||||||
|
'tmp_name' => 'tests/bedroom_workshop.jpg',
|
||||||
|
'error' => 0,
|
||||||
|
'size' => 271386,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
$page = $this->post_page("graphql_upload", ["tags" => "foo", "tags0" => "bar"]);
|
||||||
|
$this->assertEquals(200, $page->code);
|
||||||
|
$this->assertEquals(1, $database->get_one("SELECT COUNT(*) FROM images"));
|
||||||
|
$id = $database->get_one("SELECT id FROM images");
|
||||||
|
$this->assertEquals("{\"results\":[{\"image_ids\":[$id]}]}", $page->data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue