PHPackages                             wsmallnews/support - 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. wsmallnews/support

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

wsmallnews/support
==================

Wsmallnews system support modules

v1.0.9(today)136[1 PRs](https://github.com/Wsmallnews/support/pulls)5MITPHPPHP ^8.2CI failing

Since Nov 24Pushed 4d ago1 watchersCompare

[ Source](https://github.com/Wsmallnews/support)[ Packagist](https://packagist.org/packages/wsmallnews/support)[ Docs](https://github.com/wsmallnews/support)[ GitHub Sponsors](https://github.com/Wsmallnews)[ RSS](/packages/wsmallnews-support/feed)WikiDiscussions v1 Synced today

READMEChangelog (9)Dependencies (138)Versions (14)Used By (5)

Wsmallnews System Base Support Package
======================================

[](#wsmallnews-system-base-support-package)

[![Latest Version on Packagist](https://camo.githubusercontent.com/a1a64c62bf219a0aae65176056caecf93c0b496fc974648d74c777bf7ff45678/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f77736d616c6c6e6577732f737570706f72742e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/wsmallnews/support)[![GitHub Tests Action Status](https://camo.githubusercontent.com/df23c76833557d432f604abe6581ec745d080686e8e32ef02ea3070c1aeec736/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f77736d616c6c6e6577732f737570706f72742f72756e2d74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/wsmallnews/support/actions?query=workflow%3Arun-tests+branch%3Amain)[![GitHub Code Style Action Status](https://camo.githubusercontent.com/f2708dbe58d524172ce40a23c7a045e818d4238d941780103946b28ab2386dca/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f77736d616c6c6e6577732f737570706f72742f6669782d7068702d636f64652d7374796c652d6973737565732e796d6c3f6272616e63683d6d61696e266c6162656c3d636f64652532307374796c65267374796c653d666c61742d737175617265)](https://github.com/wsmallnews/support/actions?query=workflow%3A%22Fix+PHP+code+style+issues%22+branch%3Amain)[![Total Downloads](https://camo.githubusercontent.com/91bf2440a8cca70d387f976a45c9787139543a8d6da27614d9e58b0ce5140cce/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f77736d616c6c6e6577732f737570706f72742e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/wsmallnews/support)

Wsmallnews System Base Support Package. Provides common models, form components, Livewire traits, plugin capabilities, enum types and other underlying capabilities for other packages.

Features
--------

[](#features)

### Base Model Layer

[](#base-model-layer)

- **SupportModel**: Base class for all package models, with built-in `Scopeable` trait, automatically supports multi-scope isolation and multi-tenancy
- **Scopeable Trait**: Provides `scopeType()`, `scopeId()`, `scopeable()`, `snScope()` query scopes for models
- **Content Model**: Generic polymorphic content storage model, supports three content types: text, rich text, and Markdown

### Filament Form Components

[](#filament-form-components)

| Component | Description | | `FormComponents` | Form component factory, provides unified methods for creating file upload and editor components |

### Livewire Traits

[](#livewire-traits)

TraitDescription`HasProperties`Generic property management, provides `getProperty()` / `setProperty()` methods`HasContentType`Content type management, supports Textarea / Richtext / Markdown`HasAuth`Auth user management, `getAuthUser()` / `hasAuthUser()``CanPagination`Enhanced pagination, supports scroll loading, paginator, and manual modes`CanBeContained`Whether the component has an outer container`Scopeable`Component-level scope management for Livewire### Plugin / Resource Traits

[](#plugin--resource-traits)

> Extension of bezhansalleh/filament-plugin-essentials, providing custom property management functionality

TraitDescription`HasCustomProperties` (Plugin)Plugin-level custom property management, supports multiple Resource contexts`HasCustomProperties` (Resource)Resource-level custom property reading, supports `getCustomProperty()` shortcut method### Eloquent Casts

[](#eloquent-casts)

CastDescription`CounterCast`JSON counter field transformation, supports direct access like `->like_num`, `->view_num``MoneyCast`Currency amount conversion, based on `moneyphp/money``ImplodeCast`Array field concatenation transformation### Other Features

[](#other-features)

- **Enums**: `ContentType` (textarea / richtext / markdown), `ActivityLogEvent`
- **Sms**: SMS sending functionality, based on `overtrue/easy-sms`
- **Tenant Settings**: Multi-tenant configuration storage, database Settings Repository
- **Observers**: Activity log observer, MediaLibrary observer
- **Middleware**: Multi-tenant identification middleware `IdentifyTenant`

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

[](#installation)

You can install the package via composer:

```
composer require wsmallnews/support:^1.0
```

Installing this package will publish the configuration files and migration files of both the third-party dependency package and the current package:

```
php artisan sn-support:install
```

You can publish only the config file individually:

```
php artisan vendor:publish --tag="sn-support-config"
```

Publish and run only the migrations individually:

```
php artisan vendor:publish --tag="sn-support-migrations"
php artisan migrate
```

Multi language support, you can publish the language files using:

```
php artisan vendor:publish --tag="sn-support-translations"
```

Publish the views (optional):

```
php artisan vendor:publish --tag="sn-support-views"
```

This is the contents of the published config file `config/sn-support.php`:

```
use Wsmallnews\Support\Models;

return [
    /*
    |--------------------------------------------------------------------------
    | Filesystem Disk
    |--------------------------------------------------------------------------
    |
    | This is a storage disk used for store files. By default, The storage disk set by filament will be used
    | You can use any disk defined in `config/firesystems.php`.
    |
    */
    'filesystem_disk' => null,

    /**
     * Custom models
     */
    'models' => [
        'content' => Models\Content::class,
        'sms_log' => Models\SmsLog::class,
    ],

    /*
    |--------------------------------------------------------------------------
    | Multi-Tenancy
    |--------------------------------------------------------------------------
    |
    | Firstly, the panel where the current plugin is located should support multi tenancy before you can set this option.
    | Secondly, The tenant model should be set as a panel model.
    |
    */
    'tenant_model' => null,

    /*
    |--------------------------------------------------------------------------
    | Filament Form Components
    |--------------------------------------------------------------------------
    |
    | Unified management of default configurations for Filament form components
    |
    */
    'form_components' => [
        /**
         * Upload component default configuration
         */
        'upload' => [
            /**
             * Visibility
             */
            'visibility' => 'public',
            /**
             * Downloadable
             */
            'downloadable' => true,
            /**
             * Openable
             */
            'openable' => true,
            /**
             * Reorderable (valid for multi-file upload)
             */
            'reorderable' => true,
            /**
             * Append files mode (valid for multi-file upload)
             */
            'append_files' => true,
            /**
             * Maximum number of files (valid for multi-file upload)
             */
            'max_files' => 10,
            /**
             * Maximum file size, default 120MB
             */
            'max_size' => 122880,
            /**
             * Image preview height, default 200px
             */
            'image_preview_height' => '200',
        ],

        'editor' => [
            /**
             * Maximum content length, default null (unlimited)
             */
            'max_length' => null,
            /**
             * File upload configuration
             */
            'file_attachment' => [
                /**
                 * Visibility (richtext only)
                 */
                'visibility' => 'public',
                /**
                 * Maximum file size, default 120MB
                 */
                'max_size' => 122880,
            ],
            /**
             * Markdown editor configuration
             */
            'markdown' => [
                /**
                 * Toolbar buttons
                 */
                'toolbar_buttons' => [
                    ['bold', 'italic', 'strike', 'link'],
                    ['heading'],
                    ['blockquote', 'codeBlock', 'bulletList', 'orderedList'],
                    ['table', 'attachFiles'],
                    ['undo', 'redo'],
                ],
            ],
            /**
             * Rich text editor configuration
             */
            'richtext' => [
                /**
                 * Toolbar buttons
                 */
                'toolbar_buttons' => [
                    ['bold', 'italic', 'underline', 'strike', 'subscript', 'superscript', 'link', 'textColor'],
                    ['h2', 'h3'],
                    ['alignStart', 'alignCenter', 'alignEnd'],
                    ['blockquote', 'codeBlock', 'bulletList', 'orderedList'],
                    ['table', 'attachFiles'],
                    ['undo', 'redo'],
                ],
                /**
                 * Floating toolbar buttons
                 */
                'floating_toolbars' => [
                    'paragraph' => [
                        'bold', 'italic', 'underline', 'strike', 'subscript', 'superscript',
                    ],
                    'heading' => [
                        'h1', 'h2', 'h3',
                    ],
                    'table' => [
                        'tableAddColumnBefore', 'tableAddColumnAfter', 'tableDeleteColumn',
                        'tableAddRowBefore', 'tableAddRowAfter', 'tableDeleteRow',
                        'tableMergeCells', 'tableSplitCell',
                        'tableToggleHeaderRow', 'tableToggleHeaderCell',
                        'tableDelete',
                    ],
                ],
                /**
                 * Text color list, effective when textColor is included in toolbar
                 */
                'text_colors' => null,
            ],
        ],
    ],
];
```

Usage
-----

[](#usage)

### SupportModel Base Model

[](#supportmodel-base-model)

All package models should extend `SupportModel` to automatically get multi-scope and multi-tenancy capabilities:

```
use Wsmallnews\Support\Models\SupportModel;

class YourModel extends SupportModel
{
    protected $table = 'your_table';
}
```

Automatically available query scopes:

```
// Scope query
YourModel::scopeable('blog', 1)->get();

// Combined query (scope + tenant), will automatically get current tenant ID
YourModel::snScope('blog', 1)->get();

// Get scope information for current record
$model->getScopeType();  // 'blog'
$model->getScopeId();    // 1
$model->getScopeable();  // ['scope_type' => 'blog', 'scope_id' => 1]
```

### HasProperties Trait

[](#hasproperties-trait)

Use property management in Livewire components:

```
use Wsmallnews\Support\Livewire\Concerns\HasProperties;

class YourComponent extends Component
{
    use HasProperties;

    public function mount(): void
    {
        $this->setProperties([
            'emptyLabel' => 'No data',
            'pageSize' => 20,
        ]);
    }

    public function getEmptyLabel(): ?string
    {
        return $this->getProperty('emptyLabel', 'Default empty text');
    }
}
```

### HasCustomProperties (Plugin)

[](#hascustomproperties-plugin)

Use custom properties in Plugin:

```
use Wsmallnews\Support\Concerns\Plugin\HasCustomProperties;

class YourPlugin implements Plugin
{
    use HasCustomProperties;

    public function register(Panel $panel): void
    {
        // Set custom properties during Panel registration
    }
}

// Usage
YourPlugin::make()
    ->customProperties([
        'pageSize' => 20,
        'enableSearch' => true,
    ]);
```

### HasCustomProperties (Resource)

[](#hascustomproperties-resource)

Read custom properties in Resource/Page:

```
use Wsmallnews\Support\Concerns\Resource\HasCustomProperties;

class YourPage extends Page
{
    use HasCustomProperties;

    public function getPageSize(): int
    {
        return static::getCustomProperty('pageSize', 10);
    }
}
```

### Form Components Factory

[](#form-components-factory)

Quickly create configured form components using `FormComponents`:

```
use Wsmallnews\Support\Filament\Forms\FormComponents;

// Media library image upload (Spatie Media Library)
FormComponents::mediaImageUpload('avatar', 'avatars');

// Media library file upload
FormComponents::mediaFileUpload('attachment', 'files');

// Local image upload
FormComponents::localImageUpload('cover');

// Local file upload
FormComponents::localFileUpload('document');

// Markdown editor
FormComponents::markdownEditor('content');

// Rich text editor
FormComponents::richEditor('description');
```

Components will automatically apply default configurations from `sn-support.php`.

### CounterCast

[](#countercast)

```
use Wsmallnews\Support\Casts\CounterCast;

class Post extends SupportModel
{
    protected $casts = [
        'counter' => CounterCast::class,
    ];
}

// Usage
$post->counter->like_num;    // 0
$post->counter->view_num;    // 0
$post->counter->share_num;   // 0 (non-existent key defaults to 0)

// Update counter
$post->incrementJson('counter->like_num');
$post->decrementJson('counter->view_num');
```

### CanPagination

[](#canpagination)

```
use Wsmallnews\Support\Livewire\Concerns\CanPagination;

class CommentList extends Component
{
    use CanPagination;

    public string $pageType = 'scroll';     // scroll / paginator / manual
    public string $pageName = 'page';
    public int $perPage = 10;

    public function loadComments()
    {
        $query = Comment::query();
        $this->comments = $this->withPagination($query);
        // $this->pageInfo contains pagination status
        // $this->links contains pagination link HTML
    }

    public function render()
    {
        return view('comment-list', [
            'paginatorLink' => $this->links,        // paginator HTML when using paginator mode
        ]);
    }
}
```

### Multi-Tenancy Support

[](#multi-tenancy-support)

If your panel uses multi-tenancy, you should set the tenant model.

```
return [
    /*
    |--------------------------------------------------------------------------
    | Multi-Tenancy
    |--------------------------------------------------------------------------
    |
    | Firstly, the panel where the current plugin is located should support multi tenancy before you can set this option.
    | Secondly, The tenant model should be set as a panel model.
    |
    */
    'tenant_model' => \App\Models\Team::class,
]
```

#### laravel-settings Multi-Tenancy Support

[](#laravel-settings-multi-tenancy-support)

Publish the laravel-settings config file:

```
php artisan vendor:publish --provider="Spatie\LaravelSettings\LaravelSettingsServiceProvider" --tag="config"
```

Add the `team_database` configuration in `settings.php`, specifying the `sn_team_settings` table:

```
return [
    /*
     * Settings will be stored and loaded from these repositories.
     */
    'repositories' => [
        'database' => [
            // ...
        ],
        'team_database' => [
            'type' => Wsmallnews\Support\Tenant\Settings\Repositories\DatabaseSettingsRepository::class,
            'model' => null,
            'table' => 'sn_team_settings',
            'connection' => null,
        ],
        // ...
    ],
]
```

The event listener will be automatically registered in the `boot` method of `SupportServiceProvider`, which initializes tenant settings in the database.

#### laravel-activitylog Multi-Tenancy Support

[](#laravel-activitylog-multi-tenancy-support)

Publish the laravel-activitylog config file:

```
php artisan vendor:publish --provider="Spatie\Activitylog\ActivitylogServiceProvider" --tag="activitylog-config"
```

Set the `activity_model` to `\Wsmallnews\Support\Models\Activity`:

```
return [
    // ...

    /*
     * This model will be used to log activity.
     * It should implement the Spatie\Activitylog\Contracts\Activity interface
     * and extend Illuminate\Database\Eloquent\Model.
     */
    'activity_model' => \Wsmallnews\Support\Models\Activity::class,
]
```

### media-library

[](#media-library)

Publish the laravel-medialibrary config file:

```
php artisan vendor:publish --provider="Spatie\MediaLibrary\MediaLibraryServiceProvider" --tag="medialibrary-config"
```

Change the media observer to `\Wsmallnews\Support\Tenant\MediaLibrary\Observers\MediaObserver` in media-library, otherwise files in the filesystem will be deleted when media is deleted.

```
return [
    /*
     * The fully qualified class name of the media observer.
     */
    'media_observer' => \Wsmallnews\Support\Tenant\MediaLibrary\Observers\MediaObserver::class,
]
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](.github/CONTRIBUTING.md) for details.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](../../security/policy) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- [smallnews](https://github.com/Wsmallnews)
- [bezhansalleh/filament-plugin-essentials](https://github.com/bezhansalleh/filament-plugin-essentials)
- [filament/filament](https://github.com/filamentphp/filament)
- [overtrue/easy-sms](https://github.com/overtrue/easy-sms)
- [ralphjsmit/livewire-urls](https://github.com/ralphjsmit/livewire-urls)
- [spatie/laravel-activitylog](https://github.com/spatie/laravel-activitylog)
- [spatie/laravel-markdown](https://github.com/spatie/laravel-markdown)
- [spatie/laravel-medialibrary](https://github.com/spatie/laravel-medialibrary)
- [spatie/laravel-settings](https://github.com/spatie/laravel-settings)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

47

—

FairBetter than 93% of packages

Maintenance98

Actively maintained with recent releases

Popularity11

Limited adoption so far

Community21

Small or concentrated contributor base

Maturity55

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 95.5% of commits — single point of failure

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 ~22 days

Recently: every ~14 days

Total

11

Last Release

0d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/16216215?v=4)[小新](/maintainers/Wsmallnews)[@Wsmallnews](https://github.com/Wsmallnews)

---

Top Contributors

[![Wsmallnews](https://avatars.githubusercontent.com/u/16216215?v=4)](https://github.com/Wsmallnews "Wsmallnews (256 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (8 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (4 commits)")

---

Tags

laravelsupportWsmallnews

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/wsmallnews-support/health.svg)

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

###  Alternatives

[stephenjude/filament-feature-flags

Filament implementation of feature flags and segmentation with Laravel Pennant.

122177.8k1](/packages/stephenjude-filament-feature-flags)[ysfkaya/filament-phone-input

A phone input component for Laravel Filament

3161.3M25](/packages/ysfkaya-filament-phone-input)[finity-labs/fin-mail

A powerful email template manager and composer for Filament with dynamic token replacement, template versioning, and inline email sending.

284.5k1](/packages/finity-labs-fin-mail)[rawilk/profile-filament-plugin

Profile &amp; MFA starter kit for filament.

3914.6k](/packages/rawilk-profile-filament-plugin)[stephenjude/filament-blog

Filament Blog Builder

20619.4k](/packages/stephenjude-filament-blog)[marcelweidum/filament-expiration-notice

Customize the livewire expiration notice

94135.4k5](/packages/marcelweidum-filament-expiration-notice)

PHPackages © 2026

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