|
|
@@ -8,9 +8,11 @@ use ApiPlatform\Metadata\GraphQl\Mutation;
|
|
|
use ApiPlatform\Metadata\GraphQl\Query;
|
|
|
use ApiPlatform\Metadata\GraphQl\QueryCollection;
|
|
|
use ApiPlatform\Metadata\Link;
|
|
|
+use ApiPlatform\Metadata\ApiProperty;
|
|
|
use Webkul\BagistoApi\Dto\CreateProductReviewInput;
|
|
|
use Webkul\BagistoApi\Dto\UpdateProductReviewInput;
|
|
|
use Webkul\BagistoApi\Resolver\BaseQueryItemResolver;
|
|
|
+use Webkul\BagistoApi\State\ProductReviewLikeProcessor;
|
|
|
use Webkul\BagistoApi\State\ProductReviewProcessor;
|
|
|
use Webkul\BagistoApi\State\ProductReviewProvider;
|
|
|
use Webkul\BagistoApi\State\ProductReviewUpdateProvider;
|
|
|
@@ -214,6 +216,51 @@ use ApiPlatform\OpenApi\Model\Operation;
|
|
|
],
|
|
|
),
|
|
|
),
|
|
|
+ new \ApiPlatform\Metadata\Post(
|
|
|
+ uriTemplate: '/reviews/{id}/like',
|
|
|
+ processor: ProductReviewLikeProcessor::class,
|
|
|
+ denormalizationContext: [
|
|
|
+ 'allow_extra_attributes' => true,
|
|
|
+ ],
|
|
|
+ openapi: new Operation(
|
|
|
+ tags: ['Customer Review'],
|
|
|
+ summary: 'Like a product review',
|
|
|
+ description: 'Adds a like to a review. Uses `client_id` (device identifier) to track whether the current visitor has already liked. If already liked, returns an error. Guests can like; `client_id` is a UUID the client generates and stores locally.',
|
|
|
+ requestBody: new \ApiPlatform\OpenApi\Model\RequestBody(
|
|
|
+ required: true,
|
|
|
+ content: new \ArrayObject([
|
|
|
+ 'application/json' => [
|
|
|
+ 'schema' => [
|
|
|
+ 'type' => 'object',
|
|
|
+ 'required' => ['client_id'],
|
|
|
+ 'properties' => [
|
|
|
+ 'client_id' => ['type' => 'string', 'example' => '550e8400-e29b-41d4-a716-446655440000', 'description' => 'Device/visitor identifier (UUID generated by client, stored locally)'],
|
|
|
+ ],
|
|
|
+ ],
|
|
|
+ 'example' => [
|
|
|
+ 'client_id' => '550e8400-e29b-41d4-a716-446655440000',
|
|
|
+ ],
|
|
|
+ ],
|
|
|
+ ]),
|
|
|
+ ),
|
|
|
+ responses: [
|
|
|
+ '200' => new \ApiPlatform\OpenApi\Model\Response(
|
|
|
+ description: 'Like added.',
|
|
|
+ content: new \ArrayObject([
|
|
|
+ 'application/json' => [
|
|
|
+ 'example' => [
|
|
|
+ 'id' => 2,
|
|
|
+ 'liked' => true,
|
|
|
+ 'likeCount' => 42,
|
|
|
+ ],
|
|
|
+ ],
|
|
|
+ ]),
|
|
|
+ ),
|
|
|
+ '400' => new \ApiPlatform\OpenApi\Model\Response(description: 'Already liked this review.'),
|
|
|
+ '404' => new \ApiPlatform\OpenApi\Model\Response(description: 'Review not found.'),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ),
|
|
|
],
|
|
|
graphQlOperations: [
|
|
|
new QueryCollection(
|
|
|
@@ -312,6 +359,7 @@ class ProductReview extends \Webkul\Product\Models\ProductReview
|
|
|
'product_id',
|
|
|
'customer_id',
|
|
|
'name',
|
|
|
+ 'like_count',
|
|
|
];
|
|
|
|
|
|
protected $casts = [
|
|
|
@@ -322,6 +370,7 @@ class ProductReview extends \Webkul\Product\Models\ProductReview
|
|
|
'comment' => 'string',
|
|
|
'name' => 'string',
|
|
|
'rating' => 'int',
|
|
|
+ 'like_count' => 'int',
|
|
|
'status' => 'string',
|
|
|
'created_at' => 'datetime',
|
|
|
'updated_at' => 'datetime',
|
|
|
@@ -346,6 +395,22 @@ class ProductReview extends \Webkul\Product\Models\ProductReview
|
|
|
return $this->getAttribute('id');
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 点赞总数(Eloquen 访问器,snake_case 输出 like_count)
|
|
|
+ */
|
|
|
+ public function getLikeCountAttribute(): int
|
|
|
+ {
|
|
|
+ return (int) ($this->attributes['like_count'] ?? 0);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 当前访客是否点赞(Eloquen 访问器,snake_case 输出 liked)
|
|
|
+ */
|
|
|
+ public function getLikedAttribute(): bool
|
|
|
+ {
|
|
|
+ return (bool) ($this->attributes['liked'] ?? false);
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Override __isset to ensure isset() works correctly with __get()
|
|
|
* This is critical for Symfony PropertyAccessor which checks isset() before reading.
|
|
|
@@ -364,7 +429,7 @@ class ProductReview extends \Webkul\Product\Models\ProductReview
|
|
|
*/
|
|
|
public function __set($key, $value)
|
|
|
{
|
|
|
- if (in_array($key, ['id', 'product_id', 'customer_id', 'title', 'comment', 'rating', 'name', 'email', 'status', 'created_at', 'updated_at'])) {
|
|
|
+ if (in_array($key, ['id', 'product_id', 'customer_id', 'title', 'comment', 'rating', 'name', 'email', 'status', 'like_count', 'liked', 'created_at', 'updated_at'])) {
|
|
|
$this->setAttribute($key, $value);
|
|
|
} else {
|
|
|
parent::__set($key, $value);
|