PHPackages                             lyrasoft/feedback - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. lyrasoft/feedback

ActiveWindwalker-package[Utility &amp; Helpers](/categories/utility)

lyrasoft/feedback
=================

LYRASOFT feedback package

1.1.1(2mo ago)0430↓33.3%MITPHPPHP &gt;=8.4.6

Since Jan 6Pushed 2mo ago1 watchersCompare

[ Source](https://github.com/lyrasoft/luna-feedback)[ Packagist](https://packagist.org/packages/lyrasoft/feedback)[ RSS](/packages/lyrasoft-feedback/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (1)Versions (5)Used By (0)

Lyrasoft Feedback Package
=========================

[](#lyrasoft-feedback-package)

[![](https://private-user-images.githubusercontent.com/1639206/400385316-f0058432-5dc6-448e-b5f2-2d8233119df2.jpg?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzIyNDEyODYsIm5iZiI6MTc3MjI0MDk4NiwicGF0aCI6Ii8xNjM5MjA2LzQwMDM4NTMxNi1mMDA1ODQzMi01ZGM2LTQ0OGUtYjVmMi0yZDgyMzMxMTlkZjIuanBnP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI2MDIyOCUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNjAyMjhUMDEwOTQ2WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9ZjNmNGI2MjlhYjJjZmIwNjcyNDg5OTZmNmRiNDYyMDM5YTQyOGUwMjU0NDcwYmJkMmJlNGFmYTRkNmRhYjEzNiZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QifQ.aY4dAbK7roWt_-zKnk0ygq_X6YgQOcHz7Qvz3HkGRhw)](https://private-user-images.githubusercontent.com/1639206/400385316-f0058432-5dc6-448e-b5f2-2d8233119df2.jpg?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzIyNDEyODYsIm5iZiI6MTc3MjI0MDk4NiwicGF0aCI6Ii8xNjM5MjA2LzQwMDM4NTMxNi1mMDA1ODQzMi01ZGM2LTQ0OGUtYjVmMi0yZDgyMzMxMTlkZjIuanBnP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI2MDIyOCUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNjAyMjhUMDEwOTQ2WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9ZjNmNGI2MjlhYjJjZmIwNjcyNDg5OTZmNmRiNDYyMDM5YTQyOGUwMjU0NDcwYmJkMmJlNGFmYTRkNmRhYjEzNiZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QifQ.aY4dAbK7roWt_-zKnk0ygq_X6YgQOcHz7Qvz3HkGRhw)

Lyrasoft Feedback package, contains comments and rating functions.

- [Lyrasoft Feedback Package](#lyrasoft-feedback-package)
    - [Installation](#installation)
        - [Language Files](#language-files)
        - [Seeders](#seeders)
    - [Register Admin Menu](#register-admin-menu)
    - [Comments](#comments)
        - [Comment Reply](#comment-reply)
        - [Comment With Ratings](#comment-with-ratings)
        - [Other Methods](#other-methods)
    - [Rating](#rating)
        - [Other Methods](#other-methods-1)
    - [Rating AJAX Button](#rating-ajax-button)
        - [AJAX Type Protect](#ajax-type-protect)
        - [AJAX Events](#ajax-events)
        - [Add Button to Vue App](#add-button-to-vue-app)
    - [Use `RatingRepository`](#use-ratingrepository)
        - [Join to List](#join-to-list)

Installation
------------

[](#installation)

Install from composer

```
composer require lyrasoft/feedback
```

Then copy files to project

```
php windwalker pkg:install lyrasoft/feedback -t routes -t migrations -t seeders
```

### Language Files

[](#language-files)

Add this line to admin &amp; front middleware if you don't want to override languages:

```
$this->lang->loadAllFromVendor('lyrasoft/feedback', 'ini');

// OR

$this->lang->loadAllFromVendor(\Lyrasoft\Feedback\FeedbackPackage::class, 'ini');
```

Or run this command to copy languages files:

```
php windwalker pkg:install lyrasoft/feedback -t lang

```

### Seeders

[](#seeders)

There are 2 example seeders auto installed, add `comment.seeder.php` and `rating.seeder.php` to `resources/seeders/main.php`

```
return [
    // ...

    __DIR__ . '/comment.seeder.php',
    __DIR__ . '/rating.seeder.php',

    // ...
];
```

If you don't need example seeders, write your own seeder by adding comments through service:

```
foreach ($articleIds as $articleId) {
    foreach (range(1, random_int(2, 5)) as $i) {
        $userId = $faker->randomElement($userIds);

        $item = $commentService->addComment(
            $type,
            $articleId,
            $faker->paragraph(4),
            $userId,
            extra: function (Comment $item) use ($faker) {
                $item->title = $faker->sentence(2);
                $item->created = $faker->dateTimeThisYear();
                $item->ordering = $item->count() + 1;
            }
        );
    }
}
```

Register Admin Menu
-------------------

[](#register-admin-menu)

Edit `resources/menu/admin/sidemenu.menu.php`

You must add `type` to route, every comment should contains type.

```
// Comment: Article
$menu->link('評論管理: 文章')
    ->to($nav->to('comment_list')->var('type', 'article'))
    ->icon('fal fa-comments');

// Or use translations

$menu->link($lang('feedback.comment.list.title', title: $lang('luna.article.title')))
    ->to($nav->to('comment_list')->var('type', 'article'))
    ->icon('fal fa-comments');
```

Comments
--------

[](#comments)

Add a comment to a type:

```
/** @var \Lyrasoft\Feedback\Service\CommentService $commentService */
$commentService->addComment(
    'flower', // Type
    $targetId, // Target ID
    'Comment Text...', // Content
    $user->id, // User ID
);
```

Add a comment and configure Comment entity:

```
use Lyrasoft\Feedback\Entity\Comment;

/** @var \Lyrasoft\Feedback\Service\CommentService $commentService */
$commentService->addComment(
    'flower', // Type
    $targetId, // Target ID
    'Comment Text...', // Content
    $user->id, // User ID

    // The extra can be callback or array
    extra: function (Comment $comment) {
        $comment->rating = 5; // If user mark as 5 star
        $comment->nickname = 'Another nickname';
    }
);
```

Comments ordering:

```
/** @var \Lyrasoft\Feedback\Service\CommentService $commentService */
$newComment = $commentService->addComment(
    'flower', // Type
    $targetId, // Target ID
    'Comment Text...', // Content
    $user->id, // User ID or User entity
    extra: function (Comment $comment) use ($commentService) {
        $count = $commentService->countWith($comment);
        // OR
        $count = $comment->count();

        // This optional if you want to set ordering to one comment
        $comment->ordering = $count + 1;
    }
);

// Or reorder all comments of one target item.
$commentService->reorderComments(
    'flower', // Type
    $targetId, // Target ID
);

// OR

$commentService->reorderWith($newComment);
```

### Comment Reply

[](#comment-reply)

There are 2 ways to add reply, one is just write reply content to comment, every comment contains only 1 reply:

```
/** @var \Lyrasoft\Feedback\Service\CommentService $commentService */

$commentService->addInstantReply(
    $comment, // Can be ID or entity
    'Reply text...',
    $user->id, // User ID or User entity
);
```

The other way is to create sub comments:

```
/** @var \Lyrasoft\Feedback\Service\CommentService $commentService */

$childComment = $commentService->addSubReply(
    $parentComment, // Can be ID or entity
    'Reply text...',
    $user->id, // User ID or User entity
    extra: function (Comment $comment) {
        // Configure comment entity before save
    }
);

// Optional: if you want to reorder it.
$commentService->reorderComments(
    $parentComment->type, // Type
    $parentComment->targetId, // Target ID
    $parentComment->id, // Parent ID
);

// OR

$commentService->reorderWith($childComment);
```

### Comment With Ratings

[](#comment-with-ratings)

If you want to add comment with ratings, you can simply add rating number to comment entity, and then update the origin rated item with new average rating:

```
/** @var \Lyrasoft\Feedback\Service\CommentService $commentService */
$newComment = $commentService->addComment(
    'flower', // Type
    $targetId, // Target ID
    'Comment Text...', // Content
    $user->id, // User ID or User entity
    extra: function (Comment $comment) use ($commentService) {
        $comment->rating = 4; // If user mark as 4 star
    }
);

// Update origin rated item
$orm->updateBatch(
    Target::class,
    [
        'rating_avg' => $commentService->calcAvgRatingWith($newComment),
        'rating_count' => $commentService->countWith($newComment),
    ],
    $targetId,
);
```

> !\[note\] If you need a like system without comments, you can use `Rating` entity without `Comment` entity, and simply use `count()` to count total likes. See [Rating](#rating)

### Other Methods

[](#other-methods)

```
/** @var \Lyrasoft\Feedback\Service\CommentService $commentService */

// Create Comment Item
$comment = $commentService->createCommentItem($type, $targetId, 'text...', $user);

// count Comments
$count = $commentService->countComments($type, $targetId);

// Reorder
$commentService->reorderComments($type, $targetId);

// Calc average rating
$avg = $commentService->calcAvgRating($type, $targetId);
$avg = $commentService->calcAvgRatingWith($comment);

// Check has commented
$comment = $commentService->getComment($type, $targetId);
$bool = $commentService->isCommented($type, $targetId);

// Remove comment
$commentService->removeComment($type, $targetId);
```

---

Rating
------

[](#rating)

You can use Rating for the following purposes:

1. **Like system**: Users can like content to show their supports. In this case, the Rating's `rank` field can always be set to `1` as one LIKE. Afterwards, simply use `count()` to count the total likes.
2. **Star rating system**: Users can rate content with stars, e.g., from 1 to 5. In this case, the Rating's `rank` field can be set to the numeric star chosen by the user, and you can use `calcAvgRank()` to calculate the average.

Note

If you want users to leave comments while rating, it's recommended to use the `comments` table with a `rating`column, so you don't need a separate `ratings` table. See [Comment With Ratings](#comment-with-ratings)

Add a rating to a type:

```
/** @var \Lyrasoft\Feedback\Service\RatingService $ratingService */
$ratingService->addRating(
    'flower', // Type
    $targetId, // Target ID
    $user->id, // User ID
);
```

Add rating if not rated, and configure Rating entity:

```
use Lyrasoft\Feedback\Entity\Rating;

/** @var \Lyrasoft\Feedback\Service\RatingService $ratingService */
$ratingService->addRatingIfNotRated(
    'flower', // Type
    $targetId, // Target ID
    $user->id, // User ID

    // The extra can be callback or array
    extra: function (Rating $rating) {
        $rating->rank = 4.5; // If user mark as 4.5 star
    }
);
```

Rating ordering:

```
/** @var \Lyrasoft\Feedback\Service\RatingService $ratingService */
$newRating = $ratingService->addRating(
    'flower', // Type
    $targetId, // Target ID
    $user->id, // User ID or User entity
    extra: function (Rating $rating) use ($ratingService, $targetId) {
        $count = $ratingService->countWith($rating);
        // OR
        $count = $rating->count();

        // This optional if you want to set ordering to one comment
        $rating->ordering = $count + 1;
    }
);

// Update origin rated item
$orm->updateBatch(
    Target::class,
    ['rating' => $ratingService->calcAvgWith($rating)],
    $targetId,
);

// Or reorder all ratings of one target item.
$ratingService->reorderRatings(
    'flower', // Type
    $targetId, // Target ID
);
// OR
$ratingService->reorderWith($newRating);
```

### Other Methods

[](#other-methods-1)

```
/** @var \Lyrasoft\Feedback\Service\RatingService $ratingService */

// Calc average rank
$avg = $ratingService->calcAvgRank($type, $targetId);
$avg = $ratingService->calcAvgWith($rating);

// Get rating item or check is rated
$item = $ratingService->getRating($type, $targetId);
$bool = $ratingService->isRated($type, $targetId);

// Remove
$ratingService->removeRating($type, $targetId);
```

Rating AJAX Button
------------------

[](#rating-ajax-button)

Add `useRatingButtons()` to front `main.ts` file:

```
import { useRatingButtons } from '@lyrasoft/feedback';

// ...

useRatingButtons();
```

Then uou can add button components everywhere in blade template:

```

        ...

```

Available params:

NameTypeDescription`type`string or enumThe rating type`id`string or intThe item ID`rated`bool or intIs this item rated by current user, will auto load from DB if without this params.`class-active`stringThe button class if active.`class-inactive`stringThe button class if inactive.`icon-active`stringThe icon class if active.`icon-inactive`stringThe button class if inactive.`title-active`stringThe tooltip title if active.`title-inactive`stringThe tooltip title if inactive.`tag`stringThe button HTML tag.### AJAX Type Protect

[](#ajax-type-protect)

By default, favorite package will not allow any types sent from browser.

You can configure allowed types in config file:

```
return [
    'feedback' => [
        // ...

        'rating' => [
            'ajax_type_protect' => true,
            'ajax_allow_types' => [
                'article',
                '...' //
