PHP code example of atannex / scopable

1. Go to this page and download the library: Download atannex/scopable library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

atannex / scopable example snippets


Post::published()->featured()->createdThisWeek()->ordered()->get();
$post->inState('scheduled');                    // no query
$post->enterState('breaking', until: now()->addHours(6));

use Atannex\Scopable\Concerns\HasScopes;
use Atannex\Scopable\Rules\Rule;
use Atannex\Scopable\Scopes;

class Post extends Model
{
    use HasScopes;

    public static function defineScopes(Scopes $scopes): void
    {
        // published_at: published (set, passed) / scheduled (set, ahead) / draft (null)
        // / unpublished (scheduled or draft), plus publishedToday(), publishedWithin()…
        $scopes->published();

        // A boolean column: is_featured. ->featured(), ->notFeatured(), ->featured(false)
        $scopes->toggle('featured');

        // A flag that only counts inside its window.
        $scopes->highlight('breaking', 'is_breaking', 'breaking_at', 'breaking_expires')->tracked();

        // Anything, from the rules below, including other states.
        $scopes->state('spotlight', Rule::all(
            Rule::state('published'),
            Rule::any(Rule::state('featured'), Rule::state('breaking')),
        ));

        $scopes->filter('flagged', 'flag');            // ->flagged(Flag::PUBLISHED)
        $scopes->sortable('order', then: ['created_at' => 'desc']);
    }
}

trait IsModerated
{
    use HasScopes;

    public static function defineScopesIsModerated(Scopes $scopes): void
    {
        $scopes->equals('approved', 'status', Status::Approved, otherwise: Status::Pending);
        $scopes->equals('pending', 'status', Status::Pending);
    }
}

->inverse('inactive')    // more names for the opposite
->alias('live')          // more names for the state
->label('Breaking news') // for the Filament filter and scopable:show
->byDefault()            // apply to every query
->tracked()              // fire StateEntered / StateLeft

Post::published()->get();
Post::published(now()->addDay());                 // as of a moment
Post::featured(false);                            // same as ->notFeatured()
Post::whereState(['published', 'featured']);
Post::whereNotState('breaking');
Post::whereAnyState(['breaking', 'featured']);
Post::published()->orWhereState('scheduled');
Comment::countStates(['pending', 'approved', 'spam']);   // ['pending' => 3, …] in ONE query
$category->posts()->published()->latest('published_at');
Category::whereHas('posts', fn ($q) => $q->breaking());

$post->inState('published');                 // from loaded attributes, no query
$post->inState('published', $tomorrow);
$post->stateMap();                           // ['published' => true, 'scheduled' => false, …]

$post->enterState('published');              // keeps an earlier publish date
$post->scheduleState('published', $friday);
$post->leaveState('published');              // clears published_at
$post->enterState('breaking', until: now()->addHours(6));
$post->leaveState('breaking');               // flag off, dates kept for the record
$post->setState('featured')->setState('published')->save();  // set without saving

$scopes->published()->byDefault();

Note::all();                                      // published only
Note::withoutStateDefaults()->get();              // everything
Note::withoutStateDefaults('published')->draft(); // lift one default

Schedule::command('scopable:sweep')->everyMinute()->withoutOverlapping()->onOneServer();

use Atannex\Scopable\Filament\{PeriodFilter, PeriodSelectFilter, PeriodTab, StateFilter, StateTab};

->filters([
    StateFilter::make('breaking'),                                      // yes / no / any
    PeriodFilter::make('published_at', __('Published')),                 // from / until, whole days
    PeriodFilter::window('starts_at', 'ends_at', __('Running')),         // windows overlapping the dates
    PeriodSelectFilter::make('created_at', ['today' => __('Today'), 'within 1 week' => __('This week')]),
])

public function getTabs(): array
{
    $counts = Comment::countStates(['pending', 'approved', 'spam', 'rejected']);

    return [
        'pending' => StateTab::make(Comment::class, 'pending', __('Pending'), count: $counts['pending'] ?: null),
        'rejected' => StateTab::make(Comment::class, ['spam', 'rejected'], __('Spam & rejected'), any: true),
        'today' => PeriodTab::make(Click::class, 'created', 'today', __('Today'), count: true),
        'week' => PeriodTab::make(EngagementDay::class, 'day', Period::lastDays(7)),
    ];
}
bash
php artisan scopable:show Post --sql    # states, inverses, rules, SQL, dates, filters, sorts
php artisan scopable:sweep