ehsanmoradi/categorizable

Implementing Categories system for Laravel's Eloquent models.

2.1.0 2023-03-07 19:20 UTC

This package is auto-updated.

Last update: 2024-11-07 23:13:09 UTC


README

This Package enables you to Categorize your Eloquent Models. just use the trait in the model and you're good to go.

Requirements

  • PHP 7.2+
  • Laravel 8+

Installation

composer require ehsanmoradi/categorizable

Publish and Run the migrations

php artisan vendor:publish --provider="EhsanMoradi\Categorizable\CategorizableServiceProvider"

php artisan migrate

Laravel Categorizable package will be auto-discovered by Laravel. and if not: register the package in config/app.php providers array manually.

'providers' => [
	...
	\EhsanMoradi\Categorizable\CategorizableServiceProvider::class,
],

Setup models - just use the Trait in the Model.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use EhsanMoradi\Categorizable\Categorizable;

class Post extends Model
{
	use Categorizable;
}

Usage

first of all we need to create some Category to work with. Laravel Categorizable package relies on another package called laravel-nestedset that is responsible for creating, updating, removing and retrieving single or nested categories. Here i demonstrate how to create categories and assign one as the other's child.. but you can always refer to package's repository for full documentation. https://github.com/lazychaser/laravel-nestedset

use App\Post;
use EhsanMoradi\Categorizable\Category;

// first we create a bunch of categories

// create "BackEnd" category
Category::create([
	'name' => 'BackEnd'
]);

// create "PHP" category
Category::create([
	'name' => 'PHP'
]);

// create "FrontEnd" category
Category::create([
	'name' => 'FrontEnd'
]);

// create "Test" Category (alternative way)
$test = new Category();
$test->name = 'Test';
$test->save();


// assign "PHP" as a child of "BackEnd" category
$parent = Category::findByName('BackEnd');
$child = Category::findByName('PHP');
$parent->appendNode($child);

// delete "Test" Category
$testObj = Category::findByName('Test');
$testObj->delete();



//  assuming that we have these variables
$post = Post::first();

// 3 different ways of getting a category's instance
$backendCategory = Category::findById(1);	// 'BackEnd'
$phpCategory = Category::findByName('PHP');	// 'PHP'
$frontendCategory = Category::find(3);		// 'FrontEnd'

Attach the post to category

    $post->attachCategory($phpCategory);

Detach the post from a category

    $post->detachCategory($phpCategory); 

Attach the post to list of categories

    $post->syncCategories([
	    $phpCategory,
	    $backendCategory
	    ]); 

Detach the post from all categories

    $post->syncCategories([]); 

Sync the categories attached to a post

    $post->syncCategories([
	    $frontendCategory
	    ]); 

    // removes attached categories & adds the given categories

Check if post is attached to categories (boolean)

    // single use case
    $post->hasCategory($phpCategory);

    // multiple use case
    $post->hasCategory([
	    $phpCategory,
	    $backendCategory
	    ]);

    // return boolean

List of categories attached to the post (array)

    $post->categoriesList();

    // return array [id => name]

List of categories IDs attached to the post (array)

    $post->categoriesId();

    // return array

Get all posts attached to given category (collection)

    $categoryPosts = Category::find(1)
	    ->entries(Post::class)
	    ->get();

    // return collection

Relationships

categories() Relationship

    $postWithCategories = Post::with('categories')
	    ->get();

     // you have access to categories() relationship in case you need eager loading
    

parent Relationship

    $category = Post::first()->categories()->first();
    
    $category->parent;
    // return the category's parent if available

children Relationship

    $category = Post::first()->categories()->first();
    
    $category->children;
    // return the category's children if any

ancestors Relationship

    $category = Post::first()->categories()->first();
    
    $category->ancestors;
    // return the category's ancestors if any

descendants Relationship

    $category = Post::first()->categories()->first();
    
    $category->descendants;
    // return the category's descendants if any

Credits