منبع اصلی نوشتار زیر در این لینک قرار دارد

ایجاد slug با قابلیت پشتیبانی از زبان فارسی در لاراول

برای داشتن urlهای تمیز و  SEO Friendly در برنامه‌های تحت وب راههای زیادی وجود داره. در لاراول به صورت پیشفرض می‌تونید به روش زیر slug یا نامک از رشته‌هاتون درست کنید:

$title = "sample title";
$slug = Str::slug($title); //output: sample-slug

کار خیلی راحتیه ولی هر سری که بخواهیم یک رکورد رو آپدیت یا ایجاد کنیم مجبوریم از این روش استفاده کنیم، ولی خب لاراول یه سری رویداد داره که میتونیم به صورت اتوماتیک این فیلد رو پر کنیم و نگران چیز دیگه‌ای نباشیم. از اون راحت‌تر استفاده از Packageهای تست شده و آماده‌ست. 

Eloqunet Sluggable یک پیکج برای تولید تولید اتوماتیک slug در لاراول می‌باشد که میتونید با مراجعه به صفحه گیت‌هاب این پکیج با اون روش نصبش آشنا بشید.

بعد از نصب و ایجاد تنظیمات مربوطه می‌تونید توی مدل‌هاتون ازش استفاده کنید . روش کار هم به این صورته که شما به طور فرض یک مدل دارید با نام Post. خب باید مدلتون یه چیزی شبیه زیر باشه:


class Post extends ٍEloquent {
 
protected $table = 'posts';

}

بعد از نصب پکیج مربوطه فقط کافیه مدلتونو به شکل زیر تغییر بدید:

use CviebrockEloquentSluggableSluggableInterface;
use CviebrockEloquentSluggableSluggableTrait;
class Post extends Eloquent implements SluggableInterface {
  use SluggableTrait;
    protected $sluggable = array(
        'build_from' => 'title',//فیلدی که slug از اون ساخته میشه
        'save_to'    => 'slug',//فیلدی که قراره خروجی slug در اون ذخیره بشه
    );
    
protected $table = 'posts';

}

بعد از انجام کارهای بالا حالا دیگه شما به راحتی پس از ایجاد یک پست جدید و انتخاب یک عنوان، slug اون رو هم به صورت اتوماتیک داشته باشید. مثلا:

$post = new Post;
$post->title = 'hello world';
$post->save();

خب تا اینجای کار، همه چیز مرتبه ولی یه مشکل بزرگ وجود داره و اون هم عدم پشتیبانی این پکیج و متد Str::slug() از زبان‌های یونیکد مثل فارسیه و این یعنی این پکیج و متد به درد ما نمی‌خورن. ولی باز هم راه حل وجود داره که به این ترتیبه:

ابتدا تنظیمات پکیج را publish می‌کنیم تا از فولدر config پروژه‌مون بهش دسترسی داشته باشیم و در هنگام به‌روزرسانی پکیج، تنظیماتمون باقی بمونه. برای این کار دستور زیر رو توی ترمینال و در دایرکتوری ریشه پروژه‌تون وارد کنید:

php artisan config:publish cviebrock/eloquent-sluggable

حالا اگه به فولدر app/config/packages/cviebrock/eloquent-sluggable برید فایل تنظیمات با نام config.php اونجا قرار داره.

حالا اگه فایل تنظیماتو باز کنید میبینید که گزینه‌های مختلفی برای اعمال کردن داره مثل unique که مشخص می‌کنید که slugهاتون در دیتابیس یکتا باشند یا نه که یکتا بودنشون تو آدرس‌دهی میتونه خیلی کمک کنه و یا گزینه on_update که مشخص می‌کنید آیا نامک در هنگام به روزرسانی رکورد به روزرسانی بشه یا نه که پیشنهاد می‌کنم اینو به true تغییر بدید.

یک گزینه دیگر وجود داره به نام method که میتونید در این گزینه متد و یا تابع دلخواهی که میخواهید slugهاتون بر اساس اون ساخته بشن رو تعریف کنید. به صورت پیش‌فرض Eloquent-sluggable از متد Str::slug() برا ساختن نامک استفاده می‌کنه که مشکلشو با زبان فارسی فهمیدیم چیه.

برای پشتیبانی از زبان‌های یونیکد فقط کافیه که متد زیر را به اون گزینه نسبت بدید و فایل config.php رو save کنید. بعد از اون به راحتی میتونید برید دنبال بقیه کارهاتون ;)

'method' => function($string, $separator = '-') {
            $_transliteration = array(
                '/ä|æ|ǽ/' => 'ae',
                '/ö|œ/' => 'oe',
                '/ü/' => 'ue',
                '/Ä/' => 'Ae',
                '/Ü/' => 'Ue',
                '/Ö/' => 'Oe',
                '/À|Á|Â|Ã|Å|Ǻ|Ā|Ă|Ą|Ǎ/' => 'A',
                '/à|á|â|ã|å|ǻ|ā|ă|ą|ǎ|ª/' => 'a',
                '/Ç|Ć|Ĉ|Ċ|Č/' => 'C',
                '/ç|ć|ĉ|ċ|č/' => 'c',
                '/Ð|Ď|Đ/' => 'D',
                '/ð|ď|đ/' => 'd',
                '/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě/' => 'E',
                '/è|é|ê|ë|ē|ĕ|ė|ę|ě/' => 'e',
                '/Ĝ|Ğ|Ġ|Ģ/' => 'G',
                '/ĝ|ğ|ġ|ģ/' => 'g',
                '/Ĥ|Ħ/' => 'H',
                '/ĥ|ħ/' => 'h',
                '/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ/' => 'I',
                '/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı/' => 'i',
                '/Ĵ/' => 'J',
                '/ĵ/' => 'j',
                '/Ķ/' => 'K',
                '/ķ/' => 'k',
                '/Ĺ|Ļ|Ľ|Ŀ|Ł/' => 'L',
                '/ĺ|ļ|ľ|ŀ|ł/' => 'l',
                '/Ñ|Ń|Ņ|Ň/' => 'N',
                '/ñ|ń|ņ|ň|ʼn/' => 'n',
                '/Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ/' => 'O',
                '/ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º/' => 'o',
                '/Ŕ|Ŗ|Ř/' => 'R',
                '/ŕ|ŗ|ř/' => 'r',
                '/Ś|Ŝ|Ş|Ș|Š/' => 'S',
                '/ś|ŝ|ş|ș|š|ſ/' => 's',
                '/Ţ|Ț|Ť|Ŧ/' => 'T',
                '/ţ|ț|ť|ŧ/' => 't',
                '/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ/' => 'U',
                '/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ/' => 'u',
                '/Ý|Ÿ|Ŷ/' => 'Y',
                '/ý|ÿ|ŷ/' => 'y',
                '/Ŵ/' => 'W',
                '/ŵ/' => 'w',
                '/Ź|Ż|Ž/' => 'Z',
                '/ź|ż|ž/' => 'z',
                '/Æ|Ǽ/' => 'AE',
                '/ß/' => 'ss',
                '/IJ/' => 'IJ',
                '/ij/' => 'ij',
                '/Œ/' => 'OE',
                '/ƒ/' => 'f'
            );

            $quotedReplacement = preg_quote($separator, '/');
            $merge = array(
                '/[^sp{Zs}p{Ll}p{Lm}p{Lo}p{Lt}p{Lu}p{Nd}]/mu' => ' ',
                '/[sp{Zs}]+/mu' => $separator,
                sprintf('/^[%s]+|[%s]+$/', $quotedReplacement, $quotedReplacement) => '',
            );
            $map = $_transliteration + $merge;
            unset($_transliteration);
            return preg_replace(array_keys($map), array_values($map), $string);
    },

اینو بگم که من این متد رو از یکی از کتابخونه‌های فریمورک CakePHP برداشتم و با کمی تغییر تو اینجا قابل استفاده‌ش کردم.

ادامه مطلب

منبع اصلی نوشتار زیر در این لینک قرار دارد

ایجاد slug با قابلیت پشتیبانی از زبان فارسی در لاراول

برای داشتن urlهای تمیز و  SEO Friendly در برنامه‌های تحت وب راههای زیادی وجود داره. در لاراول به صورت پیشفرض می‌تونید به روش زیر slug یا نامک از رشته‌هاتون درست کنید: [crayon-54331cac6c92f679879834/]   کار خیلی راحتیه ولی هر سری که بخواهیم یک رکورد رو آپدیت یا ایجاد کنیم مجبوریم از این روش استفاده کنیم، ولی […] ادامه مطلب

منبع اصلی نوشتار زیر در این لینک قرار دارد

ایجاد کنترلرهای منعطف در لاراول با استفاده از Repository‌ها

repository ها در لاراول

اگر با فریمورک‌های مختلف مثل laravel کار کرده باشید، اینو می‌دونید که نوشتن یه وب اپلیکیشن یا یه پروژه میتونه خیلی راحت‌تر از زمانی باشه که میخواهید از پایه با کتابخونه‌های خودتون بنویسید. یکی از مزیت‌های مهم استفاده از فریمورک‌ها، مستندات قوی و جامعه پشتیبان اون‌هاست که بهشون قدرت میده و شما هم می‌تونید از این قدرت به نفع خودتون و یا نفع همون جامعه کاربریش استفاده کنید.

در لاراول با استفاده از کتابخونه‌های قوی کارتون خیلی سرعت دارهو به راحتی پیش میره ولی بعضی موقع این راحتی کار دستتون میده. به عنوان مثال به کد زیر دقت کنید:

class PostController extends BaseController {
public function getIndex()
{
$posts = Post::all();
return View::make('post.index', compact('posts'));
}

تو کد بالا ما یه کنترلر Post داریم و یه متد index که میشه صفحه اصلی کنترلرمون و توش با استفاده از مدل Post تمام رکورد‌ها رو ریختیم داخل یه متغیر و اونو پاس دادیم به View مون. تا اینجای کار، لذت بخش و آسون بود.

مشکل کجاست؟

 مشکل موقعی پیش میاد که بخواهید کدتونو تست کنید. خب تو این مورد انجامش ممکن نیست، چون Dependencyها یا نیازمندی‌های کنترلرمون که از یک کلاس دیگه استفاده می‌کنه تعیین نشده و نمیشه از اون توی تست استفاده کرد. پس به مشکل میخوریم.

یکی دیگه از مشکلات هم برمیگیرده به زمانی که بخواهیم نوع دیتابیسمونو عوض کنیم. مثلن بخواهیم از mongoDB به جای Mysql یا هر نوع دیتابیس از نوع Sql، استفاده کنیم. خب، توی استفاده از انواع Sql دیگر مثل SqlServer یا Postgesql نباید مشکلی باشه و نیازی نیست کدمونو تغییر بدیم ولی اگر به mongoDB بخواهیم کوچ کنیم مجبوریم تمام قسمت‌های کدمونو بازنویسی کنیم که این به دور از اصول توسعه سریع و تمیزه.

راه حل چیه؟

یکی از بهترین راه‌حل ها استفاده از Repository ها برای جدا کردن مدل‌ها از کنترلر‌هامون و مدیریت Dependency Injectionهاست. خب اول باید ببینیم Repository چی کار می‌کنه؟ Repositoryها میان یه واسطی میشن به بخش دیتابیس و کنترلرهامون و مثل یه تونل و فیلتر عمل می‌کنن تا ما از یک نوع کدنویسی و استاندارد برای ارتباط با پایگاه‌های داده اعم از (Redis, Sql, NoSql) استفاده کنیم.

به طور کلی Repositoryها به معنای ارتباط دهنده بین دو چیز هستند.

اگر به واژه رابط یا واسط توجه کرده‌باشد درمی‌یابید که Repository چیزی نیست جز interfaceها. بله، ما به کمک یکی از امکانات شی‌گرایی برای حل این مشکلات استفاده می‌کنیم.

حالا کد بالا رو می‌خواهیم بازنویسی کنیم:

ابتدا یک Repository برای Post ایجاد می‌کنیم:

interface PostRepository{
public function find($id, array $columns = array('*'));
public function all(array $columns = array('*'));
}

سپس میاییم یک کلاس دیگر که از این interface ارث برده را ایجاد می‌کنیم: (توجه داشته باشید تمام کلاس‌هایی که از interfaceها implement می‌شوند باید تمام متدهایی که در interface نام برده شده‌اند‌ را داخل خودشون پیاده‌سازی کنند:

ما یک کلاس برای کار با انواع دیتابیس Sql ایجاد می‌کنیم و همونطور که میدونید برای این کار از کتابخونه Eloqunet لاراول استفاده می‌کنیم:

class EloquentPostRepository implements PostRepository {
public function find($id, array $columns = array('*'))
{
return Post::find($id, $columns);
}
public function all(array $columns = array('*'))
{
return Post::all($columns);
}
}

حالا کنترلرمونو بازنویسی می‌کنیم:

class PostController extends BaseController {
public function __construct(PostRepository $post)
{
$this->post = $post;
}
public function getIndex()
{
$posts = $this->post->all();

return View::make('post.index', compact('posts'));
}
}

همونطور که میبینید دیگه کنترلر ما براش فرق نمیکنه که از چه نوع دیتابیسی استفاده کنه. ما به راحتی می‌تونید کلاس مربوط به اونو بنویسیم و با استفاده از Ioc Container لاراول، اونو به عنوان مدلمون معرفی کنیم.

چیزی که تو این پست نوشتم یه خورده خورده کاری داره مثل bind کردن کلاسمون به interface تا بتونیم تو پروژه‌هامون ازش استفاده کنیم که به صورت تفصیلی تو پست‌های آینده در موردش صحبت می‌کنم. فقط میخواستم یه دیدی از این کار داشته باشید.

ادامه مطلب

منبع اصلی نوشتار زیر در این لینک قرار دارد

ایجاد کنترلرهای منعطف در لاراول با استفاده از Repository‌ها

اگر با فریمورک‌های مختلف مثل laravel کار کرده باشید، اینو می‌دونید که نوشتن یه وب اپلیکیشن یا یه پروژه میتونه خیلی راحت‌تر از زمانی باشه که میخواهید از پایه با کتابخونه‌های خودتون بنویسید. یکی از مزیت‌های مهم استفاده از فریمورک‌ها، مستندات قوی و جامعه پشتیبان اون‌هاست که بهشون قدرت میده و شما هم می‌تونید از […] ادامه مطلب