PHP code example of architools / laravel-sieve

1. Go to this page and download the library: Download architools/laravel-sieve 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/ */

    

architools / laravel-sieve example snippets


namespace App\Utilities;

use ArchiTools\LaravelSieve\UtilitiesService;

class MyUtilitiesService extends UtilitiesService
{
}

namesapce App\Utilities;

use ArchiTools\LaravelSieve\UtilitiesService;
use ArchiTools\LaravelSieve\Criteria;
use ArchiTools\LaravelSieve\Filters\Conditions\Concretes\Condition;

class ProductUtilitiesService extends UtilitiesService
{
    public function filters(): array
    {
        return [
            'product_name' => 'productNameFilter',
        ];
    }

    public function productNameFilter(Criteria $criteria, mixed $value): void
    {
        $criteria->appendCondition(new Condition('products.name', 'like', "%$value%"));
    }
}

use ArchiTools\LaravelSieve\Filters\Joins\Concretes\Join;
use ArchiTools\LaravelSieve\Filters\Conditions\Concretes\Condition;

$criteria->appendJoin(
    new Join('product_categories', 'categories.id', '=', 'products.category_id')
);

$criteria->appendCondition(
    new Condition('product_categories.name', 'like', "%$value%")
);

use ArchiTools\LaravelSieve\Filters\Joins\Concretes\Join;
use ArchiTools\LaravelSieve\Filters\Conditions\Concretes\Condition;

$criteria->appendJoin(
    (new Join('product_categories', 'categories.id', '=', 'products.category_id'))
        ->appendCondition(new Condition('product_categories.is_active', '=', 1))
        ->appendCondition(...)
);

use ArchiTools\LaravelSieve\Filters\Joins\Concretes\Join;

if (!$criteria->joinExists('product_categories')) {
    $criteria->appendJoin(new Join('product_categories', 'categories.id', '=', 'products.category_id'));
}

namespace App\Utilities;

use ArchiTools\LaravelSieve\Filters\Joins\Concretes\Join;
use ArchiTools\LaravelSieve\Filters\Conditions\Concretes\{Condition, AggregationCondition};
use ArchiTools\LaravelSieve\UtilitiesService;
use ArchiTools\LaravelSieve\Criteria;

class MyUtilitiesService extends UtilitiesService
{
    public function filters(): array
    {
        return [
            'category_name' => 'categoryNameFilter',
            'has_multiple_categories' => 'multipleCategoriesFilter',
        ];
    }

    public function categoryNameFilter(Criteria $criteria, mixed $value)
    {
        if (!$criteria->joinExists('product_categories')) {
            $criteria->appendJoin(new Join('product_categories', 'categories.id', '=', 'products.category_id'));
        }

        $criteria->appendCondition(new Condition('product_categories.name', 'like', "%$value%"));
    }

    public function multipleCategoriesFilter(Criteria $criteria, mixed $value)
    {
        if (!$value) return;

        if (!$criteria->joinExists('product_categories')) {
            $criteria->appendJoin(new Join('product_categories', 'categories.id', '=', 'products.category_id'));
        }

        $criteria->appendCondition(new AggregationCondition('COUNT(product_categories.id)', '>', 1));
    }
}

namespace App\Utilities\Filters;

use ArchiTools\LaravelSieve\Filters\Contracts\Filter;
use ArchiTools\LaravelSieve\Criteria;
use ArchiTools\LaravelSieve\Filters\Joins\Concretes\Join;
use ArchiTools\LaravelSieve\Filters\Conditions\Concretes\Condition;

class ProductCategoryNameFilter implements Filter
{
    public function apply(Criteria $criteria, mixed $value)
    {
        if (!$criteria->joinExists('product_categories')) {
            $criteria->appendJoin(new Join('product_categories', 'categories.id', '=', 'products.category_id'));
        }
        $criteria->appendCondition(new Condition('product_categories.name', 'like', "%$value%"));
    }
}

namespace App\Utilities;

use ArchiTools\LaravelSieve\UtilitiesService;
use App\Utilities\Filters\ProductCategoryNameFilter;

class ProductUtilitiesService extends UtilitiesService
{
    public function filters(): array
    {
        return [
            'category_name' => new ProductCategoryNameFilter(),
        ];
    }
}

namespace App\Utilities;

use ArchiTools\LaravelSieve\UtilitiesService;
use App\Utilities\Filters\ProductCategoryNameFilter;

class DashboardUtilitiesService extends UtilitiesService
{
    public function filters(): array
    {
        return [
            'category' => new ProductCategoryNameFilter(),
        ];
    }
}

namespace App\Utilities;

use ArchiTools\LaravelSieve\UtilitiesService;
use ArchiTools\LaravelSieve\Sorts\Concretes\RawSort;
use ArchiTools\LaravelSieve\Sorts\Contracts\BaseSort;

class OrderUtilitiesService extends UtilitiesService
{
    public function sorts(): array
    {
        return [
            'name' => 'customNameSort',
            'created_at' => 'orders.created_at',
        ];
    }

    public function customNameSort(string $direction): BaseSort
    {
        return new RawSort('LENGTH(products.name)', $direction);
    }
}

namespace App\Utilities;

use ArchiTools\LaravelSieve\UtilitiesService;

class MyUtilitiesService extends UtilitiesService
{
    protected string $sortsKey = 'your_custom_sort_key';
    ...
}
l
use App\Utilities\ProductUtilitiesService;

class ProductController extends Controller
{
    public function index(Request $request, ProductUtilitiesService $utilitiesService)
    {
        $criteria = $utilitiesService
            ->applyFilters()
            ->applySorts()
            ->getCriteria();

        // Use the criteria in your repository or query builder
    }
}

use ArchiTools\LaravelSieve\Criteria;

class ProductRepository
{
    public function getProducts(Criteria $criteria)
    {
        $query = Product::query();
        $criteria->applyOnBuilder($query);

        return $query->get();
    }
}

use App\Utilities\Filters\ProductCategoryNameFilter;

protected function filters(): array
{
    return [
        'category_name' => new ProductCategoryNameFilter(),
        'date_range' => 'applyDateRangeFilter',
    ];
}

protected function sorts(): array
{
    return [
        'created_at' => 'created_at',
        'name' => 'users.name',
        'custom_sort' => 'applyCustomSort'
    ];
}

use ArchiTools\LaravelSieve\UtilitiesService;
use ArchiTools\LaravelSieve\Criteria;
use Illuminate\Http\Request;
use App\Utilities\Filters\{StatusFilter, RoleFilter};
use ArchiTools\LaravelSieve\Filters\Conditions\Concretes\Condition;

class UserService extends UtilitiesService
{
    protected string $defaultSortDirection = 'DESC';

    protected function filters(): array
    {
        return [
            'status' => new StatusFilter(),
            'role' => new RoleFilter(),
            'search' => 'applySearchFilter'
        ];
    }

    protected function sorts(): array
    {
        return [
            'name' => 'users.name',
            'email' => 'users.email',
            'created_at' => 'users.created_at'
        ];
    }

    protected function applySearchFilter(Criteria $criteria, string $value): void
    {
        $criteria->appendCondition(new Condition('name', 'like', "%{$value}%"));
    }
}

use ArchiTools\LaravelSieve\UtilitiesService;
use ArchiTools\LaravelSieve\Criteria;
use Illuminate\Http\Request;
use App\Utilities\Filters\{
    StatusFilter,
    CategoryFilter,
    TagsFilter};
use ArchiTools\LaravelSieve\Filters\Joins\Concretes\Join;
use ArchiTools\LaravelSieve\Filters\Conditions\Concretes\{
    Condition,
    BetweenCondition
};
use ArchiTools\LaravelSieve\Filters\Sorts\Concretes\RawSort;

class PostService extends UtilitiesService
{
    protected string $defaultSortDirection = 'DESC';
    protected string $sortsKey = 'order_by'; // Customize the sort parameter key

    protected function filters(): array
    {
        return [
            'status' => new StatusFilter,
            'category' => new CategoryFilter,
            'date_range' => 'applyDateRangeFilter',
            'author' => 'applyAuthorFilter',
            'tags' => new TagsFilter
        ];
    }

    protected function sorts(): array
    {
        return [
            'created_at' => 'posts.created_at',
            'title' => 'posts.title',
            'views' => 'applyViewsSort',
            'popularity' => 'applyPopularitySort'
        ];
    }

    protected function applyDateRangeFilter(Criteria $criteria, array $value): void
    {
        $criteria->appendCondition(new BetweenCondition(
            'created_at',
            [$value['start'], $value['end']]
        ));
    }

    protected function applyAuthorFilter(Criteria $criteria, int $authorId): void
    {
        $criteria->appendJoin(new Join('users', 'users.id', '=', 'posts.user_id', 'inner'));
        $criteria->appendCondition(new Condition('user_id', '=', $authorId));
    }

    protected function applyViewsSort(string $direction): BaseSort
    {
        return new RawSort('views_count + likes_count', $direction);
    }

    protected function applyPopularitySort(string $direction): BaseSort
    {
        return new RawSort('(views_count * ?) + (likes_count * ?)', $direction, [
            0.5, // Weight for views
            1.5  // Weight for likes
        ]););
    }
}

use ArchiTools\LaravelSieve\Criteria;
use ArchiTools\LaravelSieve\Joins\Concretes\Join;
use ArchiTools\LaravelSieve\Conditions\Concretes\{
    Condition,
    BetweenCondition,
    InCondition,
    GroupConditions
};
use ArchiTools\LaravelSieve\Sorts\Concretes\Sort;

$criteria = new Criteria();

// Add multiple joins with different priorities
$criteria->appendJoin(new Join('users', 'users.id', '=', 'posts.user_id', 'inner'), 100);
$criteria->appendJoin(new Join('categories', 'categories.id', '=', 'posts.category_id', 'left'), 200);

// Add complex conditions
$criteria->appendCondition(new Condition('status', '=', 'active'));
$criteria->appendCondition(new BetweenCondition('created_at', ['2023-01-01', '2023-12-31']));
$criteria->appendCondition(new InCondition('category_id', [1, 2, 3]));

// Add grouped conditions
$groupConditions = new GroupConditions([
    new Condition('views', '>', 1000),
    new Condition('likes', '>', 100, 'or')
]);
$criteria->appendCondition($groupConditions);

// Add multiple sorts
$criteria->appendSort(new Sort('created_at', 'DESC'));
$criteria->appendSort(new Sort('views', 'DESC'));

// Apply to a query builder
$query = DB::table('posts');
$query = $criteria->applyOnBuilder($query);

// The resulting query will be equivalent to:
// SELECT * FROM posts
// INNER JOIN users ON users.id = posts.user_id
// LEFT JOIN categories ON categories.id = posts.category_id
// WHERE status = 'active'
//   AND created_at BETWEEN '2023-01-01' AND '2023-12-31'
//   AND category_id IN (1, 2, 3)
//   AND (views > 1000 OR likes > 100)
// ORDER BY created_at DESC, views DESC

use ArchiTools\LaravelSieve\Filters\Conditions\Concretes\Condition;

// Simple equality check
$condition = new Condition('name', '=', 'John');

// Greater than comparison
$condition = new Condition('age', '>', 18);

// LIKE query
$condition = new Condition('email', 'like', '%@gmail.com');

// You can optionally set the boolean operator to either 'and' or 'or'; it defaults to 'and'.
$condition = new Condition('status', '=', 'active', 'or');


use ArchiTools\LaravelSieve\Filters\Conditions\Concretes\ColumnCondition;

// Compare two columns
$condition = new ColumnCondition('products.price', '>', 'categories.min_price');

// You can optionally set the boolean operator to either 'and' or 'or'; it defaults to 'and'.
$condition = new ColumnCondition('products.stock', '<', 'suppliers.min_stock', 'or');

use ArchiTools\LaravelSieve\Filters\Conditions\Concretes\JsonContainCondition;

// Check if tags array contains 'php'
$condition = new JsonContainCondition('tags', 'php');

// Check if preferences->languages contains 'en'
$condition = new JsonContainCondition('preferences->languages', 'en');

// Exclude users whose roles contain 'admin'
$condition = new JsonContainCondition('roles', 'admin', not: true);


use ArchiTools\LaravelSieve\Filters\Conditions\Concretes\JsonContainsKeyCondition;

// Check if preferences has 'notifications' key
$condition = new JsonContainsKeyCondition('preferences->notifications');

use ArchiTools\LaravelSieve\Filters\Conditions\Concretes\JsonLengthCondition;

// Check if tags array has more than 2 items
$condition = new JsonLengthCondition('tags', '>', 2);

// Check if preferences->languages has exactly 3 items
$condition = new JsonLengthCondition('preferences->languages', '=', 3);

// Exclude rows where 'settings' JSON object has an 'experimental' key
$condition = new JsonContainsKeyCondition('settings->experimental', not: true);


use ArchiTools\LaravelSieve\Filters\Conditions\Concretes\JsonOverlapCondition;

// Check if tags overlap with ['php', 'laravel']
$condition = new JsonOverlapCondition('tags', ['php', 'laravel']);

// Check if skills overlap with 


use ArchiTools\LaravelSieve\Filters\Conditions\Concretes\AggregationCondition;

// Filter products with more than 5 orders
$condition = new AggregationCondition('COUNT(id)', '>', 5);

// Filter categories with total sales over 1000
$condition = new AggregationCondition('SUM(price)', '>', 1000);

// Filter products with average rating above 4.5
$condition = new AggregationCondition('AVG(rating)', '>', 4.5);

use ArchiTools\LaravelSieve\Filters\Conditions\Concretes\GroupConditions;

// Basic group with AND
$group = new GroupConditions([
    new Condition('status', '=', 'active'),
    new Condition('age', '>', 18)
], 'and');

// Nested groups with mixed operators
$group = new GroupConditions([
    new GroupConditions([
        new Condition('status', '=', 'active'),
        new Condition('age', '>', 18)
    ], 'or'),
    new Condition('is_verified', '=', true)
], 'and');

// Complex real-world example with deeper nesting
$group = new GroupConditions([
    new GroupConditions([
        new Condition('country', '=', 'US'),
        new GroupConditions([
            new Condition('subscription_plan', '=', 'premium'),
            new Condition('last_login', '>=', now()->subDays(30)),
        ], 'or'),
    ], 'and'),
    new GroupConditions([
        new Condition('email_verified', '=', true),
        new Condition('phone_verified', '=', true, 'or')
    ], 'and'),
], 'and');

// previous group will generate a query like this:
where (
        ("country" = 'US' or ("subscription_plan" = 'premium' and "last_login" >= '2025-01-01'))
        and
        ("email_verified" = 1 or "phone_verified" = 1)
      );

use ArchiTools\LaravelSieve\Filters\Conditions\Concretes\BetweenCondition;

// Filter products with price between 10 and 100
$condition = new BetweenCondition('price', [10,100]);

// Filter users with age between 18 and 65
$condition = new BetweenCondition('age', [18, 65]);

// Exclude orders with total between 500 and 1000
$condition = new BetweenCondition('total', [500, 1000], not: true);

use ArchiTools\LaravelSieve\Filters\Conditions\Concretes\DateCondition;

// Filter records created after specific date
$condition = new DateCondition('created_at', '>', '2024-01-01');

// Filter records created on specific date
$condition = new DateCondition('created_at', '=', '2024-01-01');

use ArchiTools\LaravelSieve\Filters\Conditions\Concretes\InCondition;

// Filter users with specific statuses
$condition = new InCondition('status', ['active', 'pending']);

// Filter products in specific categories
$condition = new InCondition('category_id', [1, 2, 3]);

// Exclude users with roles 'admin' or 'moderator'
$condition = new InCondition('role', ['admin', 'moderator'], not: true);

use ArchiTools\LaravelSieve\Filters\Conditions\Concretes\NullCondition;

// Filter records where deleted_at is NULL
$condition = new NullCondition('deleted_at');

// Filter records where deleted_at is NOT NULL
$condition = new NullCondition('deleted_at', not: true);

use ArchiTools\LaravelSieve\Filters\Conditions\Concretes\RawCondition;

// Complex condition with parameters
$condition = new RawCondition('price > ? AND status = ?', [100, 'active']);

// Date comparison with functions
$condition = new RawCondition('DATE(created_at) = ?', ['2024-01-01']);

use ArchiTools\LaravelSieve\Filters\Conditions\Concretes\WhenCondition;

// Apply condition only for admin users
$condition = new WhenCondition($isAdmin, new Condition('role', '=', 'admin'));

// Apply condition based on feature flag
$condition = new WhenCondition($featureEnabled, new Condition('feature_id', '=', $featureId));

use ArchiTools\LaravelSieve\Filters\Joins\Concretes\Join;
use ArchiTools\LaravelSieve\Filters\Conditions\Concretes\Condition;

$join = (new Join('categories', 'products.category_id', '=', 'categories.id'))
   ->appendCondition(new Condition('categories.is_active', '=', true))
   ->appendCondition(new Condition('categories.type', '=', 'main'));

 $join->apply($queryBuilder);

use ArchiTools\LaravelSieve\Filters\Joins\Concretes\Join;
use ArchiTools\LaravelSieve\Filters\Conditions\Concretes\Condition;

// Basic join.
$join = new Join(
    'categories',
    'products.category_id',
    '=',
    'categories.id'
);

// Join with additional conditions.
$join = (new Join(
    'categories',
    'products.category_id',
    '=',
    'categories.id',
    'left'
))->appendCondition(
    new Condition('categories.is_active', '=', true)
);

// Join with custom name.
$join = new Join(
    'categories',
    'products.category_id',
    '=',
    'categories.id',
    'inner',
    'product_categories'
);

// Chaining multiple conditions.
$join = (new Join('categories', 'products.category_id', '=', 'categories.id'))
    ->appendCondition(new Condition('categories.is_active', '=', true))
    ->appendCondition(new Condition('categories.type', '=', 'main'))
    ->appendCondition(new Condition('categories.created_at', '>', '2024-01-01'));

$join->apply($queryBuilder);

use ArchiTools\LaravelSieve\Filters\Joins\Concretes\ClosureJoin;

// Complex join with multiple conditions
$join = new ClosureJoin(
    'orders',
    function ($query) {
        $query->on('users.id', '=', 'orders.user_id')
              ->where('orders.status', '=', 'completed')
              ->where('orders.created_at', '>', now()->subDays(30));
    },
    'left'
);

// Join with custom name and type
$join = new ClosureJoin(
    'user_preferences',
    function ($query) {
        $query->on('users.id', '=', 'user_preferences.user_id')
              ->where('user_preferences.is_active', '=', true);
    },
    'left',
    'active_preferences'
);

// Complex join with multiple conditions and subqueries
$join = new ClosureJoin(
    'order_summary',
    function ($query) {
        $query->on('users.id', '=', 'order_summary.user_id')
              ->where('order_summary.total_orders', '>', function ($subquery) {
                  $subquery->selectRaw('AVG(total_orders)')
                          ->from('order_summary');
              })
              ->whereExists(function ($subquery) {
                  $subquery->select('id')
                          ->from('recent_orders')
                          ->whereColumn('user_id', 'users.id')
                          ->where('created_at', '>', now()->subDays(7));
              });
    }
);

$sort->apply($queryBuilder);

use ArchiTools\LaravelSieve\Sorts\Concretes\Sort;

// Sort by name in ascending order
$sort = new Sort('name', 'ASC');

// Sort by created_at in descending order
$sort = new Sort('created_at', 'desc');

// Sort by multiple fields
$sorts = [
    new Sort('status', 'asc'),
    new Sort('created_at', 'desc')
];

$sort->apply($queryBuilder);

use ArchiTools\LaravelSieve\Sorts\Concretes\RawSort;

// Sort by a calculated field
$sort = new RawSort('(price * quantity)', 'DESC');

// Sort using a SQL function
$sort = new RawSort('LENGTH(name)', 'ASC');

// Sort with bindings
$sort = new RawSort('FIELD(status, ?, ?, ?)', 'ASC', ['active', 'pending', 'inactive']);

// Complex sorting with bindings
$sort = new RawSort('
    CASE 
        WHEN status = ? THEN 1
        WHEN status = ? THEN 2
        ELSE 3
    END', 'ASC', ['active', 'pending']);