Skip to content

Commit

Permalink
[1.x] Adding backed enum support to query builder for meta (#478)
Browse files Browse the repository at this point in the history
* Revert "Revert "Support PHPUnit 10" from 0.12.x (#475)"

This reverts commit 9b6517e.

* Fixing versions

* Adding enum support to meta and query builder

* Remove unused ref

* Use only enum on the query builder
  • Loading branch information
srtfisher authored Nov 29, 2023
1 parent acfeb9a commit 0dc7855
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 7 deletions.
2 changes: 1 addition & 1 deletion src/mantle/database/model/class-post.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
* @method static \Mantle\Database\Query\Post_Query_Builder<static> whereTerm( array|\WP_Term|\Mantle\Database\Model\Term|int $term, ?string $taxonomy = null, string $operator = 'IN', string $field = 'term_id' )
* @method static \Mantle\Database\Query\Post_Query_Builder<static> andWhereTerm( array|\WP_Term|\Mantle\Database\Model\Term|int $term, ?string $taxonomy = null, string $operator = 'IN', string $field = 'term_id' )
* @method static \Mantle\Database\Query\Post_Query_Builder<static> orWhereTerm( array|\WP_Term|\Mantle\Database\Model\Term|int $term, ?string $taxonomy = null, string $operator = 'IN', string $field = 'term_id' )
* @method static \Mantle\Database\Query\Post_Query_Builder<static> whereMeta( string $key, mixed $value, string $operator = '=' )
* @method static \Mantle\Database\Query\Post_Query_Builder<static> whereMeta( string|\BackedEnum $key, mixed $value, string $operator = '=' )
* @method static \Mantle\Database\Query\Post_Query_Builder<static> whereRaw( array|string $column, ?string $operator = null, mixed $value = null, string $boolean = 'AND' )
* @method static \Mantle\Database\Query\Post_Query_Builder<static> where_raw( array|string $column, ?string $operator = null, mixed $value = null, string $boolean = 'AND' )
* @method static \Mantle\Database\Query\Post_Query_Builder<static> orWhereRaw( array|string $column, ?string $operator = null, mixed $value = null, string $boolean = 'AND' )
Expand Down
21 changes: 18 additions & 3 deletions src/mantle/database/model/meta/trait-model-meta.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace Mantle\Database\Model\Meta;

use BackedEnum;
use Mantle\Database\Model\Model_Exception;

/**
Expand Down Expand Up @@ -47,7 +48,7 @@ public function add_meta( string $meta_key, mixed $meta_value, mixed $prev_value
return;
}

\add_metadata( $this->get_meta_type(), $this->id(), $meta_key, $meta_value );
\add_metadata( $this->get_meta_type(), $this->id(), $meta_key, $this->serialize_value_for_storage( $meta_value ) );
}

/**
Expand All @@ -63,7 +64,7 @@ public function set_meta( string $meta_key, mixed $meta_value, mixed $prev_value
return;
}

\update_metadata( $this->get_meta_type(), $this->id(), $meta_key, $meta_value, $prev_value );
\update_metadata( $this->get_meta_type(), $this->id(), $meta_key, $this->serialize_value_for_storage( $meta_value ), $prev_value );
}

/**
Expand All @@ -73,7 +74,7 @@ public function set_meta( string $meta_key, mixed $meta_value, mixed $prev_value
* @param mixed $meta_value Previous meta value to delete.
*/
public function delete_meta( string $meta_key, mixed $meta_value = '' ): void {
\delete_metadata( $this->get_meta_type(), $this->id(), $meta_key, $meta_value );
\delete_metadata( $this->get_meta_type(), $this->id(), $meta_key, $this->serialize_value_for_storage( $meta_value ) );
}

/**
Expand Down Expand Up @@ -141,4 +142,18 @@ public function store_queued_meta(): void {

$this->queued_meta = [];
}

/**
* Serialize meta value for storage, converting all backed enums to their value.
*
* @param mixed $value Value to serialize.
* @return mixed
*/
protected function serialize_value_for_storage( mixed $value ): mixed {
if ( $value instanceof BackedEnum ) {
return $value->value;
}

return $value;
}
}
18 changes: 15 additions & 3 deletions src/mantle/database/query/class-builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Mantle\Database\Query;

use BackedEnum;
use Closure;
use Mantle\Container\Container;
use Mantle\Contracts\Database\Scope;
Expand Down Expand Up @@ -348,12 +349,20 @@ protected function resolve_attribute( string $attribute ): string {
/**
* Query by a meta field.
*
* @param string $key Meta key.
* @param mixed $value Meta value.
* @param string $compare Comparison method, defaults to '='.
* @param string|\BackedEnum $key Meta key.
* @param mixed $value Meta value.
* @param string $compare Comparison method, defaults to '='.
* @return static
*/
public function whereMeta( $key, $value, string $compare = '=' ) {
if ( $key instanceof BackedEnum ) {
$key = $key->value;
}

if ( $value instanceof BackedEnum ) {
$value = $value->value;
}

$meta_query = [
'compare' => $compare,
'key' => $key,
Expand All @@ -366,6 +375,7 @@ public function whereMeta( $key, $value, string $compare = '=' ) {
}

$this->meta_query[] = $meta_query;

return $this;
}

Expand All @@ -379,6 +389,7 @@ public function whereMeta( $key, $value, string $compare = '=' ) {
*/
public function andWhereMeta( ...$args ) {
$this->meta_query['relation'] = 'AND';

return $this->whereMeta( ...$args );
}

Expand All @@ -392,6 +403,7 @@ public function andWhereMeta( ...$args ) {
*/
public function orWhereMeta( ...$args ) {
$this->meta_query['relation'] = 'OR';

return $this->whereMeta( ...$args );
}

Expand Down
49 changes: 49 additions & 0 deletions tests/Database/Query/PostQueryBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,46 @@ protected static function get_random_post_id( $args = [] ): int {
array_pop( $post_ids );
return $post_ids[ array_rand( $post_ids ) ];
}

public function test_query_by_enum() {
// Check if enum is supported.
if ( PHP_VERSION_ID < 80100 ) {
$this->markTestSkipped( 'PHP 8.1+ is required for this test.' );
}

$post = static::factory()->post
->with_meta( [
'example-meta' => Testable_Meta_Values::Meta_Value_A,
Testable_Meta_Values::Meta_Key_A->value => Testable_Meta_Values::Meta_Value_A,
Testable_Meta_Values::Meta_Key_B->value => Testable_Meta_Values::Meta_Value_B,
] )
->as_models()
->create_and_get();

$this->assertEquals(
Testable_Meta_Values::Meta_Value_A->value,
$post->get_meta( 'example-meta' ),
);

$this->assertEquals(
Testable_Meta_Values::Meta_Value_B->value,
$post->get_meta( Testable_Meta_Values::Meta_Key_B->value ),
);

$this->assertEmpty(
Testable_Post::whereMeta( Testable_Meta_Values::Meta_Key_A->value, 'unknown' )->first(),
);

$this->assertEquals(
$post->id(),
Testable_Post::whereMeta( 'example-meta', Testable_Meta_Values::Meta_Value_A )->first()?->id,
);

$this->assertEquals(
$post->id(),
Testable_Post::whereMeta( Testable_Meta_Values::Meta_Key_A, Testable_Meta_Values::Meta_Value_A )->first()?->id,
);
}
}

class Testable_Post extends Post {
Expand All @@ -686,3 +726,12 @@ class Another_Testable_Post extends Post {
class Testable_Tag extends Term {
public static $object_name = 'post_tag';
}

if ( PHP_VERSION_ID >= 80100 ) {
enum Testable_Meta_Values: string {
case Meta_Key_A = 'meta-key-a';
case Meta_Key_B = 'meta-key-b';
case Meta_Value_A = 'meta-value-a';
case Meta_Value_B = 'meta-value-b';
}
}

0 comments on commit 0dc7855

Please sign in to comment.