درود دوستان
من پس از بارها پیاده سازی فیچِر دسته بندیها در پروژه های مختلف، به این نتیجه رسیدم که سورس کد این فیچر را به یک پکیج لاراولی تبدیل کنم.
بنده اخیرا پکیجی به نام Laravel Categorizable منتشر کردم. این پکیج کاملا با نسخه ۶ لاراول سازگار است و با بهره گیری از روابط چندریختی (Polymorphism) این امکان را به ما میدهد که: هر مدلی که خواستیم را دسته بندی کنیم. به عبارت دیگر در یک اپلیکیشن لاراولی میتوانیم پستها، محصولات، ویدیوها و هر تعداد مدل دیگر که نیاز داریم را براحتی دسته بندی کنیم; با این پکیج همچنین ساخت، به روزرسانی و حذف دسته بندیها به راحتی قابل انجام است.
composer require alibayat/laravel-categorizable
php artisan vendor:publish --provider="AliBayat\LaravelCategorizable\CategorizableServiceProvider"
php artisan migrate
تنها کافیست از تریت پکیح در مدل مورد نظر استفاده کنیم:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use AliBayat\LaravelCategorizable\Categorizable;
class Post extends Model
{
use Categorizable;
}
به همین سادگی ما قابلیت دستهبندی شدن رو به مدل Post اضافه کردیم. با این کار یک سری متد ها که مربوط به این فیچر هستند به مدل ما اضافه میشه
برای نمایش متدها، نیاز به ساخت چند دستهبندی داریم. در زیر نحوه ساخت و حذف دستهبندی ها را به علاوه ساخت دستهبندی ها به حالت والد و فرزند (دستهبندی های تو در تو (Nested)) مرور میکنیم:
<?php
use AliBayat\LaravelCategorizable\Category;
// 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();
حال که دستهبندی ها را ساختیم، چند متغیر را مقداردهی میکنیم و سپس عملکرد متد ها را بررسی میکنیم:
<?php
use App\Post;
use AliBayat\LaravelCategorizable\Category;
$post = Post::first();
// ۳ different ways of getting a category's instance
$backendCategory = Category::findById(۱); // 'BackEnd'
$phpCategory = Category::findByName('PHP'); // 'PHP'
$frontendCategory = Category::find(۳); // 'FrontEnd'
حال برای...
$post->attachCategory($phpCategory);
$post->detachCategory($phpCategory);
$post->syncCategories([
$phpCategory,
$backendCategory
]);
$post->syncCategories([]);
$post->hasCategory($phpCategory);
$post->hasCategory([
$phpCategory,
$backendCategory
]);
// return boolean
$post->categoriesList();
// return array [id => name]
$categoryPosts = Category::find(۱)
->entries(Post::class)
->get();
// return collection
مستندات پکیج در ریپازیتوری گیتهاب موجود است:
https://github.com/AliBayat/Laravel-Categorizable
در صورت پیدا کردن هر گونه باگ میتونید در قسمت Issues گیت و یا در این گفتگو اون رو عنوان کنید.
در اکثر اپلیکیشن های تحت وب دستهبندی ها (Categories) نقش مهمی ایفا میکنند. در یک بلاگ ساده، یک فروشگاه اینترنتی، یک سیستم آموزشی و حتی سامانههای شخصی سازی شده و غیره مفهوم دسته بندی همیشه حظور دارد; مثلا در یک بلاگ، پستها میتوانند در دسته بندی های خاص خود باشند و همین طور محصولات یک فروشگاه، مقالات آموزشی یک موسسه و ...
میشه گفت عدم اختراع دوباره چرخ، یکی از دلایلش هست
@ali.bayat
آیا امکان پیاده سازی دسته بندی ها به صورت زیر دسته (به صورت نامحدود) امکان پذیر هستش ؟
خوبه برای هر دسته بندی امکان قرار دادن یک آیکن و یک تصویر رو هم قرار بدید. در کل پکیج شما عالیه و متد هایی که براش نوشتین هم کافیه تا حد زیادی
@mrerfan.ir
درود
بله ممکنه. و همچنین دریافت ساختار دستهبندی ها به شکل درختی و به شکل Flat هم ممکنه.
درود و سپاس از لطف شما. خوشحال میشم که این پکیج توسط جامعه توسعه دهندگان ایرانی مورد استفاده قرار بگیره.
چقدر عالی. همیشه به این فکر میکردم که باید این پکیج رو یه بار برای همیشه بنویسم ولی وقت نمیشد و همیشه توی هر پروژه به صورت بزن در رویی کد میزدم و کارم رو راه مینداختم. خیلی کار خوبی کردید. حتما توی پروژه بعدی استفاده می کنم ازش
درود و سپاس
دقیقا.. من به دفعات خودم این کار رو انجام داده ام.. تا اینکه این پکیج رو در قالب یه ریپازیتوری private منتشر کردم.
به لطف Github عزیز که امکان استفاده از ریپازیتوری های private رو برای ایران و ۳ کشور دیگه محدود کرد، این پکیج هم به نوع Public تبدیل شد.
@ali.bayat اسم جداولت رو در پکیج هات با یه پرفیکس بزار تا اگه کسی تو پروژش مثل من به هر دلیلی یه جدول categories دیگه داشت با این به مشکل نخوره مثلا بزار bayat_categories
@hshafiei374
درسته اسم جدولها ممکنه تداخل داشته باشند.. در آپدیت بعدی یه فکری به حالش میکنم.
اما تا اون موقع برای استفاده از پکیج میتونید بعد از نصب با کامپوزر و پابلیش کردن فایلها...
قبل از مایگریت کردن.. فایل مایگریت رو باز کنید
و اسم جدول اول رو تغییر بدید.
بعدش مایگریت کنید
تنها کاری که میمونه اینه که فایل "vendor\alibayat\laravel-categorizable\src\Category.php" رو باز کنید و اسم پیشفرض جدول رو عوض کنید:
class Category extends Model
{
protected $table = 'newTableName';
}
برای نسخه بعد، یه سری قابلیت های دیگه در نظر گرفتم.. در کنارشون اسم جدول رو هم درست میکنم.
سپاس از اطلاعرسانی شما
@ali.bayat
سلام جناب بیات ، خسته نباشید .
سوالی پیش آمده برام .
اینکه چطور میشه دسته ای ساخت که والدش دسته دیگه ای باشه تو متد ها فقط یدونه name گزاشتید خبری از parent نبود البته هنوز پکیجو نصب و مایگریت نکردم ؟
چطور میشه دسته بندی هارو به حالت درختی یا dropdown نمایش داد؟ اگه کد آماده ای هست مثلا برای نمایش تو صفحه اصلی اینجا منتشر کنید تا استفاده کنیم .
تشکر
درود
ساخت دسته بندیهای والد و فرزند در بالا هم عنوان شده. ابتدا دستهبندی هاتون رو بسازید و سپس با متد findByName به شکل زیر پیداشون کنید:
$parent = Category::findByName('BackEnd');
$child = Category::findByName('PHP');
و در نهایت با متد apendNode ... یکی رو به عنوان والد دیگری ثبت کنید:
$parent->appendNode($child);
با متدهای زیر هم میتونید روابط والد و فرزند رو بررسی کنید:
$category->isChildOf($otherCategory);
$category->isAncestorOf($otherCategory);
$category->isSiblingOf($otherCategory);
و برای دریافت دسته بندی های والد و فرزند هم به ۴ نوع رابطه بین جداول دسترسی دارید که به شرح زیر هست
براحتی میتونید از این روابط استفاده کنید
Category::findByName('php')->parent;
و یا حتی میتونید داده ها رو Eager load کنید:
Category::with('ancestors')->get()
همچنین یه سری اِسکوپ هم برای این روابط وجود داره
$backEnd = Category::findByName('Backend');
Category::descendantsOf($backEnd);
آیا مایل به ارسال نوتیفیکیشن و اخبار از طرف راکت هستید ؟