mmb/panelkit

There is no license information available for the latest version (v0.1.4-beta) of this package.

Panel kit for mmb

v0.1.4-beta 2024-12-30 17:25 UTC

This package is auto-updated.

Last update: 2025-04-08 05:13:00 UTC


README

Installation

composer require mmb/panelkit

Publish

Optionally, you can publish the assets:

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

Every

Every is a service to notify the users by a message

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

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 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 system used to protect contents by favorite lock methods like forcing channel joining

Ready To Use

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

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

Change the config:

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

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

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 is a collection of tools to customize the actions

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 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 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();