PHPackages                             mmb/panelkit - 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. mmb/panelkit

ActiveLibrary

mmb/panelkit
============

Panel kit for mmb

0.1.1(1y ago)028PHP

Since Nov 9Pushed 1y agoCompare

[ Source](https://github.com/rapidmmb/panelkit)[ Packagist](https://packagist.org/packages/mmb/panelkit)[ RSS](/packages/mmb-panelkit/feed)WikiDiscussions 0.1 Synced 1mo ago

READMEChangelogDependencies (4)Versions (8)Used By (0)

Panel Kit
=========

[](#panel-kit)

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

[](#installation)

```
composer require mmb/panelkit
```

### Publish

[](#publish)

Optionally, you can publish the assets:

```
php artisan vendor:publish --tag="panelkit:config"
php artisan vendor:publish --tag="panelkit:lang"
```

Every
-----

[](#every)

Every is a service to notify the users by a message

### Ready To Use

[](#ready-to-use)

Add these lines to show global sending method actions:

```
$menu->schema([
    [
        $menu->key("Forward", fn () => EveryForwardForm::make()->request()),
        $menu->key("Message", fn () => EveryMessageForm::make()->request()),
    ]
])
```

### Fast Use

[](#fast-use)

Send to all users a message:

```
Every::toAll()
    ->send(['text' => 'Hello Everyone!'])
    ->log($this->update->getChat()->id)
    ->notify();
```

Send to specific users a dynamic message:

```
Every::to(fn () => BotUser::where('ban', false)->orderBy('created_at'))
    ->send()
    ->message(fn (BotUser $user) => ['text' => "Hello {$user->name}!"])
    ->log($this->update->getChat()->id)
    ->notify();
```

### Logger

[](#logger)

Logger logging the notifier status

Available builtin letters:

```
new PvEveryLogger(CHAT_ID)
```

Creating customize classes:

```
class CustomLogger implements EveryLogger
{

    public function created(EveryJob $job) : void
    {
        // ...
    }

    public function log(EveryJob $job) : void
    {
        // ...
    }

    public function error(EveryJob $job, \Throwable $exception) : void
    {
        // ...
    }

    public function completed(EveryJob $job) : void
    {
        // ...
    }

}
```

Usage:

```
Every::toAll()
    ->send(['text' => 'Foo'])
    ->logger(new CustomLogger())
    ->notify();
```

Lock
----

[](#lock)

Lock system used to protect contents by favorite lock methods like forcing channel joining

### Ready To Use

[](#ready-to-use-1)

Add handlers:

```
$handler->callback(LockMiddleAction::class),
LockRequest::for($this->context, 'main'), // For each groups
```

Use the section:

```
$menu->schema([
    [$menu->keyFor("🔒 Locks", LockResourceSection::class)],
]);
```

### Fast Use

[](#fast-use-1)

Works with locks:

```
$lock = Lock::add(...);  // To add a new lock
$lock->delete(); // To delete the lock
```

Adding the `required` to custom part of code:

```
LockRequest::for($this->context, 'main')->required();
```

### Fixed Channels

[](#fixed-channels)

Change the config:

```
    'lock' => [
        'fixed' => [
            [
                'chat_id' => -123455678,
                'title' => 'Join',
                'url' => 'https://t.me/Link',
                'group' => 'main',
            ],
        ],
    ],
```

### Lock Condition

[](#lock-condition)

```
class UserIsOddCondition implements LockCondition
{
    public function show() : bool
    {
        return BotUser::current()->id % 2 == 1;
    }
}
```

Set globally condition in config:

```
    'lock' => [
        'condition' => UserIsOddCondition::class,
    ],
```

Or set in specific request:

```
LockRequest::for($this->context, 'main')->withCondition(UserIsOddCondition::class)
```

### Customize

[](#customize)

Custom the alert dialog:

```
class PostLockRequest extends LockRequest
{

    #[Find]
    public Post $post;

    public function withPost(Post $post)
    {
        $this->post = $post;
        return $this;
    }

    #[FixedDialog('lock:{group:slug}:{post:slug}')]
    public function mainDialog(Dialog $dialog)
    {
        parent::mainDialog($dialog);

        $dialog
            ->on('submit', function () use ($dialog)
            {
                if ($this->locks)
                {
                    $this->tell(__('panelkit::lock.submit_invalid'), alert: true);
                    $dialog->reload();
                }
                else
                {
                    $this->update->getMessage()?->delete(ignore: true);
                    PostSection::invokes('main', $this->post);
                }
            }
            );
    }
}
```

Usage:

```
PostLockRequest::for($this->context, 'main')->withPost($myPost)->required();
```

Targets
-------

[](#targets)

Targets is a collection of tools to customize the actions

### Aim

[](#aim)

Aim set the target query and records

Available builtin aims:

```
new TgAllAim()
new TgCustomAim(new SerializableClosure(function () {...}))
```

Creating customize classes:

```
class TgNotBannedAim implements TgAim
{

    public function getQuery() : Builder
    {
        return BotUser::whereIsNull('ban_until')->orderBy('created_at');
    }

}
```

> We trust on `orderBy('created_at')` to sort the records by a stable order to prevent double sending or not sending to some users.

Usage:

```
Every::make()
    ->aim(new TgNotBannedAim())
    ->send(['text' => 'Hi'])
    ->notify();
```

### Letter

[](#letter)

Letter set the message value

Available builtin letters:

```
new TgFixedLetter(['text' => 'Hello Mmb!'])
new TgEmptyLetter()
new TgCustomLetter(new SerializableClosure(function () {...}))
```

Creating customize classes:

```
class TgWelcomeLetter implements TgLetter
{

    public function getLetter(Model $record) : array
    {
        return [
            'text' => "Welcome {$record->name}!",
        ];
    }

}
```

Usage:

```
Every::toAll()
    ->send()
    ->letter(new TgWelcomeLetter())
    ->notify();
```

### Notifier

[](#notifier)

Notifier set the sending method

Available builtin notifiers:

```
new TgMessageNotifier()
new TgForwardNotifier()
new TgCustomNotifier(new SerializableClosure(function () {...}))
```

Creating customize classes:

```
class TgHomeSectionNotifier implements TgNotifier
{

    public function notify(Model $record, array $message) : bool
    {
        return (bool) pov()
            ->user($record)
            ->catch()
            ->run(
                fn () => HomeSection::invokes('main')
            );
    }

}
```

Usage:

```
Every::toAll()
    ->notifier(new TgHomeSectionNotifier())
    ->notify();
```

###  Health Score

23

—

LowBetter than 27% of packages

Maintenance43

Moderate activity, may be stable

Popularity7

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity33

Early-stage or recently created project

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~25 days

Recently: every ~35 days

Total

7

Last Release

406d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/bbaf96477392e1adb53c957488c07eb48bdf9b2d75641b237a6d1becea4bc472?d=identicon)[MahdiSaremi](/maintainers/MahdiSaremi)

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/mmb-panelkit/health.svg)

```
[![Health](https://phpackages.com/badges/mmb-panelkit/health.svg)](https://phpackages.com/packages/mmb-panelkit)
```

###  Alternatives

[anourvalar/eloquent-serialize

Laravel Query Builder (Eloquent) serialization

11120.2M21](/packages/anourvalar-eloquent-serialize)[namu/wirechat

A Laravel Livewire messaging app for teams with private chats and group conversations.

54324.5k](/packages/namu-wirechat)[statamic-rad-pack/runway

Eloquently manage your database models in Statamic.

135192.6k5](/packages/statamic-rad-pack-runway)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
