<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های &lt;amir&gt;</title>
        <link>https://virgool.io/feed/@amiralizadeh9480</link>
        <description>?Talamanca = My medicine! | https://goo.gl/ceaBN7</description>
        <language>fa</language>
        <pubDate>2026-04-14 18:37:05</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/3160/avatar/RcQjl3.png?height=120&amp;width=120</url>
            <title>&lt;amir&gt;</title>
            <link>https://virgool.io/@amiralizadeh9480</link>
        </image>

                    <item>
                <title>برای رفتن به سربازی چه وسایلی همراه خود ببریم؟</title>
                <link>https://virgool.io/@amiralizadeh9480/%D8%A8%D8%B1%D8%A7%DB%8C-%D8%B1%D9%81%D8%AA%D9%86-%D8%A8%D9%87-%D8%B3%D8%B1%D8%A8%D8%A7%D8%B2%DB%8C-%DA%86%D9%87-%D9%88%D8%B3%D8%A7%DB%8C%D9%84%DB%8C-%D9%87%D9%85%D8%B1%D8%A7%D9%87-%D8%AE%D9%88%D8%AF-%D8%A8%D8%A8%D8%B1%DB%8C%D9%85-h1avjr5msfkc</link>
                <description>همونطور که میدونین سربازی شتریه که جلوی در خونه هر پسر ایرانی میخوابهیه سری یه جوری میپیچونن یا نمیرنیه سری دیگه هم میرنمن جز سری دوممحدود یک ماه پیش خدمت من شروع شد و حالا میخام بر اساس تجربیات شخصی خودم این ویرگول رو برای آیندگان بنویسم برای هر کسی که راهی خدمت زوری سربازی هستش تا مشکلی از نظر وسایل نداشته باشهقبل از هر چیزی چند نکته بگم:من این موارد رو بر اساس تجربیات شخصی خودم تو ارتش نیروی زمینی میگمممکنه تو ارگان‌های دیگه یا حتی سایر قسمت‌های ارتش یا حتی سایر آموزشی‌های نیروی زمینی شرایط خیلی متفاوت باشهپس اگه گفتم مثلا وسیله‌ای رو خودشون اونجا دادن امکانش هست زمانی که شما میرید خدمت متفاوت باشهدر ضمن الان کرونا هست و ممکنه شرایط بعد کرونا تغییر کنهدوم اینکه سعی کنین وسیله خیلی زیاد نبرین چون حجم کمد محدوده و یه قانونی برای فرم کمد هست و شما مجبورین طبق همون کمدتون رو بچینین و وسایل اضافه بردن فقط واستون دردسر ایجاد میکنهسوم اینکه هر وسیله‌ای که خودشون بهتون میدن کیفیتش خیلی مطلوب نیسپس اگه از هر چیزی میخاین جنس خوبش رو داشته باشین خودتون همراه خودتون ببرینمثلاً اگه موهاتون رو دوست دارین به هیچ عنوان توصیه نمیکنم از شامپو پادگان استفاده کنین ساک/کوله پشتییه ساک یا کوله پشتی لازم دارین که وسایل خودتون رو داخلش بذارین. تا چند سال پیش کوله‌پشتی رو خودشون میدادن اما ظاهراً مدتی هست دیگه کوله نمیدن, ترجیحا یه کوله بزرگ بگیرین که همه وسایلتون داخلش جا بشه و بتونین طبق فرم کمدتون رو آنکارد کنینقفل کوچیکیه قفل نسبتاً کوچیک برای قفل کردن کمدتون ببریناگه قفل نداشته باشین احتمال اینکه وسایلتون رو بزنن خیلی زیاده و تو خدمت ناپدید شدن وسایل کاملن عادیهبهتون پیشنهاد میکنم قفلی بخرید که بتونین باهاش ساکتون رو هم قفل کنین چون اونجا ممکنه قفل کمدتون خراب باشه و اگه اینطور بود حداقل بتونین زیپ ساکتون رو قفل بزنینبرای قفل سعی کنید دوتا کلید ببریداگه با یکی از دوستاتون رفتید یه کلید رو بدید دوستتون نگه داره و اگه تنها هستید یه جای پادگان کلید رو پنهان کنین یا دفن کنین که اگه یه موقع کلید رو گم کردین یا داخل کمد جا گذاشتین و قفل کردین یه راه برای باز کردن کمدتون داشته باشین.ساعت مچیتو سربازی زمان خیلی مهمه و لازمه همیشه ساعت دستتون باشه, یه سری پست‌های نگهبانی هم هست دونستن زمان خیلی مهمه برای مثال شب‌ها لازمه نگهبانی باشه که ورود و خروج بچه‌ها از آسایشگاه رو ثبت کنه و حتماً باید زمان ورود و خروج رو بنویسه داشتن ساعت خیلی کاربردی هستراستی ساعت خیلی گرون نبرین چون احتمال اینکه ازتون بزنن هستلباسبرای لباس ترجیحاً یه دونه شلوار راحتیدو دست شرت (خودشون یکی میدن)دو دست زیر پیراهن سفید (خودشون یکی میدن)توجه کنین زیر پیراهنتون حتماً باید آستین‌دار باشهنباید طرح یا لکه‌ای داشته باشه یا حالت راه‌راه داشته باشهنباید نازک باشه و بدنتون از زیرش مشخص باشه باید در حدی کلفت باشه انگار تیشرت پوشیدینلباس راحتی زیاد همراه خودتون نبرین چون اکثر روز لباس نظامی تنتونهفقط تو آسایشگاه اجازه دارین ساعت خارج آموزش لباس شخصی بپوشینحتی موقع دستشویی و حموم رفتن هم باید لباس و شلوار نظامی تنتون باشه حتی بعد ساعت آموزش و نصف شب شلوارک هم نبرین, موقع خواب باید شلوار پاتون باشه و پاتون رو کامل بپوشونهلباسای نظامی, جوراب ساق‌بلند, پوتین و ... لازم نیس بخرین, همه رو خودشون بهتون میدن و یه روز هم بهتون وقت میدن ببرین خیاطی اندازه کنین و علائم و اتیکت روش بچسبونینحولهیه حوله برای تایم حموم و یه حوله برای پاک کردن صورت خودشون بهتون میدنیادتون نره اونجا ملحفه سفید بهتون میدن و شبا سرتون رو روی اون میذارین و همیشه باید تمیز و بدون لک باشهاگه نمیخاین به خاطر عرق روی سرتون ملحفتون زرد شه پیشنهاد میکنم یه حوله دیگه داشته باشین یا همون حوله سرتون رو همیشه بذارین روش و سرتون رو بذارین روی حوله تا ملحفه‌تون کثیف نشه و براتون دردسر شهدمپایییه دمپایی اگه دوست داشتین ببرینالبته خودشون یکی میدن ولی دمپاییش از اسکیت هم لیزترهیکی از بچه‌ها که با کله رفت تو دستشویی بخاطر لیز بودن دمپایی :)ظرفبرای ظرف حتماً همراه خودتون قاشق, چنگال, لیوان ببریناونجا خودشون بهمون سلف میدادن ولی اگه دوس داشتین بشقاب هم ببرین چون اگه سلف رو گم کنین باید هزینه‌ش رو پرداخت کنینچاقو میوه‌خوری همراهتون نبرین اگه دژبانی ازتون بگیره حسابی دردسر میشه براتونواکس و فرچه واکسیه واکس و فرچه برای واکس زدن پوتین‌تون خودشون بهتون میدنمواد بهداشتیهمراه خودتونشامپو (خودشون میدن)مایع‌ظرف‌شویی (میتونین برای دستشویی هم استفاده کنین)صابون (خودشون میدن)پودر رختشویی (خودشون میدن)ببرینپیشنهاد میکنم همه اینا رو داخل قوطی‌های نوشابه بریزین ببرین که مبادا داخل ساکتون ظرفش باز بشه و تمام وسایلتون رو به گند بکشهپیشنهاد میکنم جورابتون رو هر روز بشورین تا مبادا پاتون قارچ بزنه و دردسر شه براتوناسکاچیه اسکاچ حتماً همراه خودتون ببرین تا ظرفاتون رو باهاش بشورینبا دست خالی شستن به شدت دردسرهجاصابونی درداردوتا جاصابونی دردار پلاستیکی بخرینتو یکیش صابون بذارینو تو یکی دیگه هم اسکاچ‌تون رو بذارینیه جاصابونی دردارخمیردندان و مسواکخمیردندون و مسواک رو خودشون بهتون میدن ولی کیفیتشون مناسب نیس و با این هزینه‌های سرسام‌آور دندون پزشکی پیشنهاد میکنم یه مسواک و خمیردندون کیفیت بالا بخرین و همراهتون ببریناگه دهانشویه و نخ‌دندون هم استفاده میکنین همراه خودتون ببرینکرم ضدآفتاباگه تو گرما میرین خدمت بدونین ساعت‌ها قراره زیر آفتاب باشین, اگه نمیخاین آفتاب سوخته بشین یه کرم ضدآفتاب همراه خودتون ببرینپودر بچهچون فعالیت بدنی زیاد دارین احتمال اینکه عرق سوز شین خیلی زیادهمن پیشنهاد میکنم هر روز قبل شروع فعالیت به جاهایی از بدنتون که عرق سوز میشه پودر بچه بزنین تا عذاب نکشینالبته اگه شما راه‌حلی بهتر برای پیشگیری از عرق‌سوز شدن بلدین از اون به جای پودر بچه استفاده کنینبرای من استفاده از پودر بچه جواب میداداسپری بدنتو طول روز تایم خیلی محدودی برای حموم دارین و حتی بعضی روزا ممکنه بخاطر نگهبانی یا کاری نتونین حموم بریناگه حموم هم برین تایمتون خیلی محدوده در حد 5 دقیقه باید شتسشو کامل انجام بدینیه اسپری بدن برای کم کردن بوی بد بدن پیشنهاد میکنم ببرینگوش پاک‌کناگه دوس داشتین یه مقدار گوش پاک کن برای پاک‌کردن گوش ببرینناخن‌گیریه ناخن‌گیر هم ببرین, اونجا ناخناتون همیشه باید کوتاه باشه و سرش یه ذره هم نباید سفیدی مشخص باشهگیره لباسگیره طناب رو برای پهن کردن لباساتون ببرین, البته اونجایی که ما بودیم طنابی نبودش و مجبوری لباسا رو پهن میکردیم روی وسایل ورزشی و عملاً از گیره استفاده‌ای نکردمدستمال کاغذی جیبییه تعداد دستمال کاغذی جیبی بخرین همراه خودتون ببرین خیلی جاها لازمتون میشهمن تو یک ماه تقریباً 7 بسته مصرف کردماگه شما مصرفتون زیاده تعداد بیشتر ببرینچسب زخماحتمال اینکه چند روز اول پاتون داخل پوتین تاول بزنه زیاده, چسب زخم همراهتون ببرین که خیلی اذیت نشیناگه دوست داشتین پماد برای درمان تاول هم همراهتون بیارینیکی از فرمانده‌ها توضیح داد اگه قبل اومدن به خدمت پاهاتون رو حنا بزنین و پوستتون زخیم شه وقتی بیاین خدمت مشکلی واسه پاتون پیش نمیادچسب نواریچسب نواری به شدت به کارتون میاد به خصوص روز ترخیص وقتی وسایلتون رو میریزین تو پلاستیک با چسب نواری سرش رو ببندین که تو اتوبوس وقتی بقیه وسیله‌شون رو بر میدارن وسایل شما پخش زمین نشهپلاستیکچندتا دونه پلاستیک دسته‌دار همراهتون باشه و یه بسته پلاستیک فریزر هم همراهتون ببرینپلاستیک روز آخری که ترخیص میشین به شدت لازمتون میشه که استحقاقی‌هاتون رو بریزین توش و ببرین, اگه اونجا پتو و این چیزاتون رو با پلاستیک دادن حتماً پلاستیکش  رو یه جا نگه دارین برای روز آخر و به هیچ عنوان دور نندازینشدفترچه و خودکاراونجا دفترچه و خودکار خودشون بهمون دادن, منتها شما یکی ببرین و توش شماره کسایی که ممکنه حین خدمت بهشون زنگ بزنین رو داخلش بنویسینکارت تلفنبرای تماس گرفتن یه تعداد تلفن کارتی اونجا موجود هست, کارت تلفن خیلی کمیاب هست ولی میتونین از بعضی مخابراتا تهیه کنینماژیک و لاک غلط‌گیرخیلی زیاد پیشنهاد میکنم این دوتا رو همراه خودتون ببرین و باهاشون روی وسایلتون اسمتون رو بنویسیناگه وسایلتون گم بشه یا یه درصد خدای ناکرده ازتون بزنن حسابی میتونه کمکتون کنهیادتون نره اگه روی لباسای نظامی اسم مینویسن جوری بنویسین وقتی میپوشینش هیچی مشخص نباشهپیشنهاد میکنم با لاک غلط‌گیر داخل پوتینتون اسمتون رو بنویسین, احتمال اینکه پوتینتون رو بزنن زیادههمچنین روز ترخیص هم اسمتون رو روی پلاستیکتون بنویسین که تو اتوبوس با مال بقیه قاطی نشهکتابتو سربازی وقت آزاد خیلی زیاد خواهید داشتیه کتاب همراهتون ببرین و اونجا مطالعه کنین تا سرگرم باشین و حوصله‌تون سر نرهلوازم خیاطیسوزن, نخ (یه رنگ سفید/مشکی و یه رنگ لباس سربازی ارگانتون)قیچی کوچیک, سعی کنین قیچی رو یه جایی بذارین تو دید نباشه چون قانونی اجازه ندارین ببرین ولی قیچی علاوه بر خیاطی خیلی جاهای دیگه به کارتون میادو دوتا تیکه کش به اندازه‌ای که بتونین بذارین دور پاتون برای گتر کردن شلوارتون لازمه که البته کش رو اونجا خودشون بهمون دادنماسک, الکل ضدعفونی و دستکش یکبار مصرفاینها چیزایی هست که برای پیشگیری از کرونا لازم میشه که امیدوارم وقتی دارین این نوشته من رو میخونین شر این بیماری کنده شده باشه از سرمون :)ماسک رو پادگان هر روز خودش به ما میدادالکل هم داده بودنالبته دستکش رو بازم پیشنهاد میکنم ببرین موقع دستشویی شستن دستکش دستتون باشه کمتر چندشتون میشهآجیل و میوه خشکغذایی که داخل پادگان میدن کیفیت خوبی نداره, حجمش کمه و انرژی کمی بهتون میدهپیشنهاد میکنم مقداری آجیل و میوه خشک ببرین هر روز بخورین تا ضعف نکنینمن توت خشک و انجیر خشک رو پیشنهاد میکنمپنبهوقتی میرین سربازی احتمال زیاد یا با تفنگ کلاش یا تفنگ ژ3 قراره تیراندازی کنینهر دو این اسلحه‌ها صدای به شدت بلندی دارن طوری که اگه گوشتون نزدیکش باشه و عادت نداشته باشین تا چند دقیقه گوش درد دارین و گوش‌تون سوت میکشهیه مقدار پنبه ببرین و موقع تیراندازی بذارین تو گوشاتون تا حداقل گوشاتون بعد تیراندازی سوت نکشهچراغ قوهتو آسایشگاه از یه ساعتی به بعد خاموشی هست و هیچکس اجازه روشن کردن چراغا رو ندارهشب‌هایی که نگهبانین برای اینکه بتونین برای مثال داخل کمد رو ببینین یه چراغ قوه خیلی ریز همراهتون باشه که به مشکل نخورینالبته آسایشگاه ما نور تا حدودی از پنجره داخلش میومد و من نیازی به استفاده از چراغ‌قوه پیدا نکردم اما یکی از دوستانم که جای دیگه خدمت میکرد آسایشگاهشون شب‌ها به شدت تاریک بود و نمیشد داخل کمد رو دیدچای کیسه‌ایچایی که داخل پادگان ما میدادن به شدت کم‌رنگ بود در حدی که اصلاً نمیشد اسمش رو چایی گذاشتاگه چای‌خور هستین چای کیسه‌ای همراهتون ببریننمکاکثر غذای‌های پادگان به شدت کم نمکه, اگه غذا پر نمک دوست دارین پیشنهاد میکنم نمک همراه خودتون ببرینداروتو پادگان به میوه و این چیزا دسترسی ندارین و غذا هم خیلی جالب نیسقرص جوشان ویتامین برای جبران کمبود ویتامین رو پیشنهاد میکنمقرص سردرد, معده و این چیزا هم خواستین ببرین اگه خدای ناکرده مریض شدین دارو داشته باشینبردن دارو داخل پادگان ممنوعه سعی کنین یه جایی بذارینش تو چشم نباشه*قبلش حتما از یه پزشک مشورت بگیرین و سرخود دارویی مصرف نکنین*مدارکچندتا کپی شناسنامه, کارت ملی, اصل برگه اعزام به خدمت و برگه واکسن و سایر مدارکی که موقع پست کردن بهتون میدن, همچنین اگه شرایط دار هستین (متاهل, والدین نظامی, والدین فوتی, ...) لازمه که یه سری دیگه مدارک همراهتون داشته باشین و حتماً باید ببرین دفتر اسناد رسمی و کپی برابر اصلش کنینالبته خود پادگان بهتون میگه چه مدارکی لازم داریناگه شهرتون نزدیک باشه میرین میارین و اگه دور باشه به خانواده‌تون میتونین بگین برن کپی برابر اصلش رو بگیرن و براتون پستش کننو کلام آخرمیدونم قبل رفتن به خدمت استرس دارین, خودم که خیلی داشتم :)من قبل اینکه بیام خدمت خیلی گند‌ه‌ش کرده بودم ولی وقتی اومدم بعد یه هفته کم کم شل کردم و به شرایط عادت کردم و خدمت برام عادی شدپیشنهاد میکنم شما هم استرس نداشته باشینامیدوارم خدمت رو به سلامتی به پایان برسونین و موفق باشین</description>
                <category>&lt;amir&gt;</category>
                <author>&lt;amir&gt;</author>
                <pubDate>Tue, 17 Aug 2021 18:08:22 +0430</pubDate>
            </item>
                    <item>
                <title>ورود و ثبت نام با رمز یکبار مصرف در لاراول</title>
                <link>https://virgool.io/laravel-community/%D9%88%D8%B1%D9%88%D8%AF-%D9%88-%D8%AB%D8%A8%D8%AA-%D9%86%D8%A7%D9%85-%D8%A8%D8%A7-%D8%B1%D9%85%D8%B2-%DB%8C%D9%87-%D8%A8%D8%A7%D8%B1-%D9%85%D8%B5%D8%B1%D9%81-%D8%AF%D8%B1-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-k3x344rltdyc</link>
                <description>آقا این چه وضعیتی شده جدیدا هر کی سایت میخاد میگه که کاربر موقع ثبت نام شماره همراه وارد کنه و یه کد چند رقمی براش ارسال بشه و تایید بشهیعنی این آخریا هر چی پروژه داشتم این قابلیت رو داشت :|قشنگ شکرش رو در آوردنحالا منم یه کدی برای این قضیه نوشته بودم هی از این پروژه میبردم به اون پروژه کپی و پیست و ... و همون زیر سوال بردن قائده DRY که خیلی زیاد دربارش به همه گفتم. تصمیم گرفتم به صورت یه پکیج درش بیارم تا هم لازم نباشه هی کپی پیست کنم و کلی کد بزنم هم اینکه دست به دامن متخصص های امنیت هم بشم که بیان یه نگاهی بندازن به چیزی که ساختم اگه باگی , راه نفوذی چیزی داره بهم خبر بدن و اگه راه حل بهتری نسبت به نگه داری آیپی دارن بهم بگن من پیاده سازی کنم هم روی سایت های قبلی که زدم آپدیت کنم و هم سایت های بعدیم خیالم راحت باشه مردم آزاری پیدا نمیشه بزنه شارژ پنل پیامکی رو خالی کنه.تازه بقیه توسعه دهنده های لاراول هم اگه حال کردن میتونن ازش استفاده کنن, صفا کنن و دفعه بعد که خواستن چنین چیزی پیاده سازی کنن کارشون از همیشه راحت تر شده باشه :)خب حالا اینجا به زبون فارسی صریح میخام بگم چجوری این پکیجی که ساختم رو استفاده کنیناستفاده ازش خیلی راحته و اینکه لازم نیست از پنل پیامکی خاصی استفاده کنین و با هر نوع پنل پیامکی روی این کره خاکی کار میکنهحتی حتما لازم نیست پیامک باشه میتونه روش های دیگه مثل ایمیل هم باشه کی میدونه!برای شروع با کمپوزر پکیج رو نصب کنین:composer require sanjabteam/verifyبعد این دستور رو بزنین تا فایل کانفیگش به پوشه کانفیگ پروژه لاراول تون منتقل بشهphp artisan vendor:publish --provider=SanjabVerify\VerifyServiceProviderدر ادامه بهتون توضیح میدم هر کدوم از کانفیگا دقیقا چیکارن اون وسط. البته کامنت توی کد رو هم بخونین به زبون انگلیسی نوشتم چی به چیه و چه خبرهخب همونطور که گفتم این پکیج وابسته به پنل پیامکی خاصی نیست و شما باید قسمت فرستادن کد رو بنویسینبرای اینکار یه اینترفیس ساختم که یه کلاسی باید توی برنامه تون بسازین که متد داخل این اینترفیس رو پیاده سازی کنه و به این شکل که شماره گیرنده رو بهتون میده . اون کد یه بار مصرف رو هم بهتون میده و شما باید کد ارسال پیامکش رو بزنین.&lt;?php
namespace App\Helpers;
use SanjabVerify\Contracts\VerifyMethod;
class SmsVerifyMethod implements VerifyMethod
{
    public function send(string $receiver, string $code)
    {
        return send_sms($receiver, &amp;quotYour code is : $code&amp;quot);
    }
}خب اینجا یه تابع خیلی ساده رو شما باید پیاده سازی کنین. receiver : این پارامتر شماره کسی هست که باید براش پیامک فرستاده بشهcode: کد منحصر بفردی که باید برای کاربر پیامکش کنیندر نهایت باید اگه پیامک با موفقیت ارسال شد باید مقدارtruereturnکنین.خب حالا بریم سراغ اصل مطلب:شما باید در مجموع دوتا کار دیگه انجام بدین هر موقع که میخاین از قابلیت رمز عبور یه بار مصرف استفاده کنین.1. ارسال2. بررسی درستی کدبرای ارسال کد کافیه از این کد استفاده کنین:use Verify;
use App\Helpers\SmsVerifyMethod;

$result = Verify::request($request-&gt;input(&#039;mobile&#039;), SmsVerifyMethod::class);که اینجا پارامتر اول شماره کسی هست که باید براش پیامک ارسال بشه. همونطور که گفتم این میتونه چیزای دیگه باشه مثل ایمیل بستگی داره اون کلاسی که بالاتر پیاده سازی کردین چه نوع گیرنده ای دریافت میکنه و کد رو چه شکلی ارسال میکنهپارامتر دوم این دستور هم اسم اون کلاسی رو باید بدین که قبلا پیاده سازی کردین.خب حالا خروجی این تابع یه آرایه هست به این شکل:$result[&#x27;success&#x27;] : اینکه آیا پیامک ارسال شد یا مشکلی وجود داره$result[&#x27;message&#x27;] : این پیامی هست که به کاربر نهایی نشون میدین$result[&#x27;seconds&#x27;] : این مورد فقط وقتی میاد که خطایی که رخ میده این باشه که کاربر اخیرا درخواست کد داده و چند ثانیه دیگه باید صبر کنه تا دوباره درخواست بدهقسمت دوم کار هم بررسی کدی هست که به کاربر فرستاده شدهبرای اینکار یه Validation rule وجود داره که میتونین ازش استفاده کنین$request-&gt;validate([
    &#039;code&#039; =&gt; &#039;required|sanjab_verify:mobile&#039;
]);اینجا منظور از mobile اسم فیلدی هست که مقدار گیرنده کد داخلشه و همزمان توی این درخواست اومده.اگه نمیخاین از این روش استفاده کنین میتونین دستی هم کدش رو بنویسین به این شکل:use Verify;

$result = Verify::verify($request-&gt;input(&#039;mobile&#039;), $request-&gt;input(&#039;code&#039;));
if ($result[&#039;success&#039;] == false) {
    // Show error $result[&#039;message&#039;]
}خب اینجا دوتا پارامتر میگیره پارامتر اول که شماره گیرنده ای هست که میخاین بررسی کنین کدی که براش ارسال شده رو داره درست وارد میکنه یا نهپارامتر دوم هم کدی هست که کاربر وارد میکنه تا شما درست بودنش رو بررسی کنین. خروجی این تابع هم مثل تابع بالایی هست که success نشونه موفق بودن یا نبودنه و message هم پیامی هست که میتونین به کاربر نشون بدین.خب بذارین کارایی که همین الان این پکیج برای امنیت انجام میده رو بهتون بگماگه متخصص امنیتین و دیدین سوتی دادم ایمیل من رو روی گیت هابم میتونین پیدا کنین :) (ارادت ?✋)با کانفیگ پیش فرض:* هر کاربر با یه آی پی خاص یا شماره گیرنده خاص حداکثر هر 120 ثانیه یک بار اجازه داره درخواست دوباره کنه برای کد* با یه سشن میتونه حداکثر سه بار در یک ساعت درخواست مجدد بده (که خب با پاک کردن کوکی قابل دور زدنه)* با یه آپی خاص میتونه ده بار در یک ساعت درخواست مجدد کد بده (که خب اگه دو نفر همزمان از یه پراکسی بدون قابلیت فوروارد کردن آی پی استفاده کنن اگه یکیشون آزار رسانی کنه اون یکی این وسط میتونه مشکل ساز بشه براش)* هر کاربر اجازه داره حداکثر 5 بار درخواست بده برای بررسی صحیح بودن کد که بعد از 5 بار اشتباه باید مجدد درخواست بده* هر کاربر بعد اینکه کد صحیح رو وارد کرد کدش منقضی میشه و یه بار دیگه نمیتونه از همون استفاده کنه* هر کاربر فقط تا ده دقیقه فرصت داره کدی که براش ارسال شده رو وارد کنه وگرنه زمانش از دست میره و باید از اول درخواست بدهخب حالا بحث کانفیگ و شخصی سازی کردنبه صورت پیش فرض پکیج یه کد عددی 6 رقمی به عنوان کد ارسال میکنه که شما میتونین با تغییر دادن محتویات آرایه code این تنظیمات رو تغییر بدینlength : طول کدcase_sensitive : اگه از حروف استفاده میکنین میتونین مشخص کنین حروف کوچک و بزرگ مهم باشه برای بررسی که خب پیشنهاد نمیکنم باعث میشه کاربرای عادی گیج بشنnumbers: اینکه کد شامل اعداد هم باشه یا نهupper_case : اینکه کد شامل حروف بزرگ انگلیسی هم باشه یا نهlower_case : اینکه کد شامل حروف کوچیک انگلیسی هم باشه یا نهsymbols: اینکه کد شامل علائم عجیب غریب هم باشه یا نهresend_delay: بعد اینکه کاربر درخواست کد داد حداقل چند ثانیه اجازه نداره دوباره درخواست کد بدهexpire_in : کدی که برای کاربر ارسال شد تو چند دقیقه منقضی بشهmax_attemps : کاربر تا چند بار اجازه داشته باشه کد اشتباه وارد کنه و بهش تذکر داده بشهmax_resends: تنظیمات محدودیت ارسال در یک ساعتper_session : تو یک ساعت هر سشن چند بار اجازه داره درخواست کد بدهper_ip : تو یک ساعت هر آیپی چند بار اجازه داره درخواست کد بدهخب اینم از این.امیدوارم یه کمکی شده باشه به توسعه دهنده های لاراولاگه این پکیج رو دوست دارین حمایت کنین حتما داخل گیت هاب بهش ستاره بدین این کارتون کمک خیلی زیادی میکنه https://github.com/sanjabteam/verify دمتون گرم که این مطلب رو خوندینتو جنگ با باگ ها موفق باشین ?سایر نوشته هام: https://virgool.io/@amiralizadeh9480/%D8%AA%D8%AC%D8%B1%D8%A8%D9%87-%D9%85%D9%87%D8%A7%D8%AC%D8%B1%D8%AA-%D8%A7%D8%B2-%D8%B2%D9%85%D9%BE-%D8%A8%D9%87-%D8%AF%D8%A7%DA%A9%D8%B1-%D8%A8%D9%87-%D9%87%D9%85%D8%B1%D8%A7%D9%87-%D9%86%DB%8C%D9%85-%D9%88%D8%AC%D8%A8-%D8%A2%D9%85%D9%88%D8%B2%D8%B4-hrwkfm0hrpth  https://virgool.io/laravel-community/%D8%A7%D8%AF%D9%88%DB%8C%D9%87-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-vumc46ozwcef  https://virgool.io/laravel-community/%D8%A7%D9%81%D8%B2%D9%88%D9%86%D9%87-%D9%85%D9%86-%D8%A8%D8%B1%D8%A7%DB%8C-vscode-%D9%88-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-mw9bcpvidbrd </description>
                <category>&lt;amir&gt;</category>
                <author>&lt;amir&gt;</author>
                <pubDate>Tue, 28 Jul 2020 19:53:56 +0430</pubDate>
            </item>
                    <item>
                <title>تجربه مهاجرت از زمپ به داکر (به همراه نیم وجب آموزش)</title>
                <link>https://virgool.io/@amiralizadeh9480/%D8%AA%D8%AC%D8%B1%D8%A8%D9%87-%D9%85%D9%87%D8%A7%D8%AC%D8%B1%D8%AA-%D8%A7%D8%B2-%D8%B2%D9%85%D9%BE-%D8%A8%D9%87-%D8%AF%D8%A7%DA%A9%D8%B1-%D8%A8%D9%87-%D9%87%D9%85%D8%B1%D8%A7%D9%87-%D9%86%DB%8C%D9%85-%D9%88%D8%AC%D8%A8-%D8%A2%D9%85%D9%88%D8%B2%D8%B4-hrwkfm0hrpth</link>
                <description>من تا همین دو سه روز پیش داشتم از زمپ استفاده میکردم اما تصمیم گرفتم بلاخره مهاجرت کنم به سمت داکر برای ادامه کارم.اگه از بروبکس زمپ کار هستین این پست برای شماست.دلایل مختلف زیادی برای اینکار هست اما من سه تا دلیل داشتم.اولیش این بود که من میخاستم imagick رو استفاده کنم. روی زمپ نصبش کردم کار هم میکرد اما همش یه وارنینگ مسخره میداد و باعث میشد یه سری دیگه از نرم افزار ها مثل phpcs کارشون رو درست انجام ندن. برای همین مجبور بودم هی افزونه ش رو توی php.ini کامنت کنم برای حالت عادی و کامنتش رو بردارم برای کار با composer و موقعی که نیاز به این افزونه بود. سرچ هم کردم چه خاکی به سر بریزم که از شر وارنینگه خلاص شم و یه مشکل مربوط به ورژن بود و نتونستم و بیخیالش شدم.دومیش این بود که زمپ واقعا کند شده بود و روی اعصابم بود و منم از اون دسته برنامه نویسام که حتی اگه یه تغییر کوچیک بدم بازم رفرش میکنم نتیجه رو ببینم مطمئن بشم و بعد به کارم ادامه میدم?. آخر همین پست هم یه مقایسه بین سرعت هاشون گذاشتم ببینین.و همچین از dusk برای تست کردن استفاده میکنم که خب شاید تست کامل یه سایت معمولی حدود 2/3 دقیقه وقت میگرفت.سومیش هم این بود که این روزا همه چی به سمت اتوماتیک شدن پیش میره به عنوان یه بک اند کار زشته اصلا بلد نیستم با داکر کار کنم (هنوزم نیستم!) ولی در همین حد که بتونم با زمپ جایگزینش کنم یادش گرفتم تا یه روزی یه پروژه که بیاد دستم که روی یه PaaS منتشر کنم.من خیلی وقت پیش سعی کردم این کار رو انجام بدم اما نتونستم و بیخیالش شدم و به کار با زمپ ادامه دادم اما این چند روز عید وقت آزاد پیدا کردم و بلاخره انجامش دادم.حالا برای شما هم توضیح میدم چجوری میتونین از زمپ مهاجرت خودتون رو شروع کنین بدون اینکه درگیرتون کنم با ریز امکانات داکر. در آخر هم محیط داشبورد داکر رو شبیه به زمپ بهتون معرفی میکنم تا احساس غریبی نداشته باشین.برای شروع چیزی که مسلمه اینه که داکر رو دانلود کنین و نصب کنین.برای ویندوز که یه ویزارد خیلی ساده داره نکست نکست نکست میزنین ریستارت میکنه سیستمو و همه چی حاضر میشه. https://www.docker.com/products/docker-desktop خب از همین الان بگم سایت داکر برای ایران تحریمه و حالا یا با شکن یا یه یخ شکن خوب میتونین دورش بزنین.خب من یه توسعه دهنده لاراول هستم و از زمپ به این شکل استفاده میکنم که همه پروژه هام رو داخل پوشه htdocs زمپ و تو فولدر های جدا قرار میدم.(test, test2, ...) بعد با کمک Virtual Hostبه هر پروژه یه آدرس منحصربفرد میدم. مثلا آدرس test.loc پروژه تست من رو بالا میاره. test2.loc پروژه تست دومی رو بالا میاره و ....حالا میخام کاری کنم بدون اینکه نیاز باشه زمپ رو حذف کنم یا پوشه htdocs رو تغییر بدم دقیقا با همون آدرس ها بالا بیاد و این کار رو داکر به عهده بگیره به جای زمپ.قبل هر کاری به phpmyadmin زمپتون برین و به تب Export برینتوی قسمت Export method روی Custom قرار بدین وتمام دیتابیس هایی که نیاز دارین رو اکسپورت بگیرین.در آخر هم حتما آپاچی و mysql رو از طریق زمپ خاموش کنین تا به مشکل پورت داخل داکر بر نخورین.خب همونطور که گفتم من توسعه دهنده لاراول هستم و برای توسعه لاراول روی داکر سرچ کردم با Laradock آشنا شدم که یه محیط برای توسعه لاراول داخل داکر فراهم میکنه.برای شروع با git داخل پوشه htdocs زمپ پروژه رو clone میکنم.git clone https://github.com/laradock/laradock.gitبعد به داخل پوشه laradock برین و از فایل env-example کپی بگیرین و اسمش رو بذارین .envخب حالا وقت کانفیگ کردن پروژه س.فایل env رو باز کنین تا قسمت هایی که لازم هست رو تغییر بدین.ظاهرا پورت پیش فرض phpmyadmin که 8080 هست از قبل استفاده شده پس من تغییرش میدم.PMA_PORT=8888خب حالا من تصمیم دارم از nginx استفاده کنم اما شما اگه خواستین میتونین از apache2 هم استفاده کنین اما من nginx رو ترجیح میدم.برای کانفیگ کردن nginx به پوشه nginx/sites میرم.اگه یادتون باشه گفته بودم چجوری با Virtual Host آدرس های مختلف برای پروژه های مختلفم داشتم.توی زمپ این کار همه شون توی فایل httpd-vhosts.conf انجام میشد.حالا برای انجام همین کار توی nginx من باید به ازای هر آدرس یه فایل کانفیگ جدا درست کنم.مثلا من الان برای پروژه test خودم یه کانفیگ میسازم.برای اینکار یه کپی از فایل laravel.conf.example میگیرم و اسمش رو بهtest.loc.conf تغییر میدم.بعد دوتا قسمت root, server_name رو تغییر میدم مناسب با پروژه ای که میخام لود شه.server_name test.loc; # این آدرس هاست من هست
root /var/www/test/public; # اینم آدرس پوشه روتقسمت # به بعد کامنته و لازم نیست بنویسینشبه همین شکل بقیه سایت ها رو هم میسازم.و حالا وقت اینه که image ها رو بسازیم و ازشون container بسازیم.برای اینکار این دستور رو توی پوشه laradock بزنین.docker-compose up -d nginx mysql phpmyadminبسته به سرعت اینترنتتون و کیفیت یخ شکنتون این کار چند دقیقه ای طول میکشه میتونین تو این مدت برین یه چایی یا قهوه☕ یا شیر کاکائو یا دلستر? یا هایپ یا اسموک? بزنین و بعد برگردین?.پیام موفقیت آخر کاراگه وسط کار خطا داد اینترنت رو چک کنین و دوباره این دستور رو بزنین.بعد نصب میرم به phpmyadmin تا دیتابیسی که اکسپورت گرفته بودم رو اینجا ایمپورت کنم آدرس127.0.0.1:8888رو باز میکنم و فیلد ورود رو به این شکل پر میکنم.server: mysql
username: root
password: rootبعد از تب ایمپورت دیتابیسم رو ایمپورت میکنم.یه کار دیگه که باید انجام بدین تغییر دادن کانفیگ فایل پروژه هاتون هست برای دیتابیس. مثلا من برای پروژه تست داخل فایل .envپروژه ام این خطوط رو این شکلی تغییر میدم.DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=test
DB_USERNAME=root
DB_PASSWORD=rootمقادیر DB_HOST, DB_USERNAME, DB_PASSWORD رو تغییر دادم.حالا باید آدرس پروژه ام رو توی مرورگر باز کنم. (test.loc)اگه مشکل csrf و یا کاربر از قبل وارد شده و این چیزا داشتین یه بار کوکی ها رو کامل از مرورگر پاک کنین و دوباره آدرس رو باز کنین.اگه ارور های دیگه ای بودش هم دیگه از عمو گوگل بپرسین تا به راه حل برسین.اگه سایت شما بالا میاد تبریک میگم? شما اولین پروژه تون روdockerizeکردین?.اجرای دستورات composer و artisanیه تفاوتی که از این به بعد تو روند توسعه براتون ایجاد میشه اینه که برای اجرای دستورات آرتیسان و کومپوزر و هر دستور دیگه ای از این به بعد باید داخل bash یا shell containerانجام بدین.برای این کار این دستور رو بزنین.docker exec -it laradock_workspace_1 /bin/bashاگه laradock_workspace_1 وجود نداشت با دستورdocker psمیتونین ببینین اسم container برای workspace تون چیهمقایسه سرعت بین زمپ و داکرخب حالا داخل یکی از پروژه هام میخام بهت نشون بدم که چقدر سرعت تفاوت داره.تست اولم رو با این افزونه انجام میدم.https://github.com/maurobussini/restful-stressکانفیگ:از قصد سه تا دستور select و یه دستور insert و یه دستور delete به mysql هم داخل کد میذارم.Route::get(&#039;/&#039;, function () {
    \App\User::all();
    \App\Category::all();
    \App\Product::all();
    $c = \App\Category::create([&#039;name&#039; =&gt; &#039;test&#039;, &#039;icon&#039; =&gt; &#039;fa fa-star&#039;]);
    $c-&gt;delete();
    return view(&#039;welcome&#039;);
});نتیجه تست در زمپ:نتیجه تست در داکر:حالا یه نمونه هم از داخل پروژه.این یه پروژه ای که برای آموزش دادن چند روز پیش ساختم و سرعت رو داخلش مقایسه کردم. برای اینکه عدالت برقرار شه حدود ده بار رفرش کردم و سریع ترین زمان ممکن رو اسکرین شات گرفتم.نتیجه در زمپ:بوت: 565ms - اپ: 349msنتیجه در داکر:بوت: 39ms - اپ: 77msالان یکی شاید بگه مگه سروره که مهم باشه سرعت چقدره دیگه چند میلی ثانیه که این حرفا رو نداره. آره شاید اینطور به نظر برسه اما فرض کنین برای منی که روزی 300 بار رفرش میکنم هر بار حدود نیم ثانیه وقتم تلف شه و این عدد رو در ماه در نظر بگیریم یه عدد نسبتا بزرگی میشه.مقایسه ظاهر برنامهبرای اینکه حس غریبی بهتون دست نده ظاهر پنل این دو برنامه رو مقایسه میکنم تا ببینین چقدر شبیه هم هستن.البته اگه اون دکمه رو بزنین تمام image هایی که laradock پشتیبانی میکنه رو دانلود میکنه.ولی برای اینکه فقط nginx, php, mysql, phpmyadmin بمونن اون دکمه سمت چپ رو بزنین تا زیر منوش باز شه و دونه به دونه کنتینر ها رو استارت بزنین.و سخن آخریکمی هم ناراحتم که دارم با زمپ خداحافظی میکنم. این نرم افزار از 16 سالگی و از اولین روز های یادگیری برنامه نویسی وب همراهم بود. قبلش فقط تونستم یه هفته توی wamp دووم بیارم و بعدش اومدم سراغ زمپ از همون موقع تا الان همراهم بوده :).زمپ دوست 6 ساله مناگرچه پاکش نمیکنم و برای یه سری کارها نیازش دارم :).ممنون که این پست رو خوندین.اگه توسعه دهنده لاراول هستین و میخاین روند توسعه دادن پنل ادمین پروژه هاتون سریع تر بشه پکیج ادمین ساز من رو یه نگاهی بندازین. http://sanjabteam.github.io/ اگه زحمتی نباشه دکمه ❤️ اون پایین سمت راست هم بفشارین وسایر نوشته هام رو هم نگاهی بندازین: https://virgool.io/@amiralizadeh9480/%D8%AA%D8%AC%D8%B1%D8%A8%D9%87-%D8%B3%D8%A7%D8%AE%D8%AA-%D9%81%DB%8C%D9%84%D9%85-%D8%A2%D9%85%D9%88%D8%B2%D8%B4%DB%8C-%D8%A8%D8%B1%D8%A7%DB%8C-%D9%BE%DA%A9%DB%8C%D8%AC-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84%DB%8C%D9%85-pz8akkudoua6  https://virgool.io/laravel-community/%D8%B3%D8%A7%D8%AE%D8%AA-%D9%BE%D9%86%D9%84-%D8%A7%D8%AF%D9%85%DB%8C%D9%86-%D8%A8%D8%A7-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-%D8%A8%D9%87-%D8%B3%D8%B1%DB%8C%D8%B9-%D8%AA%D8%B1%DB%8C%D9%86-%D8%B1%D9%88%D8%B4-%D9%85%D9%85%DA%A9%D9%86-iaycwl52ddwq  https://virgool.io/laravel-community/%D8%A7%D9%81%D8%B2%D9%88%D9%86%D9%87-%D9%85%D9%86-%D8%A8%D8%B1%D8%A7%DB%8C-vscode-%D9%88-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-mw9bcpvidbrd </description>
                <category>&lt;amir&gt;</category>
                <author>&lt;amir&gt;</author>
                <pubDate>Tue, 31 Mar 2020 11:20:17 +0430</pubDate>
            </item>
                    <item>
                <title>کاربردی ترین پکیج های لاراول</title>
                <link>https://virgool.io/laravel-community/%D8%A7%D8%AF%D9%88%DB%8C%D9%87-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-vumc46ozwcef</link>
                <description>اگه PHP رو سیخ کباب فرض کنیماگه لاراول رو خود کباب فرض کنیم?پس میشه گفت پکیج های لاراول هم ادویه هستن!??️اگه نزنین کباب اون طعمی که باید رو نمیده. یه کباب بدون نمک و فلفل و زردچوبه و ...اگه زیاد هم بزنین کلی طعم مختلف قاطی میشه و زیاد هم جالب نیستپکیج های لاراول هم همینهحالا من اینجا میخام بنویسم از پکیج هایی که هر بار یه پروژه لاراول جدید میسازم به پروژه ام اضافه میکنم تا طعم کد نویسی بهتر بشه ?از اون طرف یه سری کارها هم انجام میدم که اینجا بهتون میگم.مهم ترین ادویه! https://github.com/barryvdh/laravel-debugbar این ابزار یه قسمت به صفحه سایت اضافه میکنه که میتونین کار های مختلفی باهاش انجام بدین و گزارش بگیرینمیتونین لاگ ها رو داخل همون صفحه ببینین بدون اینکه نیاز باشه فایل لاگ رو باز کنینمیتونین درخواست های ایجکس رو ببینینمیتونین محتوای کوکی و سشن رو ببیینینو قابلیتی که من ازش خیلی استفاده میکنم میتونین کوئری هایی که در یه صفحه اجرا میشه رو ببینین و بررسی کنین چند تاشون duplicateیا تکراری هست و با روش هایی مثل Eager loadیا کش کردن بهینه تر کنینبرای شروع این کامند رو میزنمcomposer require barryvdh/laravel-debugbar --devبعد هم این کامند رو برای ایجاد فایل کانفیگشphp artisan vendor:publish --provider=&amp;quotBarryvdh\Debugbar\ServiceProvider&amp;quotادویه دوم برای IDEهر جایی که کد میزنین اگه قابلیت autocompleteداشته باشه اونقدی باهوش نیست که بتونه همه چیز رو کشف کنه. https://github.com/barryvdh/laravel-ide-helper این پکیج تا حد زیاد قابلیت های لاراول رو به autocompleteمحیطی که توش کد میزنین معرفی میکنه.یه نمونه قبل نصب:همون بعد نصب:برای نصب اول کامند زیر رو میزنمcomposer require barryvdh/laravel-ide-helper --devبعد این کامند رو برای ایجاد فایل کانفیگphp artisan vendor:publish --provider=&amp;quotBarryvdh\LaravelIdeHelper\IdeHelperServiceProvider&amp;quot --tag=configفرآیند نصب تموم شده حالا میتونین از کامند های این پکیج برای ساخت فایل های اضافه جهت شناسوندن به autocompleteاستفاده کنین ولی کی حال داره بعد هر بار تغییر این حرکت رو بزنهمن یه برنامه نویس تنبلم و تنبلا همیشه دنبال راحت ترین راه ها میگردن.من این سه خط رو به فایلcomposer.jsonاضافه میکنم که با هر بار dump autoloadاین فایل ها از اول ساخته بشن.این شامل اضافه کردن پکیج های جدید به لاراول هم میشهتو قسمتscriptsاین خط رو&amp;quotpost-autoload-dump&amp;quot: [
    &amp;quotIlluminate\\Foundation\\ComposerScripts::postAutoloadDump&amp;quot,
    &amp;quot@php artisan package:discover --ansi&amp;quot
],سه خط به آرایه اش اضافه میکنم&amp;quotpost-autoload-dump&amp;quot: [
    &amp;quotIlluminate\\Foundation\\ComposerScripts::postAutoloadDump&amp;quot,
    &amp;quot@php artisan package:discover --ansi&amp;quot,
    &amp;quot@php artisan ide-helper:generate&amp;quot,
    &amp;quot@php artisan ide-helper:meta&amp;quot,
    &amp;quot@php artisan ide-helper:models --nowrite&amp;quot
],در آخر اگه شما یه برنامه نویس حرفه ای باشین حتما از یه نرم افزار کنترل نسخه مثل گیت استفاده میکنین لازمه که فایل های ide helperرو از روی ورژن کنترل بردارین وگرنه با هم تیمیاتون به کلی conflictالکی میخورین که حسابی دردسر میشه براتونبرای جلوگیری از این دردسر این سه خط رو به .gitignoreاضافه میکنم./_ide_helper_models.php
/_ide_helper.php
/.phpstorm.meta.phpادویه سوم.دست گل ?عمو تیلور تو نسخه 6 لاراولاگه از لاراول 6 به قبل استفاده میکردین حتما میدونستین به صورت پیش فرض یه سری کد ویو ( یا کد ری اکت که با کامند آرتیسن تبدیل میشد ) تو پروژه تازه ساخته شده وجود داشت و همچنین یه دستور php artisan make:authهم بود که بیس کار رو برای ثبت و ورود کاربر حاضر میکرد تا کارا سری پیش برهحالا همه ی این امکانات به یه پکیج جداlaravel/uiمنتقل شد.برای نصب اول این کامند رو میزنمcomposer require laravel/ui --dev بعد هم من چون از ویو استفاده میکنم از این کامند برای ساخت بیس کار استفاده میکنم.php artisan ui vue --authکادر آخر هم اون کامندی که توی خروجی کامند بالا بود رو میزنم.npm install
npm run devو در آخر بازم یه تعدادی فایل که باید برن تو gitignoreبه خصوص فایل های کامپایل شده توسط میکس و وب پک حسابی براتون دردسر ایجاد میکنن./public/css
/public/js
/public/mix-manifest.jsonادویه با طعم سئو https://github.com/cviebrock/eloquent-sluggable این پکیج کمک میکنه تا آدرس های داینامیک و مناسب برای گوگل بسازین مثلا این لینک ها رو ببینینtest.com/post/welcome-to-posttest.com/test?id=4test.com/test/4من که از سئو سر در نمیارم ولی سئو کارا میگن گوگل با اون اولی خیلی بیشتر حال میکنه.برای شروع این کامند رو میزنم.composer require cviebrock/eloquent-sluggableبرای ساخت فایل کانفیگ هم این دستور رو میزنم.php artisan vendor:publish --provider=&amp;quotCviebrock\EloquentSluggable\ServiceProvider&amp;quotحالا هر موقع برای هر کدوم از مدل هام آدرس اختصاصی نیاز داشتم حرکت های زیر رو انجام میدم.اول فیلد slug رو به جدول اضافه میکنم.$table-&gt;string(&#039;slug&#039;)-&gt;unique()-&gt;index();بعد کانفیگ لازم رو برای مدل انجام میدم.class Category extends Model
{
    use Sluggable;
    public function sluggable()
    {
        return [&#039;slug&#039; =&gt; [&#039;source&#039; =&gt; &#039;name&#039;]];
    }
}بعد قابلیت روت مدل بانیدینگ رو با استفاده از اسلاگ فراهم میکنم.توی تابع boot توی فایل RouteServiceProvider برای مدل مورد نظرم قابلیت بایند کردن رو فراهم میکنم.Route::bind(&#039;category_by_slug&#039;, function ($slug) {
    return Category::where(&#039;slug&#039;, $slug)-&gt;firstOrFail();
});روت های مورد نیازم رو تعریف میکنم و کنترلر و ویو و این داستانا.Route::get(&#039;/دسته-بندی/{category_by_slug}&#039;, &#039;CategoryController&#039;)-&gt;name(&#039;category&#039;);بعد برای راحت تر شدن دسترسی به آدرس مدل ها یه میوتیتور مینویسم تو مدلم.public function getLinkAttribute()
{
    return route(&#039;category&#039;, [&#039;category_by_slug&#039; =&gt; $this-&gt;slug]);
}و خیلی راحت هر جا لازمش داشتم ازش استفاده میکنم.$category-&gt;linkادویه تصاویر https://github.com/Intervention/image تقریبا تو تمام پروژه ها با عکس ها سر و کار دارم و تو اکثرشون نیاز میشه تا چند تایی حرکت روشون بزنم که مثلا سایزشون کوچیک بشن, واتر مارک بخورن و داستانای دیگه. این بهترین پکیجه به نظرم و ثابت شده س.بیشتر استفاده من از این پکیج ساخت عکس های کوچیک شده از هر عکس هست. روش من برای این کار این هست.اول کامند زیر رو میزنم تا پکیج نصب بشه.composer require intervention/imageبعد با کامند زیر فایل کانفیگش رو میسازم.php artisan vendor:publish --provider=&amp;quotIntervention\Image\ImageServiceProvider&amp;quotحالا برای اینکه بتونم از سایز کوچیک شده عکس ها استفاده کنم این حرکت رو میزنم.من معمولا فایل های آپلود شده رو توی یه فولدر uploads داخل فولدر public لاراول میسازم البته میدونم درست ترش اینه که توی storage بسازم و لینک کنم اما خب اکثر سایتایی که ما میزنیم روی هاست آپلود میشه و روی اکثر هاست ها قابلیت لینک فراهم نیست.برای ساخت نسخه کوچیک شده به یه مسیر مشخص تو لاراول ریکوئست میره و اونجا عکس توسط این پکیج کوچیک میشه و نشون داده میشه. برای اینکه سرعت بالا بره من عکس رو کش میکنم و برای اینکار دقیقا محل ذخیره رو جوری مینویسم که انگار همون آدرسیه که تو لاراول نوشتم و وظیفه تبدیل عکس رو به عهده داشت. به این شکل فقط تو اولین ریکوئست فایل کوچیک میشه و از ریکوئست دوم به بعد خود اون فایله لود میشه.اول روت مورد نظر رو تعریف میکنم.Route::get(&amp;quot/uploads/resized-images/{size}/{image_path}&amp;quot, &amp;quotImageController@resizedImage&amp;quot)-&gt;name(&amp;quotresized-image&amp;quot)-&gt;where(&amp;quotimage_path&amp;quot, &amp;quot.+&amp;quot);بعد کنترلر رو به این شکل مینویسم. https://gist.github.com/amir9480/774ca02826324c23135152fbbe93d04d حالا برای استفاده راحت تر کافیه یه میوتیتور دیگه توی مدلم بنویسم.public function getImageLinkAttribute()
{
    return Storage::disk(&#039;public&#039;)-&gt;url($this-&gt;image);
}

public function getImageThumbLinkAttribute()
{
    return route(&#039;resized-image&#039;, [&#039;image_path&#039; =&gt; $this-&gt;image, &#039;size&#039; =&gt; &#039;small&#039;]);
}فیلد image همون مسیر ذخیره عکس تو پوشه آپلود ها هستش.به همین راحتی به لینک نسخه اصلی عکس و لینک نسخه کوچیک شده دسترسی دارم.{{ $post-&gt;image_link }}
{{ $post-&gt;image_thumb_link }}ادویه ای برای دست گل طراحا برای طراحی مدرنBreadcrumbs!میتونم بگم اکثر سایت هایی که تا حالا زدم چه با قالب حاضر و آماده چه با قالب اختصاصی داخلش breadcrumbداشت و اوایل دستی میزدم. اما وقتی با این پکیج آشنا شدم دستی نوشتن بردکرامب کاملا از سرم بیرون رفت دیگه هم برنگشت. https://github.com/davejamesmiller/laravel-breadcrumbs ادویه برای تاریخ شمسیما چه خواسته و چه ناخواسته تو ایران به دنیا اومدیم و اگه برای ایرانی سایت بزنیم احتمالا یه جایی نیاز میشه که با تاریخ شمسی هم سر و کله بزنیم. برای تاریخ شمسی خودم از این پکیج استفاده میکنم و به نظر شخصی خودم نسبت به پکیج های مشابه ش خیلی تمیز تر نوشته شده. https://github.com/hekmatinasser/verta/ ادویه ای برای هاست های اشتراکی و مشتریان خسیس https://github.com/recca0120/laravel-terminal اگه شما هم نیاز دارین که سایتی که ساختین رو روی هاست اشتراکی آپلود کنین پس برای زدن دستورات آرتیسان این پکیج لازمتون میشه حسابی.برای شروع این کامند رو میزنم.composer require recca0120/terminalبرای ساخت فایل کانفیگ و ویو و ...  این کامند رو میزنم.php artisan vendor:publish --provider=&amp;quotRecca0120\Terminal\TerminalServiceProvider&amp;quotبعد این قسمت فایل کانفیگش رو از&#039;enabled&#039; =&gt; env(&#039;APP_DEBUG&#039;),تغییر میدم به&#039;enabled&#039; =&gt; true,و مهمترین و حیاتی ترین قسمت کانفیگ این پکیج این قسمته. احتمالا شما هم یه میدل ویر دارین که فقط به ادمین ها اجازه دسترسی به قسمت هایی از سایت رو میده و بقیه بهش اجازه دسترسی ندارن.اگه چنین میدل ویری دارین که هیچ اگه ندارین اول بسازین و بعد اونو به این قسمت کانفیگ اضافه ش کنین.&#039;middleware&#039; =&gt; [&#039;web&#039;],مثلا&#039;middleware&#039; =&gt; [&#039;web&#039;, &#039;auth&#039;, &#039;can:access_admin_panel&#039;],ادویه مخصوص سر آشپزیه سری ادویه ها بود مثل ادویه های پرداخت و وصل شدن به بانک یا ورود با گوگل و این چیزا که ننوشتم ازشوناما علاوه بر اونا یه سری جاها هست که باید یه جعبه داشته باشین توش ادویه های مخصوص به خودتون باشه و ازش استفاده کنین. یه سری چیزا که بین پروژه ها مشترکه و مخصوص خودتونه و میدونین بهش نیاز دارین. پس چند بار ننویسینش و قاعده DRY رو رعایت کنین و یه پکیج مخصوص خودتون بسازین. اگه دوست ندارین در دسترس همه باشه اصلا اشکالی نداره با کمک قابلیت Repositoriesکومپزر براحتی فقط خودتون و هم تیمیاتون ازش استفاده کنین. اگه هم نه عمومی منتشرش کنین شاید یکی از این ادویه مخصوص سرآشپزتون خوشش اومد و به پروژه خودش اضافه کرد.تبلیغات!ادویه مخصوص سرآشپز من اینه. شاید بزنه پروژتون رو حتی بد مزه کنه اما یه نگاهی بهش بندازین.من کاربری های عمومی رو توی این پکیج برای خودم و هم تیمیام فراهم میکنم. https://github.com/sanjabteam/baloot بعد یه قسمت دیگه هم که بین پروژه ها مشترکه پنل ادمین هست که اون رو هم به شکل یه پکیج در آوردم و سرعت کارمون رو خیلی بهبود میده https://github.com/sanjabteam/sanjab پیشنهاد نمیکنم از این پکیج ها استفاده کنین ادویه آنچنان خفنی نیست اما به شدت پیشنهاد میکنم که پکیجی بسازین که کاراتون رو راحت کنه. اگه این ابزار راحت کننده رو با ما به اشتراک بذارین که چه بهتر.زیر همین پست اگه ادویه خوبی برای لاراول میشناسین بهم معرفی کنین بزنم به پروژه هام ببینم چه مزه ای میشن ?.سایر نوشت هام: https://virgool.io/laravel-community/%D8%B3%D8%A7%D8%AE%D8%AA-%D9%BE%D9%86%D9%84-%D8%A7%D8%AF%D9%85%DB%8C%D9%86-%D8%A8%D8%A7-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-%D8%A8%D9%87-%D8%B3%D8%B1%DB%8C%D8%B9-%D8%AA%D8%B1%DB%8C%D9%86-%D8%B1%D9%88%D8%B4-%D9%85%D9%85%DA%A9%D9%86-iaycwl52ddwq  https://virgool.io/laravel-community/%D9%88%D8%B5%DB%8C%D8%AA-%D9%86%D8%A7%D9%85%D9%87-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-dlyu27r2ijld  https://virgool.io/laravel-community/%D8%A7%D9%81%D8%B2%D9%88%D9%86%D9%87-%D9%85%D9%86-%D8%A8%D8%B1%D8%A7%DB%8C-vscode-%D9%88-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-mw9bcpvidbrd </description>
                <category>&lt;amir&gt;</category>
                <author>&lt;amir&gt;</author>
                <pubDate>Mon, 27 Jan 2020 23:20:27 +0330</pubDate>
            </item>
                    <item>
                <title>قطعی اینترنت از نگاه من (به عنوان یه برنامه نویس)</title>
                <link>https://virgool.io/@amiralizadeh9480/%D9%82%D8%B7%D8%B9%DB%8C-%D8%A7%DB%8C%D9%86%D8%AA%D8%B1%D9%86%D8%AA-%D8%A7%D8%B2-%D9%86%DA%AF%D8%A7%D9%87-%D9%85%D9%86-%D8%A8%D9%87-%D8%B9%D9%86%D9%88%D8%A7%D9%86-%DB%8C%D9%87-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3-jscdj9hby0fz</link>
                <description>اولین روز آذر 1398 هست و شش روز هست که اینترنت ایران تبدیل به اینترانت شده و راه های دسترسی به حتی پایه ترین وبسایت یعنی گوگل قطعه. اعصابم از اونجایی خرد شد که میبینم دغدغه یکی اینه که دیشب رفته رستوران حاج محسن (از رستوران با کلاسای شهر آمل) ولی نتونسته استوری بذاری اینستاگرام!حالا من میخام از دید خودم بگم اوضاع چقدر بدتر نسبت به اونی که دیدش به این موضع فقط استوری گذاشتنه! سعی میکنم جوری توضیح بدم که کسایی که برنامه نویس نیستن هم تا حدودی متوجه بشن من دقیقا چجوری به خاک سیاه نشسته ام.من یه توسعه دهنده وب هستم. با زبان های PHP,JavaScript و فریمورک های Vue , Laravel سر و کله میزنم. بیش از دوسال بدون هیچ درآمدی و کنار گذاشتن بخش زیادی از تفریحاتم تو خونه تونستم سرخود برنامه نویسی رو یاد بگیرم تا یه روزی بتونم از طریقش بتونم زندگیم رو بگذرونم.من نزدیک سه سالی هست در بازار کار مشغول هستم و از این طریق نون بخور و نمیری در میارم.اما حالا همه این زحمت ها قراره به باد بره.دلیلش هم اینه:روحانی و وزیر ارتباطات گفته بودن تلگرام رو فیلتر نمیکنناما فیلتر کردنهمین چند هفته پیش گفتن بنزین رو گرون نمیکنناما گرون کردنهمین چند روز پیش هم گفتن ما چیزی به نام &quot;اینترنت ملی&quot; و &quot;شبکه ملی اطلاعات&quot; نداریم و اینترنت قراره وصل شه...خب اینطور که مشخصه قراره اینترنت کاملا ملی بشهشاید این روز ها فقط جهت آزمایش باشه و موقت دوباره اینترنت وصل شه تا نرم افزاری که قراره اینترنت ملی رو کنترل کنه بهبود پیدا کنه!ولی چیزی که از این مصاحبه ها میشه گفت صد در صد حتمیه ملی شدن اینترنت هست.اگه بی انصاف نباشم خیلی شغل های دیگه هم به واسطه همین کار از بین میره. کسایی که فروشگاه داشتن به خصوص تو اینستاگرام, یوتیوبر ها, استریمر ها, کسایی که با Forex و Binance کار میکردن. کسایی که کانال تلگرام یا پیج اینستاگرام داشتن و از طریق تبلیغ گذاشتن داخلش پول در میاوردن. قبول دارم شغل کاذبیه اما تو این روزا که کار خوب فقط یه رویاس حتی شاخ اینستاگرام هم بودن خودش یه روش پول در آوردنه و ....حالا من اساسی ترین مشکلاتم رو به عنوان برنامه نویس که این چند روز برام پیش اومده رو میگماول مشکل نبود گوگل هست. در بُعد دوم نبود استک اُورفلو. حالا این چی هست (برای کسایی که برنامه نویس نیستن). هیچ برنامه نویسی تو دنیا وجود نداره که همه چیز رو بدونه و مادر زادی همه مشکلات رو بتونه حل کنه. قدیما شاید برنامه نویس ها با زنگ زدن به دوستان و همکاراشون مشکلشون رو حل میکردن اما امروزه وقتی گوگل هست که حتی اگه نحوه سوال پرسیدنت اشتباه باشه سوالت رو هم برات درست میکنه که با خیال راحت تو فقط جواب رو پیدا می کنی. در اکثر مواقع هم این سایت استک اٌورفلو تو صفحه اولش هست و دقیقا برای برنامه نویس ها ساخته شده تا با خیال راحت جواب سوال هاشون رو پیدا کنن. حتی با سیستم امتیاز دادن (Up vote, Down vote) این قابلیت رو فراهم کرده که بفهمین چند نفر جواب یه سوال رو کاربردی دونستن یا یه جواب الکی و بیخود. علاوه بر اون میتونین بفهمین کسی که سوال پرسیده کدوم جواب کارش رو راه انداخته که خب مسلما یه روش خیلی مفید تر نسبت به روش سرچ زدن تو فروم ها به سبک ده سال پیش هست. من میتونم به یقیین بگم بیشتر از 99 درصد ارور ها و مشکلاتی که موقع کد زدن باهاشون مواجه میشم یکی بوده که قبل از من به اون مشکل بر بخوره و بیاد تو استک اٌورفلو بپرسه و من نیازی نباشه که سوال رو بپرسم. حالا فرض هم اون یه درصد پیش بیاد بازم میتونم با دانش انگلیسی در حد نخودچی داخل استک اورفلو سوال بپرسم و همچنین خود استک اورفلو قبل اینکه سوالتون رو ارسال کنین یه بار از نظر گرامری بررسی میکنه تا خیالتون جمع باشه. اما خب من نیازی بهش ندارم چون یه افزونه مفیدی تو مرورگر هست به اسم گرامرلی که از همه نظر متن آدم رو بررسی میکنه اما مشکل همینجاست که این ابزار هم به اینترنت وابسته هست و بدون اینترنت دیگه متن انگلیسی نوشتن بدون خطا هم خبری نیست!علاوه بر این دو سایت بزرگوار فروم لاراکستس و ویو جی اس هم دو تا از دیگه سایت ها هستن که میشه توشون جواب های درست برای مشکلات لاراول و  ویو جی اس پیدا کرد که خب این ها هم از دسترس خارج هستن.هنونطور که گفتم برنامه نویس همه چی دون نداریم اما برنامه نویسا قبل از اینکه با یه ابزاری به مشکل بخورن باید یادش بگیرن و خب هیچ جایی کامل تر از مستندات رسمی اون تکنولوژی نیست.مستندات لاراول و ویو جی اس از دسترس من خارج هستن. من برنامه نویس بک اند سایت هستم . به طور خلاصه بگم بک اند میشه دقیقا اون قسمت از کد سایت که ظاهری نیست و جلوی چشم هاتون نیست و نمیتونین ببینینش اما وجود داره! یه قسمت برعکسش هم هست که کد نویسی میشه و شما میتونین نتیجه رو ببینین اینکه یه عکس کجا باشه یه متن کجا باشه منو چجوری باشه و به طور خلاصه ظاهر چجوری پیاده بشه که میشه گفت کد نویسی فرانت اند هست.من در قسمت فرانت اند مثل یه گاو??? عمل میکنم! بعضی موقع ها من نیاز دارم یه ساختاری رو خودم پیاده سازی کنم چون یه سری قسمت ها هست فرونت کار انجامش نمیده و به عهده منه مثل پنل مدیریت سایت هایی که میزنم.این روزا هم اکثر سایت ها فرانتشون بر پایه فریمورک بوت استرپ هست. به طور خلاصه بگم بوت استرپ یه سری کد های آماده هست که یه سری المنت های پایه رو حاضر کرده که کد نویس های فرونت میتونن ازشون استفاده کنن و وقتشون رو فقط برای شخصی سازی این المنت ها بذارن و مجبور نباشن کل کد رو از پایه بزنن. همچنین یه سیستم قدرتمند به اسم گرید داره که کمک میکنه زدن سایت هایی که تو همه نوع صفحه نمایش, از مانیتور 4K تا گوشی های هواووی درست نشون داده بشه و خیلی کم دردسرتر بشه.منم چون نمیتونم کد ها رو از پایه بزنم اکثرا اول فکر میکنم تو صفحه مورد نظرم چه چیزی لازم دارم بعد میرم تو مستندات بوت استرپ و دقیقا کدی که نیاز دارم رو کپی میکنم و بعد هم میشینم سر شخصی سازیش. مثلا من یه جدول میخام بسازم میرم کدش رو کپی میکنم بعد میام سطر و ستون و محتویات توش رو شخصی سازی میکنم اما مشکل اینجاست الان اگه صفحه مستندات بوت استرپ رو باز کنم فقط یه صفحه سفید میبینم. حالا من چون با ویو جی اس کار میکنم زیاد نیازی به این ندارم و از bootstrap vue استفاده میکنم که اومده این المنت های بوت استرپ رو با ویو جی اس سازگارشون کرده اما اگه مستندات بوت استرپ ویو رو هم باز کنم باز به نتیجه ای نمیرسم.حالا شاید بگین خب یه کم مغزت رو به کار بنداز و حفظشون کن یا پاشو برو از همکارات کمک بگیر یا برو از کد های قدیمیت کپی کن بردار بیار اما مشکل بزرگتر از این حرفاست.لاراول و یا حتی اکثر فریمورک های پی اچ پی بر پایه کومپوزر هستن. به طور خلاصه بگم کمپوزر یه ابزاری هست که کمک میکنه شما از کد های برنامه نویس های حرفه ای دیگه در سر تا سر دنیا به صورت یه پکیج جمع و جور تو کدهای خودتون استفاده کنین. بزرگترین مزیتی که نسبت به کپی کردن کد ها به صورت دستی تو پروژه داره اینه که اول نیازی نیست این ها رو داخل کدهاتون بذارین تا همکاراتون ازش استفاده کنن. دومین مزیتش هم اینه که بروزرسانی و گرفتن نسخه های جدیدتر کد های اون برنامه نویس حرفه ای ها خیلی راحت و کم دردسره و فقط با یه کامند این کار انجام میشه! مشکل اول اینجاست این ابزار از سایت پکیجیست اطلاعات پکیج های موجود رو جمع میکنه که این سایت هم از دسترس خارجه. پکیجیست جایی که شما هم اگه خودتون یه سری کد ها داشته باشین و بخواین اون رو از طریق کومپوزر در اختیار سایر برنامه نویس ها قرار بدین باید تو این سایت ثبتش کنین.  مشکل دوم هم اینجاست که خود کد ها از سایت هایی دانلود میشن که بر پایه گیت هستن که در اکثر موارد این سایت گیت هاب هستش که خب این سایت هم الان از دسترس خارجه. سورس کد لاراول هم در گیت هاب نگه داری میشه.حالا این کمپوزر برای بک اند هست. مشابه این قضیه رو برای فرونت هم داریم. پکیج منیجر نود یا به طور خلاصه ان پی ام شبیه این قضایا رو برای فرونت اند فراهم میکنه که خب الان این سایت هم از دسترس خارجه!عملا الان تنها راهی که برای ساخت یه پروژه جدید لاراول هست کپی کردن سورس کد پروژه های قبلی هست! و دقیقا باید با پکیج های همون سایت قبلی کار کنیم و به هیچ وجه نمیتونیم یه پکیج جدید نصب کنیم.گفتم گیت و گیت هاب بذارین بیشتر ازش بگم براتون.گیت ابزاریه که کمک میکنه برنامه نویسی به صورتی تیم راحت تر بشه به این شکل که شما نیازی نیست وقتی تغییری تو کد ها انجام میدین به همکاراتون زنگ بزنین و بگین چیکار کردین تا اون ها هم روی کدهاشون کد های شما رو اضافه کنن. گیت کمک میکنه بفهمین کد هایی که افتضاح نوشته شدن کی نوشته شده برین خرخره ش رو بجوین :) و همچنین میتونین بفهمین همکاراتون رو چه قسمت هایی کار میکنن و دقیقا چیکار میکنن. اگه قسمتی از کد باشه شما و همکارتون همزمان روش کار میکردین و به تداخل بخوره این تداخل ها رو به شما نشون میده تا تصمیم بگیرین کدوم کد نگه داشته باشین و کدومش دور بندازین. علاوه بر همه این ها کمک میکنه شما بتونین خیلی راحت کدهاتون رو مثلا به چند روز پیش برگردونین و تغییرات چند روزتون رو کامل بذارین کنار و مثل یه موزه به کد های گذشته دسترسی دارین و میتونین برین سراغشون.حالا ما به یه سرور نیاز داریم تا هم من و هم همکارام به اون وصل بشیم همگی و تغییرات کد ها رو اونجا نگه داری کنیم. یکی از قابلیت های گیت هاب هم همینه اما گیت هاب یه بدی داره اونم اینه که شما باید سورس کدتون در دسترس عموم باشه. اول اینکه اگه میخاین خصوصی باشه یه محدودیتی تو تعداد پروژه های خصوصی تون دارین (تا همین چند ماه پیش کلا پولی بود این قسمت) دوم اینکه همین چند ماه پیش این قابلیت رو برای ایران تحریم کرد که خب میشه گفت راه حل دور زدنش خیلی دردسره.بهترین جایگزین با اینکه تحریم هست گیت لب هست که با کلک رشتی که همتون بهتر از من بلدین تحریمش رو دور میزنیم و از امکانات رایگانش بهره میبریم که دیگه نمیبریم چون همینجوریش که تحریم بود از داخل هم زدیم قطعش کردیم اون کلک رشتی ها رو هم قطع کردیم دیگه گیت لب بی گیت لب. قشنگ کار میمونه رو هوا. تنها راهش هم الان اینه که سورس گیت لب رو گیر بیاریم و یه سرور بخریم و کد هامون رو اونجا نگه داریم که این کار دوتا بدی داره. اول اینکه کدمون رو علاوه بر خودمون چند تا ایرانی دیگه (صاحب سرور رو عرض میکنم) میتونه ببینه و خب من ترجیح میدم یه خارجی جاسوسی مارو کنه تا یه ایرانی. دوم اینکه هرماه باید کلی پولش بدیم و همچنین مسئولیت بک آپ گرفتن ازش هم به عهده خودمونه.حالا گیت هاب این وسط یه کم امکاناتش فراتره . اصلا گیت هاب رو میشه گفت شبکه اجتماعی برنامه نویس ها هستش و بیشتر از 40 میلیون برنامه نویس تو این شبکه اجتماعی عضون و داخلش هم پر پروژه های اوپن سورس خفن هست. اوپن سورس به طور خلاصه بگم یعنی اینکه شما یه برنامه درست میکنین کدش رو هم در اختیار بقیه قرار میدین به این شکل اونها میتونن تو بهتر کردن اون کد به شما کمک کنن. بهترین مثالی که میتونم بزنم اپلیکیشن تلگرام هست که اوپن سورس هست و صدها ایرانی از روی اون کد تونستن تلگرام های ایرانی بزنن (سورسش رو هم منتشر نکردن هیچوقت به جز یه تعدادی محدودی از دوستان) مثل هات گرام و طلا گرام و قرمز گرام و آبی گرام و قهوه ای گرام! یکی از بزرگترین مزیت هایی که میتونه گیت هاب واسه آدم داشته باشه اینه که اگه کد های خودش رو اوپن سورس منتشر کنه و یه پروژه پرطرفدار و موفق بشه یه رزومه توپ میشه براش و شانس زیادی پیدا میکنه برای استخدام تو شرکت های بزرگ. حتما هم لازم نیست خودتون از پایه یه چیز رو بزنین و موفق بشه.میتونین تو پروژه های بزرگ مثل لینوکس همکاری کنین و یه قسمتی از کار رو به عهده بگیرین :).ولی خب به لطف اینترنت ملی دیگه از این خبرا نیست و میتونین به جاش امنیت داشته باشین.منم چند تا پروژه کوچولویی داشتم روی گیت هاب که دیگه الان ازشون خبری ندارم.حالا این شغل منه و من از نون خوردن افتادم.من یه سری برنامه های بزرگتر واسه آیندم داشتم. هدفم این بود یه برنامه نویس گرافیک بازی بشم و خب تقریبا هفته ای سه شب سعی میکردم آموزش های اوپن جی ال بخونم که بیشتر از این سایت میخوندم که خب اینم دیگه در دسترس نیست. علاوه بر اون سعی داشتم کار با یه موتور بازی سازی آماده رو یاد بگیریم که خب من آنریل انجین رو انتخاب کرده بودم اما حالا مستندات این انجین هم در دسترس نیست.موتور آنریل انجین موتور خیلی بزرگ و پیشرفته ایه و بر خلاف حوزه وب واقعا یه سری جاها آدم نمیتونه فقط با مستندات متنی جلو بره. فیلم های آموزشی رسمی این انجین و همچنین فیلم های آموزشی غیر رسمی که گاهی اوقات بهتر از فیلم های رسمی آموزش میدادن همه و همه در سایت یوتیوب در دسترس بودن که با همون کلک رشتیه میتونستم برم و ببینمشون. اما حالا اونا هم دیگه در دسترس نیستن و دنیایی از آرزوهام برای آینده ام دود میشه میره هوا.اما خب سعی هم کردم با اینترنت ملی کنارم بیام اما واقعا این کجا و امکانات بلاد کفر کجا بیاین براتون مثال بزنم.Connection Refused یکی از ارور های متداول هست که پی اچ پی وقتی نمیتونه به بانک اطلاعاتی مای اس کیو ال وصل بشه چنین خطایی میده. حالا من این ارور رو تو پارسی جو , پارسیک و گوگل سرچ میکنم با همون سبکی که همیشه سرچ میکنم, نتیجه رو ببینین و خودتون قضاوت کنین.این از پارسی جو که این همه بهش افتخار میکنن و میگن &quot;مگه چیش از گوگل کمتره&quot; و &quot;مرغ همسایه غازه&quot; و از این حرفا, تا صفحه 5 رفتم و حتی یه دونه سایتی بهم نشون نداد که به سوال من ربط داشته باشه. از همه چیز مسخره تر اون لینک سوم هست بازش کردم و دیدم یه سایت پی اچ پی هست که داره ارور اتصال به دیتابیس نشون میده در صورتی که گوگل اگه سایتتون ارور بده کلا از روی نتایج سرچ برتون میداره.پارسیک باز یه کم شرایطش بهتره و نتایج مرتبط رو بالا آورد. کارش هم خوب بود اما مشکل اصلی اینجاست به خاطر اینترنت ملی هیچکدوم از لینک های صفحه اول بالا نیومد.در مورد گوگل هم توضیحی لازم نیست بدم واقعا.حالا اگه بخام تحت چالش بذارمشون دیگه واقعا حرفی واسه گفتن جلو گوگل ندارن. خیلی از مواقع پیش میاد که موقع سرچ یه کلمه ای رو با اشتباه تایپی مینویسم و گوگل واسم زحمت تصحیحش رو میکشه.من در مورد undefined variableسرچ میکنم که یکی از ارور های رایج پی اچ پی هست و وقتی اتفاق میفته که شما میخاین از یه متغیری استفاده کنین که وجود خارجی نداره. از قصد با یه مشکل تایپی مینویسم تا ببینم چه میکنن.این از پارسی جو بازم خوبه که همین اول تیر خلاص رو زد مجبور نشدم پنج صفحه دنبال جواب سوال بگردم آخرم هیچی که هیچی.اینم از پارسیک اون یه نتیجه هم هیچ ربطی به سوال من نداشت.اینم از گوگل. نه تنها بهم گفت چجوری میتونم سوالی که پرسیدم رو بهتر بپرسم بلکه با اینکه با کلمات اشتباه سرچ کردم اما بازم نتیجه ای که من دنبالش بودم و ناتوان در تایپش بودم رو بهم نشون داد. به طور خلاصه گوگل از من یه هیرو برنامه نویسی ساخت در صورتی که من زیزیگولویی بیش نبودم و نیستم!حالا در مورد فیلم . یادمه یکی بود میگفت یوتیوب رو میشه جز بزرگترین دانشگاه های دنیا به حساب آورد. راست هم میگفت بزرگوار اما خب چون قراره عوضش امنیت داشته باشیم پس یوتیوب بی یوتیوب. من دسترسی به یوتیوب ندارم اسکرین شات بگیرم همین یه ذره هم که به گوگل وصل هستم به زور وی پی اس هست به حرفایی که میزنم بسنده کنین.اول از همه اینکه یوتیوب همیشه صفحه اولش پر چیزای هیجان انگیزه. سلیقه من رو دقیقا میدونه. میدونه من از بازی سازی و برنامه نویسی خوشم میاد. یه کانال هست به اسم Game From Scratch دقیقا مطالبی که من خیلی دوستشون دارم رو آپلود میکنه. میدونه از گیم خوشم میاد. میدونه ویدیو های یوتیوبر های ایرانی مثل آریا کئوکسر و کیودی پای و میاپلیز رو دوست دارم. میدونه از فیلم های زنده کردن وسایل الکترونیکی از کار افتاده خوشم میاد و خیلی چیزای دیگه. از اون مهمتر میدونه دقیقا از چه سبک موسیقی خوشم میاد و دقیقا مشابه همونا رو برام میاره. حتی یه گزینه گذاشته توی موارد پیشنهادی که اگه من از چیزی خوشم نیومد بهش میگم داداش من با این حال نکردم و دیگه هم برام نمیاردش.اما حالا دوستان ایرانی. من قبلا تو آپارات اکانت داشتم بنابراین باید تا حدودی بدونه چند مرده حلاجم ( که نیست ) و نماشا و تماشا هم همینجوری آوردم این پست کامل بشه.این از آپارات آدم حس میکنه زده شبکه خبراین از تماشا اون عکسش هم نمیدونم چرا بالا نیومدهاینم از نماشا انگار نه انگار ممکنه یه بچه ممکنه اومده باشه تو این سایت تا باب اسفنجی ببینه اما اشتباهی میره تو اون فیلمهنمیگم تو یوتیوب از این چیزا نیست اما حداقل تو صفحه اول و بدون هیچ هیستوری این مسائل رو نشون نمیده دوم اگه به زور سرچ کردن چیزی نشون بده وقتی روش کلیک میکنین ازتون میخاد که ثبت نام کنین و بگین متولد چه سالی هستین تا اگه زیر 18 سال بودین اون فیلم رو نشون نده. بازم میدونم یکی میتونه تاریخ تولد رو اشتباه بزنه و فیلم ببینه اما خب کسی که این همه راه رو امده کرم از خودش بوده!اما خب بیخیال سرگرمی بریم سراغ مباحث علمی.آپارات فقط یه سری فیلم معرفی آورد و در بهترین حالت آموزش های نصب و ... و همچنین فیلم نمونه کار های ساخته شده با آنریل که اکثر فیلم ها هم از سایت های خارجی کپی شده بودتماشا کلا دو سه تا فیلم بود . بعدش رفت تو فاز آموزش رفع چین و چروک صورت !نماشا باز یه کم وضعیت بهتر بود یه چند تا فیلم باز کردم دیدم اینا خودشون از رو یوتیوب کپی شدن و آموزش ملی خبری نیست.یوتیوب که نتوستم سرچ کنم اما به همین عکس گوگل راضی باشین :).من شب هایی که خسته ام تفریحم بازی کردنه. دوتا بازی که این اواخر بازی میکردمCall of Duty Mobile , PUBG Liteبودن که در حالت عادی با کلک رشتی بهشون وصل میشدم اما الان سرگرمیم هم تغییر پیدا کرده به بازی های آفلاین.مشکلات دیگه هم مسلما هست و برنامه نویسی علاوه بر اون تکنولوژی هایی که معرفی کردم به خیلی چیزای دیگه وابسته هست و آدم نیاز هست که طبق نیاز هر پروژه از یه سری پکیج ها استفاده کنه تا کارش جلو بره و این روزا دیگه نه به خود اونها و نه مستنداتشون دیگه دسترسی نداریم.خیلی از آدم ها قراره فدا بشن تا عوضش امنیت داشته باشیم. یکیش منم.دو تا شغل جایگزینی که میتونم انجام بدم.یکیش فست فود هست که اولا درآمدش خیلی کمه و دوم اینکه ساعت کار واقعا طولانی داره و از تعطیلی هم خبری نیست و حتی جمعه ها هم آدم باید کار کنه. من خودم قبلا پیتزایی کار میکردم سه ماه تابستون کنار تنور کار کردن و پیتزا زدن واقعا یکی از کار های سخته.دوم کار کردن کنار پدرم هست که تو کار زدن درخت و چوب هست که خب اونم وضعیت درآمد چندان جالبی نداره اما میتونم کمک کنم با سرعت بیشتری چوب بزنه اما خب واقعا کسل کننده هست برام. جمع کردن چوب از یه جا و ریختنشون پشت نیسون اصلا کاری نیست که بهش علاقه داشته باشم.یه تشکر هم میکنم از شما که به درددل یه برنامه نویس بدبخت شده گوش دادین.فعلا امینت داشته باشیم تا ببینیم چی پیش میاد.به قول یه دوستی تو همین ویرگول &quot;بخند و خوشحال باش که فردا روز بدتریه&quot;.</description>
                <category>&lt;amir&gt;</category>
                <author>&lt;amir&gt;</author>
                <pubDate>Fri, 22 Nov 2019 11:33:30 +0330</pubDate>
            </item>
                    <item>
                <title>ساخت پنل ادمین با لاراول به سریع ترین روش ممکن</title>
                <link>https://virgool.io/laravel-community/%D8%B3%D8%A7%D8%AE%D8%AA-%D9%BE%D9%86%D9%84-%D8%A7%D8%AF%D9%85%DB%8C%D9%86-%D8%A8%D8%A7-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-%D8%A8%D9%87-%D8%B3%D8%B1%DB%8C%D8%B9-%D8%AA%D8%B1%DB%8C%D9%86-%D8%B1%D9%88%D8%B4-%D9%85%D9%85%DA%A9%D9%86-iaycwl52ddwq</link>
                <description>از کجا شروع شد؟تنبلی آقا تنبلی! تنبلی سرچشمه همه این چیزایی هست که میخام براتون بنویسم.تنبلی که نتیجه ش الان ساخت این پکیج هست که کارم رو حسابی سریع کرده :) .واسه همه پروژه هایی که دستم میرسید بلاخره باید یه پنل ادمین میساختم میدادم دست صاحبش تا بتونه اونجوری که میخاد سایتش رو پر کنه. روند ساخت ادمین هم که مشخص بود. https://virgool.io/Software/%D8%B3%D8%A7%D8%AE%D8%AA-crud-%D8%A8%D8%A7-%D9%84%D8%A7%D8%B1%D9%88%D8%A7%D9%84-%D9%88-vue-oa3s5ageyafv البته اون اوایل با vue نمیزدم :).اولین پنل ادمین من با لاراول خیلی هم داغوندقیقا اولین سایتی که پنل ادمین براش زدم خیلی سنگین بود و بخش های خیلی مختلفی داشتاز همه این ها بدتر اینکه چند زبانه بود. یعنی اصلا اینجوری بگم صاحب کار اولم کلا هر سایتی از هر مشتری میگرفت به من میگفت چند زبانه باشه و زبان ها هم به صورت داینامیک اضافه بشه از طریق خود پنل ادمین !من هر قسمت رو که میزدم باید کلی کد مینوشتم.برای هر قسمت یه viewکاملا جدا میزدم. حتی فرم افزودن و فرم اصلاح رو هم جدا از هم درست میکردم و یه تنه قائده DRY رو زیر سوال برده بودم ?. پیشنهاد میکنم در مورد این قائده بخونین و سعی کنین ازش پیروی کنین. https://en.wikipedia.org/wiki/Don%27t_repeat_yourself نتیجه کار این بود که برای هر اصلاح کوچیک بخش های خیلی زیادی رو باید تغییر میدادم.یه چیز دیگه این بود که یه بخش هایی از کار رو کپی پیست میکردم مثلا برای dropzoneباید کلی کد مختلف مینوشتم و دقیقا تو هر کنترلر و ویو کلی کد تکراری مینوشتم و کپی پیست میکردم و اگه جایی نیاز به اصلاح داشت باید یه عالمه بخش های مختلف رو اصلاح میکردم.من حتی با قابلیت fill , fillable و اینا آشنایی نداشتم و هر فیلد رو اینجوری پر میکردم!$post-&gt;test_1 = $request-&gt;input(&amp;quottest1&amp;quot);
$post-&gt;test_2 = $request-&gt;input(&amp;quottest 2&amp;quot);و هر بار ادیت کردن یه بخش یه عذاب حسابی واسه من بودش.حالا یه پروژه جدید میومد و من مجبور بودم هی کد کپی کنم از این پروژه ببرم تو اون پروژه, اصن یه وضی.خب حالا از کجا روش سریع تر به ذهنم رسید.همکار من یه پکیج به اسم voyager به من معرفی کرد. https://laravelvoyager.com/ من این پکیج رو امتحان کردم و واقعا ازش لذت بردم. برای شروع و تست کردنش یه پنل یه وبلاگ رو یه روزه پیاده سازی کردم باهاش کاری که راحت از من یه هفته وقت میگرفت و خب یه خط کد هم ننوشتم!!!خیلی خوب بود به خودم میگفتم ایول من همین رو اصن استفاده میکنم از این به بعد کی حال داره ادمین بزنه.اگه متن رو از اول دقیق خونده باشین میدونین اینجا جاییه که مشکل میخورم.یه مدیر که نه تنها سایت چند زبانه میخاد بلکه میخاد زبان ها از طریق ادمین داینامیک اضافه بشن و حذف بشن. منم جا نزدم گفتم احتمالا باید پکیج دیگه ای هم باشه که بتونه این کار رو برام انجام بده( ولی نبود ).اون پکیج life changing چی بود؟!خب یه پکیج پیدا کردم که بهم فهموند یه چیزی مثل voyagerچجوری کار میکنه http://crudbooster.com/ این پکیج بر خلاف voyagerنیاز به کد نویسی داشت و این همون چیزی بود که نیاز داشتم تا بفهمم چجوری میشه یه ادمین رو سریع تر پیاده سازی کرد.$this-&gt;col = []; $this-&gt;col[] = [&amp;quotlabel&amp;quot=&gt;&amp;quotName&amp;quot,&amp;quotname&amp;quot=&gt;&amp;quotname&amp;quot];
$this-&gt;col[] = [&amp;quotlabel&amp;quot=&gt;&amp;quotHomeroom Teacher&amp;quot,&amp;quotname&amp;quot=&gt;&amp;quothomeroom_teacher&amp;quot]; 

$this-&gt;form[] = [&amp;quotlabel&amp;quot=&gt;&amp;quotName&amp;quot,&amp;quotname&amp;quot=&gt;&amp;quotname&amp;quot,&amp;quottype&amp;quot=&gt;&amp;quottext&amp;quot,&amp;quotrequired&amp;quot=&gt;TRUE,&amp;quotvalidation&amp;quot=&gt;&amp;quotrequired|string|min:3|max:70&amp;quot,&amp;quotplaceholder&amp;quot=&gt;&amp;quotYou can only enter the letter only&amp;quot];
$this-&gt;form[] = [&amp;quotlabel&amp;quot=&gt;&amp;quotHomeroom Teacher&amp;quot,&amp;quotname&amp;quot=&gt;&amp;quothomeroom_teacher&amp;quot,&amp;quottype&amp;quot=&gt;&amp;quottext&amp;quot,&amp;quotrequired&amp;quot=&gt;TRUE,&amp;quotvalidation&amp;quot=&gt;&amp;quotrequired|min:1|max:255&amp;quot];خب این پکیج اومده بود یه کنترلر ساخته بود و مشخصات فیلد های جدول و فیلد های فرم ها رو تو آرایه ذخیره کرده بود و با استفاده از همین ها ویو های مناسب رو تولید میکرد. و بعد موقع ذخیره دوباره با استفاده از همین ها تشخیص میداد هر فیلد رو چجوری ذخیره کنه.با همین تکنیک سعی کردم پنل ادمین خودم رو دقیقا با همین سبک بسازم. اینطوری هم لازم نبود مثل قدیم هی کد اینور اونور کپی پیست کنم. هم قابلیت زبان رو هم به صورت داینامیک داخل خود ادمین اضافه میکردم.ولی خب من یه تفاوتی بین ادمین خودم و crudbooster گذاشتم. اونم این بود که crudbooster یه آرایه برای فیلد فرم ها داشت و یکی دیگه برای جدول, من هر دو این ها رو ادغام کردم و اسمشون رو گذاشتم widget! خروجی این یه فرم و جدول کامل به اصطلاح CRUD بود که فقط با داشتن مدل کار خودش رو انجام میداد. فقط با همین میزان کد برای هر پروژه بعدی که به دستم میرسید. بدون نیاز به ساخت ویو جدا یا کد ذخیره سازی جدا کارش رو انجام میداد.خب  حالا میخام یه توضیح سطحی بدم از اینکه خودتون چجوری میتونین یه چیز شبیه این رو درست کنین.اولین قدم ساخت جدول هست. شما برای ساخت جدول به یه تعداد اطلاعات نیاز دارین.اینکه جدولتون چه ستون هایی داره و اینکه چه چیز هایی تو هر سطر و ستون نشون بده.خب برای این کار نیاز به دو تا آرایه (یا کالکشن نیاز دارین).یه آرایه که لیست فیلد ها رو نگه داره.$fields = [    
    [&#039;name&#039; =&gt; &#039;name&#039;, &#039;title&#039; =&gt; &#039;نام&#039;],
    [&#039;name&#039; =&gt; &#039;email&#039; =&gt; &#039;title&#039; =&gt; &#039;ایمیل&#039;]
]و خب لیست کاربران.$users = User::all();کد ویو جدول یه چیز شبیه این میشه. کد رو ذهنی مینویسم.&lt;table&gt;
    &lt;thead&gt;
        @foreach($fields as $field)
            &lt;th&gt;{{ $field[&#039;title&#039;] }}&lt;/th&gt;
        @endforeach
    &lt;/thead&gt;
    &lt;tbody&gt;
        @foreach($users as $user)
             &lt;tr&gt;
            @foreach($fields as $field)
                &lt;td&gt;
                   {{ $user-&gt;{ $field[&#039;name&#039;] } }}
                &lt;/td&gt;
             @endforeach
             &lt;/tr&gt;
          @endforeach
    &lt;/tbody&gt;
&lt;/table&gt;این جدول رو تشکیل میده اما فیلد های فرم یکمی از این پیچیده تر هستن.شما ممکنه نوع ورودی مختلف داشته باشینمثل چک باکس, متن, رمز عبور, فایلهر کدوم از این ها هم به سبک خودشون باید تو دیتابیس ذخیره بشن.پس تو لیست فیلد ها به نوع هم احتیاج هست.$fields = [
    [&#039;name&#039; =&gt; &#039;name&#039;,  &#039;title&#039; =&gt; &#039;نام&#039;, &#039;type&#039; =&gt; &#039;text&#039;],
    [&#039;name&#039; =&gt; &#039;email&#039;, &#039;title&#039; =&gt; &#039;ایمیل&#039;, &#039;type&#039; =&gt; &#039;email&#039;],
    [&#039;name&#039; =&gt; &#039;password&#039;, &#039;title&#039; =&gt; &#039;رمز عبور&#039;, &#039;type&#039; =&gt; &#039;password&#039;]
];حالا برای ویو فرم.@foreach($fields as $field)
    &lt;input type=&amp;quot{{ $field[&#039;type&#039;] }}&amp;quot id=&amp;quot{{ $field[&#039;name&#039;] }}&amp;quot name=&amp;quot{{ $field[&#039;name&#039;] }}&amp;quot /&gt;
     &lt;label for=&amp;quot{{ $field[&#039;name&#039;] }}&gt;{{ $field[&#039;name&#039;] }}&lt;/label&gt;
@endforeachبرای ذخیره سازی این مثال دو حالت داریم.برای رمز عبور باید از تابع bcrypt استفاده بشه و بقیه فیلد ها ذخیره عادی کافی هست.foreach ($fields as $field) {
    if ($field[&#039;type&#039;] == &#039;password&#039;) {
        $model-&gt;{ $field[&#039;name&#039;] } = bcrypt($request-&gt;input($field[&#039;name&#039;]));
    } else {
        $model-&gt;{ $field[&#039;name&#039;] } = $request-&gt;input($field[&#039;name&#039;]);
    }
}این یه ادمین دیتامحور خیلی ساده هست. دو تا فیلد که نحوه ذخیره شون با هم فرق داره بیشتر نداره.اگه بخواین همه رو با if و else ذخیره کنین فرض کنین 20 نوع فیلد مختلف وجود داشته باشه. اون وقته که کد حسابی شلوغ میشه. این مشکل رو من با تبدیل کردن این آرایه ها به کلاس حل کردم به این شکل که نحوه ذخیره کردن و کد نمایش فیلد و ... همه درون همون کلاس نگه داری میشن و دیگه نیازی به دست بردن تو کد کنترلر یا ویو CRUD نیست. یه تابع تو کلاس هر widget برای render کردن وجود داره و من دیگه نیازی به این ندارم که دستی چیزی رو چک کنم.@foreach($fields as $field)
    {!! $field-&gt;getHtml() !!}
@endforeachهمچنین برای ذخیره سازی دیگه نیازی به if و else ندارم.foreach ($fields as $field) {
    $field-&gt;store($request, $model);
}برای مثال برای همین ویجت رمز عبور چنین تابعی باید داشته باشم.public function store(Request $request, $model) {
    $model-&gt;{ $this-&gt;name } = bcrypt($request-&gt;input($this-&gt;name));
}همچنین برای اون قسمت getHtml کافیه یه view بنویسم تا کارم رو راه بندازه.public function getHtml() {
    return view(&#039;admin.components.password_field&#039;);
}و به این ترتیب کد مخصوص فیلد رو میفرستم به ویو اصلی crud بدون اینکه نیاز باشه به کد crudدسترسی داشته باشم یا نیاز باشه که اصلاحش کنم.گاهی اوقات پیش میاد که کد html خالی کافی نیست. برای مثال همون dropzone برای درست شدنش علاوه بر html به کد های جاوا اسکریپت هم نیاز داریم. بنابراین دقیقا زیر همون صفحه فیلد یه تگ script هم لازم داریم که کد جاوا اسکریپت فیلد ها در اونجا استفاده میشن.
    @foreach($fields as $field)
        {!! $field-&gt;getJs() !!}
    @endforeach
به همین راحتی میتونین جاوا اسکریپت رو هندل کنین.خب اگه بخام همینجوری ادامه بدم باید یه کتاب بنویسم در مورد کارایی هایی که میتونین به ادمینتون اضافه کنین. شما باید بر اساس نیازتون یه کارایی به ادمینتون اضافه کنین. یعنی تا نیاز حس نشه نمیتونین کاری کنین.بخام مثال بزنم همین فیلد نوع فایل مثلا شما باید تشخیص بدین که مدل تون حذف شده یا تغییر پیدا کرده که بتونین خود فایل رو از پوشه آپلود ها پاک کنین تا فضای هاست اشغال نشه. نوشتن این کد با ایونت مدل ها خیلی راحت هست. فقط کافیه تو کنترلری که crud رو هندل میکنه یه قسمت اضافه کنین تا ایونت مدل ها رو به تابعی تو کلاس فیلد هاتون بفرسته.ماژول کردن این پنلبه شدت پیشنهاد میکنم ادمینی که میخاین بسازین رو به شکل یه ماژول در بیارینچرا؟فرض کنین سه تا سایت مختلف با این کد ادمینتون میسازین. یهو سر چهارمین پروژه متوجه میشین که یه اشتباهی یه جا انجام دادین. خب روی چهارمین سایت درستش میکنین ولی انقدر مهم هستش که مجبور میشین رو سایت قبلی ها هم همین کار رو انجام بدین. چون کد ها کپی پیست شدن از هر پروژه به پروژه دیگه نیاز دارین که برگردین و تک تک پروژه ها دونه به دونه درست کنین. ولی اگه ماژول کنین میتونین خیلی راحت فقط روی چهارمین پروژه درستش کنین و از بقیه پروژه ها تغییرات رو با سابماژول گیت یا کمپوزر دریافت کنین خیلی راحت, شیک و مجلسی.برای ماژول کردن پنل ادمین دوتا راه پیشنهاد میدم.اول اینکه سعی کنین پکیج نویسی رو در لاراول یاد بگیرین و خودتون پکیج بسازین. البته سوء برداشت نشه که شما اگه پکیج بسازین مجبور هستین که اون رو عمومی منتشر کنین خیلی راحت میتونین با قابلیت repositories کمپوزر پکیج خودتون رو خصوصی نگه دارین و تو تیم خودتون ازش استفاده کنین. https://getcomposer.org/doc/05-repositories.md#git-alternatives مستندات پکیج نویسی لاراول: https://laravel.com/docs/5.8/packages خب اما یه راه دوم هم برای ماژول نویسی هست و اونم این پکیج هست. https://github.com/nWidart/laravel-modules من شخصا از این استفاده نکردم تا حالا اما دیدم کسایی رو که استفاده میکنن!خب امیدوارم تونسته باشم یه دید اولیه از پنل ادمین دیتامحور و اینکه چجوری یکی برای خودتون یا تیم تون بسازین بهتون داده باشم. حداقل برای یک بار هم که شده این روش رو امتحان کنین شاید خوشتون اومد به خصوص تیم های کوچیک (مثل ما ?) که کارش زدن پروژه های کوچیک هست و الویتش کمیت پروژه ها هست.یه کم اضافه تر!میخام یه تعداد از پنل هایی که این سبک کار میکنن رو بهتون معرفی کنم. حالا به اسم CMS یا CMF یا admin generator یا هرچیز دیگه ای.اولین چیزی که میخام معرفی کنم, نه با لاراول ساخته شده نه اینکه ادمین ساز هست بلکه یه سیستم مدیریت محتوا کامله که دیتا رو از روی یه فایل yaml میخونه و با توجه به اون نه تنها ادمین میسازه بلکه دیتابیس و صفحات وبسایت رو هم میسازه. اسم این سیستم مدیریت محتوا bolt هست. https://bolt.cm/ امکانات جالبی داره و پیشنهاد میکنم کد نویسیش رو بررسی کنین براتون خیلی جالب خواهد بود و دید بازتری به این مسائل بهتون میده.دومین چیزی که میخام معرفی کنم پکیج orchid هست. این پکیج هم به همین سبک کار میکنه. https://github.com/orchidsoftware/platform این پکیج هم با کلاس بندی کردن فیلد ها سورسش میتونه دید بازی بهتون بده.سومین پکیج , پکیج laravel-admin رو معرفی میکنم که با همین سبک کار میکنه. https://laravel-admin.org/ چهارمین پکیج litstack. https://github.com/litstack/litstack پکیج بعدی که معرفی میکنم بهتون اسمش filament هستخوبی این پکیج این هست که باlivewireنوشته شده و به راحتی میشه هر چیزیش رو شخصی سازی کرد و توسعه و کامیونیتی‌ش هم در حال حاضر به شدت فعاله. https://filamentphp.com/ Last but not least!آخرین ولی مهم ترین هم پکیج نوا هست که توسط سازندگان خود لاراول ساخته شده و این هم با همین سبک کار میکنه. https://nova.laravel.com/ تنها بدی این پنل هم اینه که پولی هست و هزینه ش به ریال واقعا خیلی سنگینه و نمیشه مشتری رو به پرداخت هزینه ش متقاعد کرد.سخن آخرولی باز هم پیشنهاد اول من بهتون اینه که برای تیم خودتون چنین چیزی رو پیاده سازی کنین. اگه هم خواستین از پکیج های آماده ای که معرفی کردم استفاده کنین قبل از هرکاری مطمئن بشین به پکیج مورد نظرتون تسلط کامل دارین تا جایی به مشکل نخورین بعد پروژه های واقعی رو با اون ها بسازین. درسته که ساختن چنین چیزی از پایه زمان میبره اما مطمئن باشین در پروژه های متعدد باعث میشه حسابی در زمان صرفه جویی کنین و این زمان گذاشتن ارزشش رو داره.سایر نوشته هام. https://virgool.io/@amiralizadeh9480/%D9%88%D8%B5%DB%8C%D8%AA-%D9%86%D8%A7%D9%85%D9%87-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-dlyu27r2ijld  https://virgool.io/@amiralizadeh9480/%D8%A7%D9%81%D8%B2%D9%88%D9%86%D9%87-%D9%85%D9%86-%D8%A8%D8%B1%D8%A7%DB%8C-vscode-%D9%88-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-mw9bcpvidbrd  https://virgool.io/@amiralizadeh9480/%DA%86%DB%8C-%D8%B4%D8%AF-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3-%D8%B4%D8%AF%D9%85-kpsescdv5rci </description>
                <category>&lt;amir&gt;</category>
                <author>&lt;amir&gt;</author>
                <pubDate>Thu, 01 Aug 2019 18:09:26 +0430</pubDate>
            </item>
                    <item>
                <title>افزونه من برای VSCode و فلاتر</title>
                <link>https://virgool.io/@amiralizadeh9480/%D8%A7%D9%81%D8%B2%D9%88%D9%86%D9%87-%D9%85%D9%86-%D8%A8%D8%B1%D8%A7%DB%8C-vscode-%D9%88-%D9%81%D9%84%D8%A7%D8%AA%D8%B1-aukf3xbofqgm</link>
                <description>من حدودا دو ماهی میشه یادگیری فلاتر رو شروع کردم و میتونم بگم خیلی خیلی زیاد باهاش ارتباط برقرار کردم? به خصوص با قابلیت Hot reloadش که حسابی من رو به وجد میاره.من قبلا تا حدودی ری اکت نیتیو کار کردم و میتونم بگم من خیلی راحت تر تونستم فلاتر رو یاد بگیرم تا ری اکت نیتیو رو و واقعا ری اکت نیتیو عذاب میداد منو.حالا من چون در اصل یه برنامه نویس تنبل وب هستم یکی از کارهایی که زیاد تو طول روز انجام میدم اینه که گاهی اوقات مجبور میشم یه تگی رو به اول و آخر یه چیزی اضافه کنم مثلا این شکلی بوده یه چیزی&lt;h1&gt;Hello World&lt;/h1&gt;
&lt;span&gt;:D :D :D&lt;/span&gt;برای یه سری کار ها مجبور میشدم خود این رو داخل یه تگ دیگه بذارم مثلا&lt;div&gt;
    &lt;h1&gt;Hello World&lt;/h1&gt;
    &lt;span&gt;:D :D :D&lt;/span&gt;
&lt;/div&gt;برای اینکار مجبورم یه تگ بذارم قبلیه تگ بذارم بعدشیه کم هم اسپیس اضافه کنم بین تگ ها تا کد تمیز بمونه و بهم ریخته نشهیه برنامه نویس تنبل معمولا میگرده دنبال راحت ترین راهخب راستش قبلا یه افزونه به اسم htmltagwrapپیدا کردم که خب کارش اینه که این روند رو آسون کنه. https://marketplace.visualstudio.com/items?itemName=bradgashler.htmltagwrap آدرسش رو باز کنین اسکرین شاتش رو ببینین متوجه میشین جریان چیه.حالا تو فلاتر هم روند مشابه داریممثلا من یه کد این شکلی دارمRow(
  children: [
      Text(&quot;Hello World&quot;),
      Icon(Icons.test)
  ]
)این مثلا اگه حجمش زیاد باشه از صفحه بیرون میزنه پس باید قابلیت اسکرول براش بذارمSingleChildScrollView(
  child: Row(
    children: [
        Text(&quot;Hello World&quot;),
        Icon(Icons.test)
    ]
  )
)دقیقا همون کار مشابه تو htmlیه کد اولش اضافه میکنمیه کدی به آخرش اضافه میکنمیه کم اسپیس میدماز این افزونه سعی کردم برای فلاتراستفاده کنم دیدم نه نمیشه کاری کرد که ازش اینجا استفاده کردپس خودم دست به کار شدم یه افزونه زدم که دقیقا همین کار رو میکنه ?این افزونه از کلید Alt + Wاستفاده میکردمنم از دوتا کلیدAlt + Cبرای ساخت ویجت هایی که فقط یه بچه دارن و Alt + Sبرای ساخت ویجت هایی که چند تا بچه دارن استفاده کردم.اگر چه اینا رو میشه تو VS Codeبه هر کلیدی که خودتون دوست دارین تغییر بدین.Cحرف اول Containerو Sحرف اول Stackهست.لینک دانلود https://marketplace.visualstudio.com/items?itemName=amiralizadeh9480.flutter-widget-wrap لینک گیت هاب جهت مشاهده سورس کد, ارسال مشکلات و بهبود دادن افزونه https://github.com/amir9480/vscode-flutter-widget-wrap پ.ن: واقعا جا داره یه تشکر هم کنم از سازندگان VS Codeکه توسعه دادن افزونه براش انقدر بی دردسر هستبرای این افزونه کل کدی که لازم بود بنویسم همینقدر بود! و خب یه کم هم دستکاری تو packages.json ???سایر نوشته هام https://virgool.io/@amiralizadeh9480/%D8%A7%D9%81%D8%B2%D9%88%D9%86%D9%87-%D9%85%D9%86-%D8%A8%D8%B1%D8%A7%DB%8C-vscode-%D9%88-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-mw9bcpvidbrd  https://virgool.io/@amiralizadeh9480/%DA%86%DB%8C-%D8%B4%D8%AF-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3-%D8%B4%D8%AF%D9%85-kpsescdv5rci  https://virgool.io/Software/%D8%B3%D8%A7%D8%AE%D8%AA-crud-%D8%A8%D8%A7-%D9%84%D8%A7%D8%B1%D9%88%D8%A7%D9%84-%D9%88-vue-oa3s5ageyafv </description>
                <category>&lt;amir&gt;</category>
                <author>&lt;amir&gt;</author>
                <pubDate>Tue, 11 Jun 2019 22:56:25 +0430</pubDate>
            </item>
                    <item>
                <title>وصیت نامه لاراول</title>
                <link>https://virgool.io/laravel-community/%D9%88%D8%B5%DB%8C%D8%AA-%D9%86%D8%A7%D9%85%D9%87-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-dlyu27r2ijld</link>
                <description>حدود دوساله که با این پدیده بی نظیر در پی اچ پی سر و کله میزنم و میتونم بگم واقعا یه شاهکاره.به خصوص بعد اینکه متوجه این سبک عمو تیلور برای کامنت نویسی در کد ها شدم واقعا شیفته لاراول شدم.این حالت شبیه چاقو تقریبا همه جای سورس لاراول هست و واقعا قابل تحسینه این حجم از ظرافت.و خب میشه گفت من اوایل که پی اچ پی شروع کرده بودم فاز ساختن سیستم مدیریت محتوای خودم رو از پایه داشتم. بعدش هم فاز ساخت فریمورک خودم رو داشتم. ولی لاراول به خوبی حالیم کرد من از فریمورک ساختن فقط توهم ش رو داشتم!حالا از اونجایی که من در جایگاهی نیستم که بخام به کسی نصیحت کنم میخام یکم براتون وصیت بنویسم (به خصوص برای تازه کار ها) که یه سری چیز ها تو لاراول هست که باید ازشون استفاده کنین و در راه درست استفاده کنین.(که وقتی من لاراول رو شروع کرده بودم ای کاش یکی بود و به من میگفت)استفاده از Eloquentتازه کارهایی رو دیدم با اینکه به لاراول اومدن ولی هنوز به همون روش سنتی و استفاده از چیزایی مثل&#x60;DB::statement&#x60; , &#x60;DB::raw&#x60; کارشون رو پیش میبرن در صورتی که Eloquent یکی از قوی ترین و مهم ترین ویژگی های لاراول هست.امااستفاده درست از قابلیت های Eloquentاول اینکه حتما بهتون توصیه میکنم از Relationهای لاراول بهره ببرید و روش سنتی دستی کد زدن رو کنار بذارین.یکی از نکاتی که در مورد ریلیشن ها هست قابلیتی به نامEagerloadهست.اماEagerloadچطوری میتونه باعث افزایش/کاهش سرعت سایت بشه؟برای مثال من یک وبلاگ میسازم. یک صفحه لیست مطالب دارم. حالا کنار عنوان هر پست دسته بندی اون هم آورده میشه. هر دسته بندی چند پست داره و هر پست فقط یه دسته بندی پس رابطه بین شون یک به چند هست.در اینجا داخل حلقه foreach به ازای نمایش دسته بندی هر پست یه کوئری به جدول دسته بندی ها زده که حتی در مواردی اون کوئری تکراری هست.اگه دقت کنین تو این مورد خاص 45 کوئری به دیتابیس زده شده (همه کوئری ها به خاطر دسته بندی نیست فقط میخام مقایسه کنم).من دسته بندی هر پست رو تقریبا همه جای سایت لازم دارم پس با اضافه کردن متغیر$withبه مدل پستEagerloadرو برای دسته بندی هر پست به صورت خودکار فعال میکنم. https://gist.github.com/amir9480/d2b3719f53b0d04a9053a0e789d6e308#file-post-php خب حالا دوباره همون صفحه رو باز میکنم تا مقایسه انجام بدم. این بار یک بار برای همیشه به جدول دسته بندی ها کوئری میزنه و در همه ی پست ها دسته بندی ها از قبل لود شدن و همچنین از 45 کوئری به 26 کوئری رسوندیمش اما لزوما این روش همیشه بهینه نیست.هر پست چند کامنت داره و هر کامنت برای یه پست هست پس رابطه بین شون یک به چند هست.اگه ایگر لود برای کامنت ها به این شکل انجام بدیم هر پست کلی کامنت داره و همشون باهم لود بشن تو این صفحه ازشون هیچ استفاده ای نمیشه و فقط الکی حافظه رو پر میکنن.اینطوری نه تنها سرعت رو بهتر نمیکنیم بلکه قهوه ای ترش هم میکنیم.برای کامنت به جای این روش داخل کنترل نمایش پست تکی که کامنت ها داخل باید نمایش داده بشنEagerload رو انجام میدم.BlogPost::where(&#039;slug&#039;, $value)-&gt;firstOrFail()حالا اگه به جای کد بالاBlogPost::where(&#039;slug&#039;, $value)-&gt;with(&#039;comments&#039;)-&gt;firstOrFail()بنویسم تغییری در تعداد کوئری ها نمیبینم چون وقتی کامنت ها رو داخل حلقه میندازم در هر صورت یه بار کوئری میخوره و با ایگر لود هم بازم یه بار کوئری میخوره اما یه فرقی دارناگه شما نتیجه کارتون رو کش کنین بعد کش دیگه برای کامنت کوئری زده نمیشه ولی اگه eagerloadرو انجام ندین حتی بعد کش کردن یک بار کامنت ها کوئری میخورن.حالا هر کامنت یه تعداد جواب داره و هر جواب خودش یه کامنت هست. پس کامنت با خودش رابطه یک به چند داره. برای اینکه ماeagerloadرو برای جواب کامنت ها از طریق پست انجام بدیم اینکارو میکنیم.BlogPost::where(&#039;slug&#039;, $value)-&gt;with(&#039;comments.replies&#039;)-&gt;firstOrFail();خب کوئری ها کاهش پیدا کرد اما تو سایت من ممکنه جواب ها چند سطحی باشن یعنی ممکنه یه جواب خودش یه جواب دیگه داشته باشه و ... این کار رو انجام میدمBlogPost::where(&#039;slug&#039;, $value)-&gt;with(&#039;comments.replies.replies.replies.replies&#039;)-&gt;firstOrFail();اینم نتیجه ولی خب انصافا 133 کوئری کجا و 33 کوئری کجا.Eagerloadمثل شمشیر دولبه س.میتونه پرفورمنس رو از قهوه ای به طلایی برسونه یا میتونه قهوه ای رو قهوه ای تر کنه!قابلیت مهم بعدی که میخام بهتون درباره ش بگم مدیریت ایونت ها هستش که به نظرم راحت ترین روش مدیریت ایونت مدل های لاراول استفاده از Observerهست.خب این ایونت چی هست و چیکار میکنه.خیلی ساده بخام بگم این یعنی به لاراول میگین مثلا این مدل من اگه ازش یدونه ساخته شد این کار رو واسم انجام بدهاگه مقادیر داخلش به روز رسانی شد اون کار رو انجام بدهاگه هم این مدلم حذف شدش فلان کار رو انجام بده. و ....حالا میخام یه مثال بزنم که در مورد همین کامنت هست.اول اینکه میخایم IP کسی که کامنت رو میفرسته ذخیره کنیم.دوم اینکه میخایم وقتی کامنت حذف شد جواب هایی که برای اون کامنت بودن هم حذف بشه.برای مثال من https://gist.github.com/amir9480/71bd3e4f48a403eb2abe4f9605326a09 و برای ثبت این Observerدر تابع bootدر کلاسapp/Providers/EventServiceProvider.phpاین خط کد رو اضافه میکنم.BlogComment::observe(BlogCommentObserver::class);حالا دیگه لازم نیست هر جایی که کامنت اضافه میکنم هر بار آی پی کاربر رو خودم دستی همونجا مقدار بدم یا وقتی کامنت رو حذف میکنم دیگه دستی برای حذفش جواب ها دوباره کد اضافه بنویسم. کارهای عادی رو انجام میدم و اینا هم خودشون کارهای لازم رو انجام میدن برام.اماGlobal scopeقابلیت باحالیه که بهتون اجازه میده هر وقت به مدلتون کوئری میزنین یه چیزی به کوئری اضافه کنهمثلا میتونین قابلیت بذارین در قسمت پست ها همیشه بر اساس تاریخ ساخته شدن مرتب بشن و دیگه فرقی نمیکنه شما کجا از مدلتون استفاده کنین. همیشه بر اساس تاریخ مرتبشون میکنه حالا برای مثال کامنت ها همیشه از من قابلیتی میخان که کامنت ها توسط ادمین ها تایید بشن بعد تو سایت نمایش داده بشن.این کار به راحتی توسط global scopeقابل انجام هست و دیگه نیاز نگران سوتی دادن یه جایی باشین و از دستتون در بره. مثلا اگه جواب های یه کامنت رو براش شرط نذارین کامنت های تایید نشده هم بالا میاد اما باglobal scopeخیالتون از همه جهت راحته. https://gist.github.com/amir9480/246ed40d4c5e0110d5aa751d41ff86c3#file-blogpost-php خب حالا همیشه هر جا کوئری بزنین خودش یه -&gt;where(&#039;confirmed&#039;, 1)بهش اضافه میکنه.  خب حالا این جا یه مشکلی پیش میاد و اونم اینه که ما برای اینکه به ادمین اجازه بدیم کامنت های تایید نشده رو ببینه و بتونه تایید کنه.کافیه دقیقا فقط قسمت هایی که میخایم استثنا باشن رو باwithoutGlobalScopeبراش استثنا مشخص کنیم.BlogComment::withoutGlobalScope(&#039;confirmed&#039;)-&gt;paginate();قابلیت بعدی که میخام باهاتون در میون بذارمcastکردن هستفرض کنین میخایم تو کامنت ها به مقدارconfirmedدسترسی داشته باشیم.در حالت عادی مقدارش به شکل 0 , 1 هست.اما درست ترش اینه که یه بولین باشه برای با اضافه کردن متغیر$castsبه مدلمون هست https://gist.github.com/amir9480/0269df40e3c4733e387c4aa709bfc6f0#file-blogpost-php حالا از این به بعد confirmedخودش خود به خود تبدیل به بولین میشه و دو مقدار true, falseهمراه خودش دارهشاید بگین این که درد خاصی از من دوا نمیکنه شاید راست بگین اما خفن ترین تبدیل نوعی که میتونه انجام بده تبدیل آرایه هست.برای تبدیل آرایه باید نکاتی رو درنظر بگیرین.آیا اون آرایه ای که میخاین ذخیره بشه سرچ کردن/ مرتب کردن بر اساسش اهمیت داره یا نه و دوم اینکه تعدادشون خیلی زیاد هست یا نه.اگه سرچ براتون مهم نیست و تعدادشون هم اونقدرها زیاد نیست پس به جای ساخت یه مدل اضافه و شلوغ کردن کد از این قابلیت خفن استفاده کنین.بیشترین جایی که از این قابلیت استفاده کردم ساخت گالری عکس بوده.فرض کنین برای هر پست یه تعداد عکس داریم.اول کست رو به مدل پست اضافه میکنیم.protected $casts = [
 &#039;images&#039; =&gt; &#039;array&#039;
 ];و بعد جایی که داریم ذخیره میکنیم یه آرایه بهش میدیم.$post-&gt;images = [&#039;image1.png&#039;, &#039;image2.jpg&#039;];و به همین راحتی ما قابلیت ذخیره کردن یه آرایه تو دیتابیس رو بدون درد کشیدن داریم!قابلیت بعدی که میخام باهاتو در میون بذارمAccessor هست. این قابلیت بهتون اجازه میده یه تعداد فیلد اضافه کنین به مدلتون بدون اینکه نیاز باشه تو دیتابیس دستکاری کنین.  بیشترین جایی که از این قابلیت استفاده کردم ذخیره لینک هر چیزی داخلش بوده.یکی از رو اعصاب ترین کارایی که معمولا در کد اطرافیانم میبینم استفاده از route همه جا هست.{{ route(&#039;test&#039;, [&#039;post&#039; =&gt; $post-&gt;slug]) }}یا مثلا همه جا برای دسترسی به لینک فایل آپلود شده دستی آدرس رو بهش اضافه میکنن.همه جا هی کپی کپی کپی . ? https://gist.github.com/amir9480/494b19b5cb0fce3604b28adfd425f643#file-blogpost-php حالا برای دسترسی به لینک و آدرس عکسی کافیه به این شکل عمل کنیم.{{ $post-&gt;link }}{{ $post-&gt;image_link }}بهترین مزیتی که داره اینه که اگه یه روزی مجبور بشین لینک یا آدرس عکس رو عوض کنین دیگه لازم نیست برید تک تک جاهایی که کدتون رو کپی کردین دونه به دونه تغییر بدین و دهنتون آسفالت شه. آینده نگری و DRY که میگن از همین چیزای کوچیک شروع میشه. بازم اگه عمر و انگیزه ای بود وصیت های بی خاصیت بیشتری رو باهاتون در میون میذارم. https://virgool.io/@amiralizadeh9480/%DA%86%DB%8C-%D8%B4%D8%AF-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3-%D8%B4%D8%AF%D9%85-kpsescdv5rci  https://virgool.io/@amiralizadeh9480/%D8%B3%D8%A7%D8%AE%D8%AA-%D9%81%D8%B1%D9%85-%D8%AA%D9%85%D8%A7%D8%B3-%D8%A8%D8%A7-%D9%85%D8%A7-%D8%B3%D8%A7%D8%AF%D9%87-%D8%AF%D8%B1-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-nlkf9yro0a0c  https://virgool.io/@amiralizadeh9480/%D8%A7%D9%81%D8%B2%D9%88%D9%86%D9%87-%D9%85%D9%86-%D8%A8%D8%B1%D8%A7%DB%8C-vscode-%D9%88-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-mw9bcpvidbrd </description>
                <category>&lt;amir&gt;</category>
                <author>&lt;amir&gt;</author>
                <pubDate>Mon, 20 May 2019 23:35:44 +0430</pubDate>
            </item>
                    <item>
                <title>چی شد برنامه نویس شدم</title>
                <link>https://virgool.io/@amiralizadeh9480/%DA%86%DB%8C-%D8%B4%D8%AF-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3-%D8%B4%D8%AF%D9%85-kpsescdv5rci</link>
                <description>حدود پنج ساله پیش به برنامه نویسی علاقه مند شدم و حدود یه سال و خورده ای حرفه ای وب کار میکنم و خب خیلی زمان گذشته اما تاجایی که هر چیزی یادم باشه رو مینویسم. از شما هم دعوت میکنم داستان خودتون رو بنویسین.بخش اول غیر برنامه نویسی:شدیدا پیشنهاد میکنم اگه حوصله ندارین خاطرات بچگی منو بخونین مستقیم برین بخش دو رو بخونین?یادم میاد بچه که بودم حدودا 6 سالم بود حدودای سال 82 بابام برام یه میکرو کیبورد دار خریده بود یه چیزی شبیه ایناین به تلویزیون وصل میشد و بازی میکردم. خیلی ذوق کرده بودم.از اونجا که ما مستاجر بودیم تو اسباب کشی این گم شد و هیچوقت هم دیگه پیدا نشد.بعد اون یه دوستی داشتم که چند باری منو به خونش دعوت کرد و با کامپیوترش GTA vice cityبازی میکردیم کلا شاید سه چهار بار بازی کردم ولی خیلی محو این بازی شده بودم.یادمه این دوستم علاقه خاصی به قایق سواری داشت و برای دزدیدن قایق روی یه پلی تو شهر وایمیستاد و از روی پل میپرید روی قایق ها و مشکل اصلی اینجا بود همونطور که میدونین تو این بازی اگه میافتادین توی آب میمردین! و من با خودم فکر میکردم چرا کسی که بازی رو ساخته نتونسته کاری کنه که توی آب بتونیم شنا کنیم! ( اولین جرقه ها بوده ها ?)از اون دوره مدت ها گذشت و حدودای 10 سالگیم با گیم نت آشنا شدم و علاقه عجیبی به گیم نت رفتن پیدا کردم و بازی های مورد علاقه مGTA san andreasو Counter StrikeوNFS Undergroundبودن! ( میدونم مناسب سن من نبودن اما اینجا ایرانه ?)تو این دوره ها یه گوشی K310 سونی اریکسون هم داشتم که توش بازی های مثل Cannonball 8000وRally Mastersخیلی بازی میکردم. و ......حالا شاید براتون سوال پیش بیاد این چرت و پرت هایی که دارم میگم چه ربطی به علاقه مند شدن من به برنامه نویسی داره. میگم براتون...بخش دوم علاقه مندی به برنامه نویسی:حدودای 14 سالگی این ایده به ذهنم رسید چرا من خودم یه بازی نسازم. مثلا بشینم جی تی ای بسازم خیلی خوبه ( میدونم آدم ابله و خیال پردازی بودم ?) اون موقع هنوز کامپیوتر نداشتم ولی با گوشیم سرچ کردم ببینم چجوری میشه یه بازی ساخت. خیلی زیاد جاهای مختلف رو گشتم و با پدیده ای به نام یونیتی آشنا شدم.فکر میکردم GTA san andreas رو هم با همین ساختن. گفتم پس منم حتما میتونم یکی بسازم. گشتم ببینم چجوری میشه بازی رو از صفر تا صد ساخت. تو این وسطا بین مدل سازی و تکسچرینگ و اینا اولین بار با واژه برنامه نویسی آشنا شدم. اینطوری برداشتم کردم برنامه نویسی یعنی مثلا برای اینکه به CJ بگی برو اون مرد رو بکش باید براش کد بنویسی و بهش دستور بدی! برای مدل سازی و اینا متوجه شدم مدل آماده زیاد موجوده و من لازم نیست براشون زحمت بکشم (و من غافل از اینکه باید ریگ و انیمیشن هم انجام بدم و مدل خالی کافی نیست) و اینجوری بود که به برنامه نویسی علاقه مند شدم.با بابام قرار گذاشتم اگه خوب درس بخونم و معدلم بالا شه برام یه کامپیوتر بخره و معدله بالا شد! :).بخش سوم کد:تو 15 سالگی بلاخره به آرزوم رسیدم یه کامپیوتر! تابستون همون سال شروع کردم. با تحقیقاتم متوجه شدم یونیتی با C# , Javascript , Boo کار میکنه و من فقط لازمه یکیشون رو یاد بگیرم با سرچ کردن تو گوگل یه جایی خوندم سی شارپ بهترینشونه منم رفتم دنبالش. دنبال جزوه های مختلفی میگشتم اما چیز خوبی تو اینترنت برای سی شارپ نتونستم پیدا کنم (یادم نیست چرا نتونسته بودم) تحقیق کردم و متوجه شدم C++ اگه یاد بگیرم C# هم میتونم یاد بگیرم و اینا شبیه همدیگه هستن (???) کتاب جعفر نژاد قمی رو پیدا کردم و شروع کردم به خوندنش( یکی از بزرگترین اشتباهات و حماقت های زندگیم). تابستون گذشت و من نتونستم اون قدری که باید از این کتاب لعنتی یاد بگیرم و بازی ساختن رو شروع کنم. پس گشتم دنبال راه حل غیر برنامه نویسی با یه پکیج یونیتی به نام Play makerآشنا شدم که بدون کد زدن باهاش میتونستم بازی بسازم. باهاش یه چیزایی انجام دادم اما به این نتیجه رسیدم این اون قدرها هم دست آدم رو باز نمیذاره.پس سعی کردم راه حل دیگه ای پیدا کنم که همون موقع ها با UDKآشنا شدم.Unreal Engine 3مجانی که ابزاری به اسم Kismet داشت.همین بهانه من شد برای شروع یادگیری این انجین و اولین باری بود که متوجه شدم انجینی به جز یونیتی هم هست و چون نمونه های آماده و بازی های ساخته شده باهاش خیلی ظاهر قشنگی داشتن من فکر میکردمGTA IVبا این ساخته شده !گفتم من که قراره GTA بسازم پس بذار یه خفن ترش رو بسازم! (???)بعد دانلود و چند روز ور رفتن با این لعنتی عملا هیچ کار خاصی نتونستم انجام بدم بس که سخت بود برام و کم آوردم. همون موقع ها به این نتیجه رسیدم بهتره به جای یادگیریUScriptبرگردم به همون سی پلاس پلاس.اولین تصمیم دور ریختن کتاب جعفر نژاد قمی و گشتن دنبال یه کتاب دیگه بود که با کتاب دیتیل آشنا شدم.اگرچه ترجمه فارسی این کتاب خیلی روون نبود اما با هزار بد بختی و بعد حدودا شش ماه تونستم سی پلاس پلاس رو در حد کار راه بنداز یاد بگیرم. اونجا نقطه شروع بود برای یونیتی. طی گذر زمان فهمیده بودم ساخت GTA اونقدرا هم ساده نیست پس سطح توقعم پایین تر اومده بود. یه آموزش ساخت بازی شوتر اول شخصبا یونیتی فارسی پیدا کرده بودم با کمک همون تونستم کمی سینتکس سی شارپ رو یاد بگیرم و در کنارش هم بازی پیاده سازی کنم. ساخت اولین بازی و کد نوشتن براش مثل روز برام قضیه رو روشن کرد که بازی ساختن کار یه نفر نیست و باید تیم داشته باشی و ...همچنین در کنار این ها تصمیم گرفته بودم سعی کنم یه انجین خودم بسازم تا تجربه ش کنم و خب چیزایی مثل Direct3D 9 و OpenGL 3.3رو این وسط تا حدودی در حد مکعب زدن و جابه جایی دوربین و نور و اینا کار کردم و خب باعث شد بفهمم به گرافیک کار کردن خیلی علاقه دارم با اینکه ریاضیات خیلی توش دخیله و منم از ریاضیات فراری! (خیلی خلاصه گفتم حوصله تون سر نره!).من برنامه نویسی رو یاد گرفته بودم اما خب دیگه 17 سالم بود و پسرا تو این سن خیلی به فکر این هستن از لحاظ مالی از پدرشون مستقل شن. به خصوص اینکه بابای من از اینکه من هر روز زمان زیادی رو با کامپیوتر میگذروندم و نمراتم توی مدرسه چندان جالب نبودن خیلی از دستم ناراحت بود.من کد میزدم اما خب میومد بهم میگفت &quot;خجالت نمیکشی یکسره داری بازی میکنی جای اینکارو پاشو برو یه کم درس بخون&quot;.اونجا اولین جرقه های پول در آوردن از برنامه نویسی به سرم زد. بعد یه مدت تحقیق به این نتیجه رسیدم پول تو وبه و منم باید برم این سمت.بخش چهارم در جستجوی پول: من PHPرو انتخاب کردم چون میدونستم هاست های ارزون یا حتی مجانی میشه براش پیدا کرد بر خلاف سایر تکنولوژی ها مثل asp.net .میدونستم برای اینکه بتونم کار پیدا کنم باید نمونه کار داشته باشم. پس دنبال یه ایده خوب گشتم برای پیاده سازی. اون اوایل برای استارت زدن از نصب کردن وردپرس روی هاست های مجانی شروع کردم و علاقه به وبلاگ نویسی هم داشتم. واسه وردپرس یادگرفتن دلیلم این بود که سرویس هایی مثل رز بلاگ و بلاگفا تبلیغ توی وبلاگم میذاشتن و من از این موضوع خوشم نمیومد پس بهانه ای  شد برای وبلاگ نویسی و نصب وردپرس.بعد یه مدت متوجه شدم وبلاگم بازدیدی نداره و تحقیق کردم درباره راه های افزایش بازدید سایت که این مابین با این سایت آشنا شدم. https://www.traffboost.net/ خودش بود! ایده ای که در به در دنبالش میگشتم.این سایت این شکلی کار میکنه که شما میری توش سایت دیگران رو بازدید میکنی و امتیاز جمع میکنی برای خودت. با امتیاز جمع شده میتونی سایتت رو توی لیست قرار بدی دیگران بیان سایتت رو ببینن و در ازاش تو امتیاز هایی که جمع کردی رو بدی به اونا.این عکس رو امروز گرفتم اون موقع ظاهرش خیلی داغون بود!تصمیم به شروع یادگیری چیزایی مثل PHP/HTML/CSS/JS کردم که این سایته رو با امکاناتی بیشتر مثل لایک کردن سایت ها و کامنت گذاشتن واسشون بزنم.بعد یه مدت نسخه ابتدایی سایت با PHP خام و بدون هیچ فریمورک بک اندی آماده شد.آپلودش کردم و اون موقع تلگرام گروه های 200 نفره زده بود و منم تصمیم گرفتم در مورد سایتم نظر بپرسم توی یه گروه برنامه نویسی (شاید یه اشتباه بزرگ جلوتر میگم چرا) . یکی از اون وسط پیدا شد و کاری کرد که سایت دیتابیسش پر شه از کاربرای فیک و هاست مجانی سایت من رو حذف کنه و من حسابی از این قضیه ناراحت شدم که چرا اینقدر باید امنیت سایتم پایین باشه. توی اون گروه تلگرام هم هر کی نظر داد میگفت این سایت چرته و بیخوده و ... و کلا من رو قهوه ای کردن!این همه زحمت کشیده بودم برای ساختش و حس داغونی داشتم که هیچکس با اولین سایت کدنویسی شده توسط من حال نکرده.حالا چرا اشتباهم بزرگ بود چون متوجه شدم یه سایتی دقیقا مشابه این سایت ساخته شده در صورتی که من قبلش کل اینترنت چرخیده بودم  و سایت های افزایش ترافیک ایرانی همشون اتوماتیک کار میکردن و خودشون کلیک میکردن و ...  و سایت ایرانی لنگه این وجود نداشت اما سایتی رو دیدم که دقیقا مشابهشه و حتی آیکون ها رو هم از این سایته کپی کرده! یه جورایی حدس میزنم این ایده از همون گروه تلگرام در رفت! (شایدم توهمی بیش نیست) http://www.traffiset.ir/ این ماجرا هم گذشت و من تصمیم گرفتم تواناییم تو امنیت رو افزایش بدم که این مابین با فریمورک ها آشنا شدم.فریمورک PHP زیاد بود و من بین دو تا کله گنده یعنی YIIو Laravelشک داشتم که تصمیم گرفتم لاراول رو انتخاب کنم.با اینکه میدونستم ایده ام دیگه خاص نیست اما تصمیم گرفتم اولین سایتی که با لاراول پیاده سازی میکنم دوباره همین سایته باشه.تو این دوران تصمیم گرفتم یه نسخه از کدم رو نگه دارم تا برام خاطره بشه.هر وقت هم مغرور شدم برگشتم و اون کد ها رو دیدم و گفتم منم روزگاری یه احمق بودم!واقعا هم بودم هر موقع کد هاش رو نگاه میکنم میگم برنامه نویس این عجب احمقی بوده! https://github.com/amir9480/Traffic-booster اگر چه یه بار دیگه هم خواستم این ایده رو پیاده سازی کنم اما خب دیگه میدونستم این قضیه به سرمایه گذاری و تبلیغات احتیاج داره و کلا بی خیالش شدم.بخش پنجم استخدام:تخته های اتو, تخته های موج سواری هستن که رویاهاشون رو کنار گذاشتن و شغل برای خودشون پیدا کردن قسمت تلخ داستان اینجاست... من شهر آمل زندگی میکنم. اینجا شهر نسبتا کوچیکیه و کار برنامه نویسی خیلی کم پیدا میشه. به سختی یه جایی کار پیدا کردم که من رو قبول کنه.  یه تیم شش نفره کوچیک بودیم و ایده استارتاپمون هم تو حوزه ویلا و اینا بود دو ماه اول رو مفت کار کردم ( خر حمالی ) و برنامه نویسی که زیر دستش بودم چیزای جدید زیادی بهم یاد نداد و بعدش هم حدود یه سال دیگه هم براش سایت خودش و مشتریاش رو میزدم.بعد مدتی به خاطر حقوق خیلی کم ( سه روز در هفته در ازای ماهی 500 تومن! و بعد یه سال یه ذره هم اضافه نشد) از اونجا اومدم بیرون. الان هم تو سن 21 سالگی جای دیگه ای هستم یه تیم حدودا 15 نفره ایم و هنوز هم حقوق پایین (سه روز در هفته در ازای ماهی 800 تومن) همچنان &quot;خرحمالی(برده داری عصر مدرن)&quot; ولی خب اموراتم میگذره. قدم بعدیم رو وقتی که دانشگاهم ( که به اصرار پدرم درس میخونم ) تموم شه برای رویای یه برنامه نویس بازی(گرافیک) شدن دنبال خواهم کرد یا حتی شاید خدا اونقدری عمر/شرایطش رو بهم نده که دیگه بتونم این رویا رو دنبال کنم.?مرسی از اینکه این نوشته رو خوندین.نوشت های مشابه دوستان ویرگولی: https://virgool.io/@mostafa_salehi/%D9%85%D8%B5%D8%B7%D9%81%DB%8C-%D8%B5%D8%A7%D9%84%D8%AD%DB%8C-%D9%BE%D9%88%D8%B1-%D8%AF%D8%A7%D8%B3%D8%AA%D8%A7%D9%86-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3-%D8%B4%D8%AF%D9%86%D9%85-puinxzuotglc  https://virgool.io/@mdisefr/%D8%B9%D9%84%D8%A7%D9%82%D9%87-%D9%85%D9%86%D8%AF-%D8%B4%D8%AF%D9%86-%D9%85%D9%86-%D8%A8%D9%87-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3%DB%8C%D9%82%D8%B3%D9%85%D8%AA%DB%B1-rolqejrndewf  https://virgool.io/@fflanyy/%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3%DB%8C-%D9%85%D9%86-%D9%82%D8%B3%D9%85%D8%AA-%D8%A7%D9%88%D9%84-otyyidfpoilq </description>
                <category>&lt;amir&gt;</category>
                <author>&lt;amir&gt;</author>
                <pubDate>Thu, 21 Feb 2019 14:25:02 +0330</pubDate>
            </item>
                    <item>
                <title>ساخت فرم تماس با ما ساده در لاراول</title>
                <link>https://virgool.io/laravel-community/%D8%B3%D8%A7%D8%AE%D8%AA-%D9%81%D8%B1%D9%85-%D8%AA%D9%85%D8%A7%D8%B3-%D8%A8%D8%A7-%D9%85%D8%A7-%D8%B3%D8%A7%D8%AF%D9%87-%D8%AF%D8%B1-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-nlkf9yro0a0c</link>
                <description>میتونم بگم تقریبا هر مشتری میاد چنین قابلیتی رو از سایتش انتظار داره(حتی با اینکه اکثرا هیچوقت کاربری ازش استفاده نمیکنه :)  ) ولی خب چه کنیم مشتریه دیگه میگه بزنیم ما هم میزنیم.اما من میخام اینجا بنویسم روتین من برای ساخت فرم تماس با ما چیه.هدف: ساخت یه فرم تماس با ما که نام و شماره تماس و متن از کاربر میگیره و ذخیره میکنه و برای صاحب وبسایت ایمیل میفرسته.برای شروع یه مدل میسازم.php artisan make:model Message -mدر میگریشن ایجاد شده سه تا ستون اضافه میکنم برای نام, شماره تماس و متن پیام.Schema::create(&#039;messages&#039;, function (Blueprint $table) {
     $table-&gt;increments(&#039;id&#039;);
     $table-&gt;string(&#039;name&#039;);
     $table-&gt;string(&#039;phone&#039;);
     $table-&gt;text(&#039;message&#039;);
     $table-&gt;timestamps();
 });و متغیر $fillable رو برای مدل مینویسم.protected $fillable = [
     &#039;name&#039;,
     &#039;phone&#039;,
     &#039;message&#039;
 ];کنترلر لازم رو هم ایجاد میکنمphp artisan make:controller ContactControllerداخلش دو تا متد به نام show و sendمیسازم و تابع show رو به این شکل مینویسم.public function show()
 {
     return view(&quot;index&quot;);
 }و روت هاش رو هم تعریف میکنم.Route::get(&#039;/&#039;, &#039;ContactController@show&#039;)-&gt;name(&quot;contact.show&quot;);
Route::post(&#039;/send&#039;, &#039;ContactController@send&#039;)-&gt;name(&quot;contact.send&quot;);یه view جدید به نام index حاضر میکنم که داخلش یه فرم قرار داره. https://gist.github.com/amir9480/3d44b19cff050971a7d2f835fc2698e3 سشنsuccessرو برای ارسالflash messageاز کنترلر استفاده میکنم.برای نوشتن متد ارسال اول یه Requestمیسازم.php artisan make:request ContactRequestو rules رو به این شکل مینویسم.return [
    &#039;name&#039; =&gt; &#039;required|string|max:60&#039;,
    &#039;phone&#039; =&gt; &#039;required|string|max:20&#039;,
    &#039;message&#039; =&gt; &#039;required|string&#039;
];همچنین attributes رو هم برای دو phone و message داخل کلاس تعریف میکنم. public function attributes()
 {
     return [
         &#039;phone&#039; =&gt; &#039;شماره تماس&#039;,
         &#039;message&#039; =&gt; &#039;پیام&#039;,
     ];
 }و در نهایت داخل کنترلر send رو به این شکل تعریف میکنم.public function send(ContactRequest $request)
 {
     Message::create($request-&gt;all());
     return redirect()-&gt;back()-&gt;with([&#039;success&#039; =&gt; &#039;پیام شما با موفقیت ارسال شد.&#039;]);
 }تا این جای قسمت ذخیره کردن پیام ها رو زدیم که شما میتونین سمت ادمین سایت لیست پیام ها رو به صاحب وبسایت نشون بدین.ولی خب ما میخاهیم برای صاحب وبسایت ایمیل ارسال بشه که آقا برات پیام اومده.برای شروع اول یه پکیج به پروژه م اضافه میکنم که بتونم ایمیل هایی که ارسال میشه رو مشاهده کنم. https://github.com/themsaid/laravel-mail-preview/ حتما بخونین چجوری کار میکنه.composer require themsaid/laravel-mail-previewبعد نصب این دستور رو وارد میکنم که کانفیگ درست بشه.php artisan vendor:publish --provider=&quot;Themsaid\MailPreview\MailPreviewServiceProvider&quot;و داخل فایل .env مقدار MAIL_DRIVER رو تغییر میدم.MAIL_DRIVER=preview برای شروع ایمیل زدن یهmailجدید میسازم.php artisan make:mail Contact --markdown=emails.contactو کلاس رو به این شکل تغییر میدم. https://gist.github.com/amir9480/2c306785978bf85e02dbc878999a6e38 و ویو emails/contact رو به این شکل تغییر میدم.@component(&#039;mail::message&#039;)
# پیام فرم تماس با ما
این ایمیل به صورت خودکار ارسال شده است.

## مشخصات فرستنده
### نام : {{ $name }}
### شماره تماس : {{ $phone }}

@component(&#039;mail::panel&#039;)
 {{ $message }}
@endcomponent

{{ config(&#039;app.name&#039;) }}
@endcomponentبرای ادامه داخل فولدر configیه فایل جدید به نامcontact.phpمیسازم و به این شکل مینویسمششما میتونین از همون app.php استفاده کنین فرقی نداره.&lt;?php
return [
    &#039;email&#039; =&gt; env(&#039;CONTACT_EMAIL&#039;)
];و داخل فایل .env این رو اضافه میکنم.CONTACT_EMAIL=test@gmail.comبه جای این ایمیل بعدا ایمیل مشتریتون رو بنویسین.و در نهایت متد ارسال کنترلرم رو به این شکل اصلاح میکنم.public function send(ContactRequest $request)
 {
     Mail::to(config(&quot;contact.email&quot;))
         -&gt;send(new Contact(Message::create($request-&gt;all())));
     return redirect()-&gt;back()-&gt;with([&#039;success&#039; =&gt; &#039;پیام شما با موفقیت ارسال شد.&#039;]);
 }حالا بعد اینکه فرم رو ارسال کنید پکیجی که اضافه کردیم یه لینک بهتون نمایش داده میشه.در پایان من از اسپمر ها خوشم نمیاد.مشتری هم از اسپمر ها خوشش نمیاد.شما چطور؟با کمک Recaptcha سعی میکنم تا جای ممکن اسپم واسه مشتری فرستاده نشه.اول پکیج Recaptcha گوگل رو اضافه میکنم. https://github.com/google/recaptcha composer require google/recaptchaفایل کانفیگم رو به این شکل تغییر میدم.&lt;?php

return [
    &#039;email&#039; =&gt; env(&#039;CONTACT_EMAIL&#039;),
    &#039;recaptcha&#039; =&gt; [
        &#039;site&#039; =&gt; env(&#039;RECAPTCHA_SITE&#039;),
        &#039;secret&#039; =&gt; env(&#039;RECAPTCHA_SECRET&#039;),
    ]
];و این ها رو به فایل .env اضافه میکنم.RECAPTCHA_SITE=
RECAPTCHA_SECRET=باید توی سایت https://www.google.com/recaptcha سایت خودتون رو ثبت کنید.و مقادیر Site Key و Secret Keyجلوی اینا قرار بدین.بعد داخلapp/Providers/AppServiceProviderاین خطوط رو اضافه میکنم تا ولیدیتور برای Recaptchaساخته شه.use ReCaptcha\ReCaptcha;
use Illuminate\Support\Facades\Validator;
.
.public function boot()
 {
 Validator::extendImplicit(&#039;recaptcha&#039;, function ($attribute, $value, $parameters, $validator) {
 $recaptcha = new ReCaptcha(config(&quot;contact.recaptcha.secret&quot;));
 $response = $recaptcha-&gt;verify($value, request()-&gt;ip());
 if ($response-&gt;isSuccess()) {
 return true;
 }
 return false;
 });
 }و داخل فایل translations  validation.php این خط رو اضافه میکنم.&#039;recaptcha&#039; =&gt; &#039;لطفا بر روی گزینه من یک ربات نیستم کلیک کنید.&#039;,این خط کد رو به rules داخل کلاس Requestکه نوشته بودم اضافه میکنم.&#039;g-recaptcha-response&#039; =&gt; &#039;recaptcha&#039;و در نهایت داخل viewاین خط کد رو به انتهای فرمم اضافه میکنم.&lt;div class=&quot;g-recaptcha&quot; data-sitekey=&quot;{{ config(&#039;contact.recaptcha.site&#039;) }}&quot;&gt;&lt;/div&gt;و این فایل جاوا اسکریپت رو هم اضافه میکنم.&lt;script src=&quot;https://www.google.com/recaptcha/api.js?hl=fa&quot;&gt;&lt;/script&gt;و نتیجه کار بعد اینکه کاربر گزینه من یک ربات نیستم رو کلیک نکرد ولی پیام فرستاد.سورس کد هم اینجا در دسترس هست.https://github.com/amir9480/laravel-contact-form-sampleسایر نوشته هام. https://virgool.io/@amiralizadeh9480/%D8%B3%D8%A7%D8%AE%D8%AA-%DA%A9%D9%88%D8%AA%D8%A7%D9%87-%DA%A9%D9%86%D9%86%D8%AF%D9%87-%D9%84%DB%8C%D9%86%DA%A9-%D8%A8%D8%A7-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-vcrlsheusa5f  https://virgool.io/Software/%D8%B3%D8%A7%D8%AE%D8%AA-crud-%D8%A8%D8%A7-%D9%84%D8%A7%D8%B1%D9%88%D8%A7%D9%84-%D9%88-vue-oa3s5ageyafv  https://virgool.io/JavaScript8/%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-%D9%81%D8%A7%DB%8C%D9%84-%D9%87%D8%A7%DB%8C-%D8%AA%D8%B1%D8%AC%D9%85%D9%87-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-%D8%AF%D8%B1-%D8%AC%D8%A7%D9%88%D8%A7-%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-mxxpowoydz0z </description>
                <category>&lt;amir&gt;</category>
                <author>&lt;amir&gt;</author>
                <pubDate>Fri, 18 Jan 2019 12:48:33 +0330</pubDate>
            </item>
                    <item>
                <title>افزونه من برای VSCode و لاراول</title>
                <link>https://virgool.io/laravel-community/%D8%A7%D9%81%D8%B2%D9%88%D9%86%D9%87-%D9%85%D9%86-%D8%A8%D8%B1%D8%A7%DB%8C-vscode-%D9%88-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-mw9bcpvidbrd</link>
                <description>من بیشتر از یک ساله که از مریدان VSCode شدم و بعد از گذشتن از سرزمین هایPHPStormEclipseNetbeansAtomرسیدم به VSCode و هنوزم اینجا هستم!اما ایده افزونه زدن از کجا اومد.من اخیرا تو شرکتی استخدام شدم و برنامه نویس ها رو می دیدم که همشون PHPStormدارن.تا اینجای کار که مشکلی نبود , مشکل از جایی شروع شد که اینا گیر دادن به من چرا من ساز مخالف میزنم و پاشم برم رو PHPStorm ولی خب من زیر بار نمیرم :). برای اینکه من رو قانع کنن چند تا قابلیت هاش رو بهم نشون دادن منم عین همون قابلیت (حالا چه با افزونه چه بدون افزونه) بهشون نشون دادماما یکی از قابلیت های PHPStormرو نشونم دادن که برای اسمRouteها Autocompleteداشت. و VSCode هم نداشت و این قضیه رو زدن تو سر من . زیر بار نرفتم ادیتورم رو عوض کنم به جاش نشستم تایپ اسکریپت یاد گرفتم و بعدش هم افزونه نویسی برای VSCode و سعی کردم این قضیه رو تو VSCodeپیاده سازی کنم.این اولین افزونه من برای VSCode هست و خیلی جالب نشده ولی همون کار رو انجام میده.علاوه بر این قابلیت Autocompleteبرای view هاهم پیاده سازی کردمتصمیم گرفتم این افزونه رو به اشتراک بذارم. اسمش رو یه چیز ساده انتخاب کردم Laravel Extra Intellisenseنام روتپارامتر های روتویو هااین افزونه در کنار یه سری افزونه های قدرتمند دیگه VSCode رو برای برنامه نویس لاراول تبدیل به بهشت میکنه.من یه تعداد از افزونه هایی که مربوط به لاراول میشن و خودم هر روز باهاشون سر و کار دارم رو اینجا مینویسمPHP IntelephensePHPCSPHP DocBlockerPHP formatterLaravel Blade SnippetsLaravel goto viewLaravel goto controllerلینک دانلود افزونه ساخت خودم:Laravel Extra Intellisensehttps://github.com/amir9480/vscode-laravel-extra-intellisenseاگه شما هم افزونه فوق العاده ای تو VSCodeمیشناسین یا خودتون ساختین معرفی کنین.</description>
                <category>&lt;amir&gt;</category>
                <author>&lt;amir&gt;</author>
                <pubDate>Tue, 08 Jan 2019 23:43:44 +0330</pubDate>
            </item>
                    <item>
                <title>استفاده از فایل های ترجمه لاراول در جاوا اسکریپت</title>
                <link>https://virgool.io/JavaScript8/%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-%D9%81%D8%A7%DB%8C%D9%84-%D9%87%D8%A7%DB%8C-%D8%AA%D8%B1%D8%AC%D9%85%D9%87-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-%D8%AF%D8%B1-%D8%AC%D8%A7%D9%88%D8%A7-%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-mxxpowoydz0z</link>
                <description>اگه براتون سوال شده چجوری توی فایل های جاوا اسکریپت از قابلیت translation لاراول بهره ببرید، این نوشته رو واسه شما (هرچند نه چندان خوب) مینویسم. این کد جاوا اسکریپت قراره فقط ترجمه های ساده رو انجام بده و همه ی امکانات رو نداره (مثل Pluralization) ولی کار من یکی باهاش راه میفته.در نهایت هم میگم چجوری میتونین توی vue js از ترجمه ها استفاده کنین.اول از همه یه پروژه جدید حاضر میکنم و قابلیت چند زبانه شدن رو با استفاده از آدرس دهی فراهم میکنم به این شکلhttp://test/fa/helloنسخه فارسی سایتhttp://test/en/helloنسخه انگلیسی سایتاین قابلیت رو به کمک یه میدل ویر پیاده سازی میکنم.اول از همه یه فایل کانفیگ ایجاد میکنم و اسمش رو میذارم translation.php و لیست زبان های قابل پشتیبانی در سایت رو توی اون مینویسم&lt;?php
return [
 &#039;locales&#039; =&gt; [&#039;fa&#039; =&gt; &#039;فارسی&#039;,
 &#039;en&#039; =&gt; &#039;English&#039;
 ],
];و میدل ویر مورد نظر رو مینویسم.&lt;?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\App;

class SetLocale
{
 public function handle($request, Closure $next)
 {
 $locale = $request-&gt;segment(1);
 if (in_array($locale, array_keys(config(&#039;translation.locales&#039;)))) {
 App::setLocale($locale);
 }
 return $next($request);
 }
}بعد میدل ویر رو توی گروپ web توی Kernel.php اضافه میکنم.&#039;web&#039; =&gt; [
...
\App\Http\Middleware\SetLocale::class,
]یه کنترلر جدید میسازم و اسمش رو مثلا میزارم IndexControllerو یه متد indexبهش اضافه میکنم به این شکلclass IndexController extends Controller
{
 public function index()
 {
 return view(&#039;home&#039;);
 }
}و روت هام رو هم به این شکل تعریف میکنم.Route::redirect(&#039;/&#039;, &#039;/&#039;.config(&quot;app.locale&quot;));
foreach (array_keys(config(&#039;translation.locales&#039;)) as $loc) {
 Route::prefix($loc)-&gt;name($loc.&quot;.&quot;)-&gt;group(function () {
 Route::get(&#039;/&#039;, &#039;IndexController@index&#039;);
 });
}نکته در مورد روت: اگه چنانچه زبانی اضافه کردین یا حذف کردین وقتی که روت ها کش شده هستش. باید از اول کش رو انجام بدین.یه گروه جدید ترنسلیشن ایجاد میکنم و مثلا اسمش رو میذارم  home.این مقدار ها رو داخلش قرار میدم.برای فارسی (resources/lang/fa/home.php):&lt;?php

return [
 &#039;laravel_is_awesome&#039; =&gt; &#039;لاراول فوق العادس&#039;,
 &#039;make_something&#039; =&gt; &#039;یه چیز :param بساز&#039;,
 &#039;awesome&#039; =&gt; &#039;فوق العاده&#039;,
];برای انگلیسی (resources/lang/en/home.php):&lt;?php

return [
 &#039;laravel_is_awesome&#039; =&gt; &#039;Laravel is awesome&#039;,
 &#039;make_something&#039; =&gt; &#039;Make something :param&#039;,
 &#039;awesome&#039; =&gt; &#039;awesome&#039;,
];و در نهایت ویو home رو این شکلی مینویسم.&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;{{ App::getLocale() }}&quot;&gt;
&lt;head&gt;
 &lt;meta charset=&quot;UTF-8&quot;&gt;
 &lt;title&gt;Test&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
 &lt;h1&gt;@lang(&#039;home.laravel_is_awesome&#039;)&lt;/h1&gt;
 &lt;h3&gt;@lang(&#039;home.make_something&#039;, [&#039;param&#039; =&gt; trans(&quot;home.awesome&quot;)])&lt;/h3&gt;
&lt;/body&gt;
&lt;/html&gt;اینم از نتیجه کار تا اینجا.خب حالا میرم سراغ اصل مطلب. من میخوام همین رو به صورت یه alert  و توی جاوا اسکریپت نمایش بدم.برای شروع یه روت میسازم که انگار شبیه یه فایل جاواسکریپت هست.Route::redirect(&#039;/&#039;, &#039;/&#039;.config(&quot;app.locale&quot;));
foreach (array_keys(config(&#039;translation.locales&#039;)) as $loc) {
 Route::prefix($loc)-&gt;name($loc.&quot;.&quot;)-&gt;group(function () {
 Route::get(&#039;/&#039;, &#039;IndexController@index&#039;);
 Route::get(&#039;generated-asset.js&#039;, &#039;IndexController@generatedAsset&#039;)-&gt;name(&#039;generated_asset&#039;);// روت جدید
 });
}تابع generatedAsset لازمه که یه آبجکت جاوا اسکریپت ایجاد کنه که ما بتونیم از طریق پارامتری که داریم مقدار مورد نظرمون رو پیدا کنیم و نمایش بدیم.برای شروع نیاز داریم گروه های ترجمه ها رو بشناسیم برای این کار من یه مقدار جدید توی کانفیگ translation ایجاد میکنم به این شکل.&#039;groups&#039; =&gt; [
 &#039;auth&#039;,
 &#039;pagination&#039;,
 &#039;passwords&#039;,
 &#039;validation&#039;,
 &#039;home&#039;
 ]این آرایه مشخص میکنه برامون کدوم گروه ها قابل دسترس باشن در جاوا اسکریپت.کنترلر رو به این شکل مینویسم.public function generatedAsset()
 {
 $groups = [];
 foreach (config(&#039;translation.groups&#039;) as $group) {
 $groups[$group] = trans($group);
 }
 return response()
 -&gt;view(&quot;generated_asset&quot;, compact(&quot;groups&quot;))
 -&gt;header(&quot;Content-Type&quot;, &quot;text/javascript&quot;);
 }حالا ویو generated_asset رو به این شکل مینویسم.var ___jtrans = @json($groups);خب حالا باید یه همچین چیزی داشته باشیم.حالا میخام یه تابع بهش اضافه کنم که شبیه trans خود لاراول عمل کنه.پس ویو رو به این شکل کامل ترش میکنم.var ___jtrans = @json($groups);

function jtrans(key, parameters)
{
    if (parameters === undefined) {
        parameters = {};
    }
    var out = __jtransHelper(key, parameters, ___jtrans, &#039;&#039;);
    for(var parameter in parameters){
        out = out.replace(new RegExp(&quot;\:&quot;+parameter), parameters[parameter]);
    }
    return out;
}

function __jtransHelper(key, parameters, __data, previous_key)
{
    var key_array = key.split(&quot;.&quot;);
    var this_group = key_array[0];
    key_array = key_array.splice(1, key_array.length-1);
    var searchingKey = key_array.join(&#039;.&#039;);
    if( typeof __data[this_group] !== &#039;undefined&#039; ) {
        if(searchingKey.length&gt;0){
            return __jtransHelper(searchingKey, parameters, __data[this_group], previous_key+(previous_key.length&gt;0?&#039;.&#039;:&#039;&#039;)+this_group);
        } else {
            return __data[this_group];
        }
    }
    return previous_key+&#039;.&#039;+this_group;
}خب حالا برای تست کردن میخام یه کار کنم طرف وقتی روی هر کدوم از جملات توی صفحه اصلی کلیک کرد همون توی یه alert نشون داده بشه. فایل جاوا اسکریپت جدا نمیسازم فقط میخام تست کنم ولی در اصل هدف ساخت همچین چیزی اینه که توی کد جاوا اسکریپت به شکل جدا استفاده کرد.این خطوط کد رو به کد ویو صفحه اصلی اضافه میکنم.&lt;script src=&quot;{{ route(App::getLocale().&#039;.generated_asset&#039;) }}&quot;&gt;&lt;/script&gt;
 &lt;script&gt;
 document.querySelector(&quot;h1&quot;).addEventListener(&quot;click&quot;, function(){
 alert(jtrans(&quot;home.laravel_is_awesome&quot;));
        });
 document.querySelector(&quot;h3&quot;).addEventListener(&quot;click&quot;, function(){
 alert(jtrans(&quot;home.make_something&quot;, {&#039;param&#039;: jtrans(&quot;home.awesome&quot;)}));
        });
 &lt;/script&gt;حتما آدرس فایل ترجمه رو قبل از آدرس فایل های اختصاصیتون قرار بدین.حالا روی هر کدوم از متن ها کلیک کنین شاهد نمایش ترجمه اون به صورت آلرت خواهید بود!استفاده از ترجمه های لاراول در Vueبه نظرم ویو خیلی خفنه! حالا میخام چیزی که تا اینجا ساختیم رو توی یه کامپوننت Vue استفاده کنم برای اینکار یه پلاگین خیلی ساده میسازم و ازش استفاده میکنم پس لازمه از قبل بدونین چه شکلی واسه ویو میشه پلاگین ساخت و استفاده کرد.اول یه فایل js ایجاد میکنم و مثلا اسمش رو میذارم LaravelTranslation.js و محتویات زیر رو درونش مینویسم.var LaravelTranslation = {};
LaravelTranslation.install = function (Vue, options) {
 Vue.prototype.jtrans = jtrans;
 Vue.filter(&quot;trans&quot;, jtrans);
};
export default LaravelTranslation;من دو سینتکس مختلف رو برای استفاده داخل template vue آماده کردم.اول:{{ &quot;home.laravel_is_awesome&quot;|trans }}این روش استفاده از فیلتر هست و  به نظرم جذابه!  و روش دوم:{{ jtrans(&quot;home.laravel_is_awesome&quot;) }}اینم با استفاده از متد البته متد حتما باید باشه شاید یه جای دیگه توی کد هاتون به جز template بهش احتیاج داشته باشین.برای ادامه توی app.js این پلاگین رو به Vue اضافه میکنم.import Vue from &#039;vue&#039;;
import LaravelTranslation from &#039;./LaravelTranslation&#039;;

Vue.use(LaravelTranslation);
Vue.component(&#039;example-component&#039;, require(&#039;./components/ExampleComponent.vue&#039;));
const app = new Vue({
 el: &#039;#app&#039;
});و حالا کامپوننت ExampleComponent این شکلی اصلاح میکنم.&lt;template&gt;
 &lt;div&gt;
 &lt;h2&gt;Example Component&lt;/h2&gt;
        {{ jtrans(&quot;home.laravel_is_awesome&quot;) }}&lt;br&gt;
        {{ jtrans(&quot;home.make_something&quot;, {&#039;param&#039;: jtrans(&quot;home.awesome&quot;)}) }}&lt;br&gt;
 &lt;br&gt;&lt;br&gt;
        Using filters:&lt;br&gt;
        {{ &quot;home.laravel_is_awesome&quot;|trans }}&lt;br&gt;
        {{ &quot;home.make_something&quot;|trans({&#039;param&#039;: jtrans(&quot;home.awesome&quot;)}) }}&lt;br&gt;
 &lt;br&gt;&lt;br&gt;&lt;br&gt;
 &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
 export default {
 
    }
&lt;/script&gt;و در نهایت آدرس فایل اسکریپت رو بعد کامپایل با mix به صفحه اصلی اضافه میکنم.&lt;script src=&quot;/js/app.js&quot;&gt;&lt;/script&gt;و داخل صفحه ی اصلی این کد رو اضافه میکنم.&lt;div id=&quot;app&quot;&gt;
 &lt;example-component&gt;&lt;/example-component&gt;
 &lt;/div&gt;و اینم نتیجه کارسورس کد هم اینجاست: https://github.com/amir9480/laravel-js-localization-exampleحرف آخر : روز خوبی داشته باشین. :) https://virgool.io/@amiralizadeh9480/%D8%B3%D8%A7%D8%AE%D8%AA-%D9%81%D8%B1%D9%85-%D8%AA%D9%85%D8%A7%D8%B3-%D8%A8%D8%A7-%D9%85%D8%A7-%D8%B3%D8%A7%D8%AF%D9%87-%D8%AF%D8%B1-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-nlkf9yro0a0c  https://virgool.io/@amiralizadeh9480/%D8%B3%D8%A7%D8%AE%D8%AA-%DA%A9%D9%88%D8%AA%D8%A7%D9%87-%DA%A9%D9%86%D9%86%D8%AF%D9%87-%D9%84%DB%8C%D9%86%DA%A9-%D8%A8%D8%A7-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-vcrlsheusa5f  https://virgool.io/Software/%D8%B3%D8%A7%D8%AE%D8%AA-crud-%D8%A8%D8%A7-%D9%84%D8%A7%D8%B1%D9%88%D8%A7%D9%84-%D9%88-vue-oa3s5ageyafv </description>
                <category>&lt;amir&gt;</category>
                <author>&lt;amir&gt;</author>
                <pubDate>Fri, 14 Sep 2018 14:24:31 +0430</pubDate>
            </item>
                    <item>
                <title>ساخت یه CRUD با Laravel و Vue</title>
                <link>https://virgool.io/Software/%D8%B3%D8%A7%D8%AE%D8%AA-crud-%D8%A8%D8%A7-%D9%84%D8%A7%D8%B1%D9%88%D8%A7%D9%84-%D9%88-vue-oa3s5ageyafv</link>
                <description>Create | Read | Update | Deleteجز اون چیزایی که همه برنامه نویسا مجبورن باهاش سر و کله بزنن. اکثر قسمت های پنل ادمین یه وبسایت همیناس. من این جا میخام نشونتون بدم خودم چطوری یه CRUDSPAدرست میکنمخب اول از همه چیز لاراول رو نصب میکنم  و همچنین php artisan make:authبرای اینکه میخام فقط کاربرها بتونن به صفحه مورد نظر دسترسی داشته باشن بعد محتویات فایل .env رو مطابق نیازم دستکاری میکنم و میگریت رو انجام میدمبعد داخل پوشه ساخته شده بساط لاراول میکس رو فراهم میکنمnpm installاگه npm بلد نیستید یا نصب ندارید حتما نصب کنید و یاد بگیرین :)خب برای اینکه آدرس دهی داشته باشیم توی این کراد باید vue-router گرامی رو نصب کنیم.npm install vue-routerو خب من چون خیلی آدم خسته ایم و همچنین از طراحی و این داستانا کلا هیچی حالیم نیست و همه از ذائقه غیر هنریم انتقاد میکنن من میرم و یه قالب آماده تهیه میکنم برای پنل که به نظرم این یکی خیلی تمیز و ساده س.برای شروع اول یه روت آماده میکنم برای نمایش پنل ادمین. من برای جلوگیری از شلوغ شدن web.phpیه فایل دیگه میسازم توی routes مثلا به اسم admin.php و روت های مربوط به پنل ادمین رو اونجا قرار میدم. شما میتونین به همون روش عادی توی web.php روت ها رو تعریف کنین اجباری در کار نیست برای معرفی کردنش به لاراول هم فایل app/Providers/RouteServiceProvider.php رو باید ادیت کنمتوی تابع mapWebRoutesاین خط کد رو اضافه میکنمRoute::middleware([&#039;web&#039;, &#039;auth&#039;])
 -&gt;prefix(&#039;admin&#039;)
 -&gt;name(&#039;admin.&#039;)
 -&gt;namespace($this-&gt;namespace.&#039;\\Admin&#039;)
 -&gt;group(base_path(&#039;routes/admin.php&#039;));این خط میاد به اول اسم همه روت ها admin. اضافه میکنه. تمام آدرس های توی admin.php با admin شروع میشن. همشون میدلویر دارن برای جلوگیری از دسترسی کاربر وارد نشده به سایت(بعدا یه کار کنین فقط ادمین بیاد ) دارن و البته تمام کنترلر های مربوط به ادمین رو توی پوشه Admin میسازم تا با بقیه قاطی پاطی نشه.  ( باز هم تکرار میکنم این روش منه اجباری در کار نیست )خب حالا یه کنترلر میسازم برای نمایش داشبوردphp artisan make:controller Admin\DashboardController کد های مورد نیاز رو توی public و view حاضر میکنم اسمش رو هم میذارمmaster.blade.phpتابع نمایش داشبورد رو توی کنترلر مینویسمpublic function dashboard()
 {
 return view(&#039;admin.master&#039;);
 }و فایل روت admin.php رو این شکلی مینویسمRoute::get(&#039;/&#039;, &#039;DashboardController@dashboard&#039;)-&gt;name(&#039;dashboard&#039;);و درنهایت سایت رو بازمیکنم و یه اکانت برای خودم میسازم و آدرس پایین رو بازمیکنمlocalhost/adminاگه تا اینجای کار یه کم گیج شدین نگران نباشین انتهای مطلب سورس کد رو گذاشتم کد همه چیز رو میگه :) فقط کافیه بدونین blade چه شکلی کار میکنه.خب من حالا میخام نوشتن اولین کامپونت Vue رو با این قسمت Card که وسط صفحه میبینین که CRUD Example نوشته و action داره شروع کنم و تبدیلش کنم به یه کامپنونت تا ازش استفاده کنماول فایل webpack.mix.js رو یکم ادیت میکنم تا محل خروجی فایل رو عوض کنمmix.js(&#039;resources/assets/js/app.js&#039;, &#039;public/asset/admin/js&#039;)
   .sass(&#039;resources/assets/sass/app.scss&#039;, &#039;public/asset/admin/css&#039;);و بعد کامند لاراول میکس رو اجرا میکنم تا خروجی ها رو ببینم که توی public/asset هستش و همچنین آدرس ها رو اضافه میکنم به view&lt;link rel=&amp;quotstylesheet&amp;quot href=&amp;quot{{ mix(&amp;quotasset/admin/css/app.css&amp;quot) }}&amp;quot&gt;&lt;script src=&amp;quot{{ mix(&amp;quotasset/admin/js/app.js&amp;quot) }}&amp;quot&gt;برای پشتیبانی از csrf این کد رو به داخل head اضافه میکنم&lt;meta name=&amp;quotcsrf-token&amp;quot content=&amp;quot{{ csrf_token() }}&amp;quot&gt; و وقتشه همه چیز رو بیارم توی میکس. اول از همه فایل های boostrap و jquery رو حذف میکنم از داخل قالب چون اونا توی app.css , app.js به صورت پیش فرض موجود هستن. همچنین اسکریپت های مربوط به چارت ها رو هم پاک میکنم چون توی این برنامه بهشون احتیاجی ندارم. میمونه یه فایل metismenu که باید بگردید روی npm و پکیجش رو پیدا کنین یا با mix به فایل app.js اضافه ش کنین که خب طی یه پرس و جو از عمو گوگل این پکیج رو روی npm یافتم و نصبش کردمnpm install metismenuبعد تست مجدد متوجه شدم که این قالب از بوت استرپ سه استفاده میکرده و ما بهش داریم چهار رو میدیم و قیافه سایت شبیه مگس شده ! بنابراین بوت استرپ رو میبریمش به نسخه سهnpm install bootstrap@^3.*و فایل app.scss رو به این شکل اصلاح میکنم// Bootstrap
@import &#039;~bootstrap/dist/css/bootstrap.css&#039;;
@import &amp;quot~metismenu/dist/metisMenu.css&amp;quot
@import &#039;../../../public/asset/admin/vendor/font-awesome/css/font-awesome.min.css&#039;;
@import &#039;../../../public/asset/admin/css/sb-admin-2.css&#039;;مطمئن بشین آدرس ها رو درست دادین چون تو لاراول 5.7 ساختار پوشه resource تغییر میکنه و من این برنامه رو با 5.6 نوشتم :)از طرف دیگه ما باید کدهایی که سازنده قالب نوشته رو به کدهای خودمون اضافه کنیم برای این یکی من فایل webpack.mix.js رو دستکاری میکنم mix.js([
 &#039;resources/assets/js/app.js&#039;,
 &#039;public/asset/admin/js/sb-admin-2.js&#039;
], &#039;public/asset/admin/js&#039;)
   .sass(&#039;resources/assets/sass/app.scss&#039;, &#039;public/asset/admin/css&#039;);و در نهایت metisMenu رو به فایل app.js اضافه میکنمrequire(&#039;./bootstrap&#039;);
require(&#039;metismenu&#039;);در انتها یه div به body اضافه کنین و تمام کدهای body رو توی اون بنویسین تا vue.js بتونیم استفاده کنیم البته میتونیم el رو برابر #wrapper بذاریم ولی من ترجیح میدم المنت جدید بسازم&lt;div id=&amp;quotapp&amp;quot&gt;
کدهای قالب
&lt;/div&gt;حالا با خروجی گرفتن و تنها دو فایل app.css | app.js باید بتونین همون صفحه رو مشاهده کنین.خب حالا از جاده خاکی بزنیم توی راه اصلی و اون کامپوننت Card رو بسازیممن فایل جدید نمیسازم و ExampleComponent.vueاسمش رو تغییر میدم به CardComponent.vueو این کدها رو توش مینویسم &lt;template&gt;
 &lt;div class=&amp;quotpanel panel-default&amp;quot&gt;
 &lt;div class=&amp;quotpanel-heading&amp;quot&gt;
 &lt;i class=&amp;quotfa fa-bar-chart-o fa-fw&amp;quot&gt;&lt;/i&gt;{{ title }}
 &lt;div class=&amp;quotpull-right&amp;quot&gt;
 &lt;div class=&amp;quotbtn-group&amp;quot&gt;
 &lt;button type=&amp;quotbutton&amp;quot class=&amp;quotbtn btn-default btn-xs dropdown-toggle&amp;quot data-toggle=&amp;quotdropdown&amp;quot&gt;
                        Actions
 &lt;span class=&amp;quotcaret&amp;quot&gt;&lt;/span&gt;
 &lt;/button&gt;
 &lt;ul class=&amp;quotdropdown-menu pull-right&amp;quot role=&amp;quotmenu&amp;quot&gt;
 &lt;li&gt;&lt;a href=&amp;quot#&amp;quot&gt;Action&lt;/a&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href=&amp;quot#&amp;quot&gt;Another action&lt;/a&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href=&amp;quot#&amp;quot&gt;Something else here&lt;/a&gt;
 &lt;/li&gt;
 &lt;li class=&amp;quotdivider&amp;quot&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href=&amp;quot#&amp;quot&gt;Separated link&lt;/a&gt;
 &lt;/li&gt;
 &lt;/ul&gt;
 &lt;/div&gt;
 &lt;/div&gt;
 &lt;/div&gt;
 &lt;!-- /.panel-heading --&gt;
 &lt;div class=&amp;quotpanel-body&amp;quot&gt;
 &lt;slot&gt;&lt;/slot&gt;
 &lt;/div&gt;
 &lt;!-- /.panel-body --&gt;
 &lt;/div&gt;
&lt;/template&gt;


 export default {
 props: {
 title: {
 type: String,
 default: &amp;quotExample Card&amp;quot
            },
        },
    }
و اون رو توی app.jsثبت میکنمVue.component(&#039;card-component&#039;, require(&#039;./components/CardComponent.vue&#039;));و درنهایت به viewخودم جهت تست این خط رو مینویسم &lt;card-component title=&amp;quotTEST TEST TEST&amp;quot&gt;
                Hello World
 &lt;/card-component&gt;خب من میخام ساخت CRUD برای مدل User رو شروع کنماول یه کنترلر میسازمphp artisan make:controller Admin\UserController --resource --model=Userو روت لازم رو براش مینویسمRoute::resource(&#039;/users&#039;, &#039;UserController&#039;);بعد داخل کنترلر درون توابع  index | create | show | editاین کد رو مینویسمreturn view(&#039;admin.master&#039;);یادتون نره میتونین با ساخت یه trait کدتون رو تمیزتر بنویسین ولی من برای این مثال همین طوری مینویسم چون یه کلاس بیشتر نداریماول از همه کامپونتت صفحه اصلی داشبورد رو مینویسم اسمش رو میذارم DashboardComponent&lt;template&gt;
 &lt;card-component title=&amp;quotTEST TEST TEST&amp;quot&gt;
        Hello World
 &lt;/card-component&gt;
&lt;/template&gt;

export default {
 mounted() {
 document.title = &amp;quotCRUD Example - Dashboard&amp;quot
        }
    }
و خب وقت نوشتن روت ها هستش . اول یه فایل به اسم routes.js درست میکنم. و این محتویات رو توش مینویسم. این ها برای vue-router هستexport default [
    { path: &#039;/admin&#039;, component: require(&amp;quot./components/DashboardComponent.vue&amp;quot), name: &#039;admin.dashboard&#039;}
];و app.js رو برای استفاده از vue-router به این شکل اصلاح میکنمrequire(&#039;./bootstrap&#039;);
require(&#039;metismenu&#039;);

import Vue from &#039;vue&#039;;
import VueRouter from &#039;vue-router&#039;;
import routes from &#039;./routes&#039;;

Vue.use(VueRouter);

const router = new VueRouter({
 mode: &#039;history&#039;,
 routes
});

Vue.component(&#039;card-component&#039;, require(&#039;./components/CardComponent.vue&#039;));

const app = new Vue({
 el: &#039;#app&#039;,
 router
});و توی view خودمون باید تگ مربوطه رو وسط صفحه بنویسیم&lt;router-view&gt;&lt;/router-view&gt;خب همه چی حاضره و اگه localhost/admin رو بازکنین میتونین محتویات DashboardComponent رو ببینین. برای ادامه کار کامپوننت صفحه جدول کاربرا رو میسازم ( crud/users/ListComponent) رو و برای اینکه بتونم لیست کاربرا رو داشته باشم تابع index  UserController رو این شکلی مینویسم.public function index(Request $request)
 {
 if($request-&gt;ajax()) {
 return User::paginate(20);
 }
 return view(&#039;admin.master&#039;);
 }این شکلی کار میکنه که چک میکنه axios درخواست ajax داده پس کلا کاربرا رو بر میگردونه وگرنه داشبورد رو نشون میده.به routes.js این روت رو اضافه میکنم   { path: &#039;/admin/users&#039;, component: require(&amp;quot./components/crud/users/ListComponent.vue&amp;quot), name: &#039;admin.users.index&#039;}و ListComponent رو این شکلی مینویسم&lt;template&gt;
 &lt;card-component title=&amp;quotUsers List&amp;quot&gt;
 &lt;div class=&amp;quottable-responsive&amp;quot&gt;
 &lt;table class=&amp;quottable table-striped table-bordered table-hover&amp;quot&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;#&lt;/th&gt;
 &lt;th&gt;Name&lt;/th&gt;
 &lt;th&gt;Email&lt;/th&gt;
 &lt;th&gt;Created at&lt;/th&gt;
 &lt;th&gt;Last update&lt;/th&gt;
 &lt;th&gt;Actions&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr v-if=&amp;quotusers === null&amp;quot&gt;
 &lt;td colspan=&amp;quot6&amp;quot&gt;
 &lt;h2&gt;Loading...&lt;/h2&gt;
 &lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr v-else-if=&amp;quotusers.data.length &gt; 0&amp;quot v-for=&amp;quotuser in users.data&amp;quot&gt;
 &lt;td&gt;{{ user.id }}&lt;/td&gt;
 &lt;td&gt;{{ user.name }}&lt;/td&gt;
 &lt;td&gt;{{ user.email }}&lt;/td&gt;
 &lt;td&gt;{{ user.created_at }}&lt;/td&gt;
 &lt;td&gt;{{ user.updated_at }}&lt;/td&gt;
 &lt;td&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr v-else&gt;
 &lt;td colspan=&amp;quot6&amp;quot&gt;
 &lt;h3&gt;No Users Exists&lt;/h3&gt;
 &lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;/table&gt;
 &lt;/div&gt;
 &lt;ul v-if=&amp;quotusers != null&amp;quot class=&amp;quotpagination&amp;quot&gt;
 &lt;li v-for=&amp;quotpage in users.last_page&amp;quot :class=&amp;quot{active : users.current_page == page}&amp;quot&gt;&lt;router-link :to=&amp;quot{ name:&#039;admin.users.index&#039;, query: { page } }&amp;quot&gt;{{ page }}&lt;/router-link&gt;&lt;/li&gt;
 &lt;/ul&gt;
 &lt;/card-component&gt;
&lt;/template&gt;


 export default {
 data() {
 return {
 users: null
            }
        },
 mounted() {
  document.title = &amp;quotCRUD Example - users&amp;quot
 this.loadUsers();
        },
 watch: {
 &#039;$route.query&#039;(newValue, oldValue) {
 this.loadUsers();
            }
        },
 methods: {
 loadUsers() {
 var self = this;
 this.user = null;
 axios.get(&amp;quot/admin/users?page=&amp;quot+(this.$route.query.page ? this.$route.query.page : 1))
                .then(function(res){
 self.users = res.data;
                })
                .catch(function(error) {
 alert&#40;&amp;quotOOPS... something went wrong!&amp;quot&#41;;
                });
            }
        },
    }
خب ما سمت چپ قالب یه منو داریم پس دو تا لینک داشبورد و صفحه لیست کاربرا رو بهش اضافه میکنم&lt;li&gt;
 &lt;router-link :to=&amp;quot{name:&#039;admin.dashboard&#039;}&amp;quot&gt;&lt;i class=&amp;quotfa fa-dashboard fa-fw&amp;quot&gt;&lt;/i&gt; Dashboard&lt;/router-link&gt;
 &lt;/li&gt;
 &lt;li&gt;
 &lt;router-link :to=&amp;quot{name:&#039;admin.users.index&#039;}&amp;quot&gt;&lt;i class=&amp;quotfa fa-user fa-fw&amp;quot&gt;&lt;/i&gt; Users&lt;/router-link&gt;
 &lt;/li&gt;خب میخوام یه کار خرکی انجام بدم تاریخ last update رو میخام به سبک چند روز پیش و فلان بنویسم به نظرم اینطوری بهتره. برای شروع اول این تابع رو توی مدل User مینویسمpublic function getLastUpdateAttribute()
 {
 return $this-&gt;updated_at-&gt;diffForHumans();
 }و برای اینکه بتونم توی جاوااسکریپت بهش دسترسی داشته باشم باید $appends رو برای مدل تعریف کنمprotected $appends = [
 &#039;last_update&#039;
 ];و در نهایت در موقع نمایش به جای updated_at این رو مینویسم&lt;td&gt;{{ user.last_update }}&lt;/td&gt;حالا بریم دومین قدم برای CRUD میخام برای هر آیتم قابلیت حذف شدن رو اضافه کنم. اول تابع destroy توی کنترلمون رو آماده میکنمpublic function destroy(User $user)
 {
 $user-&gt;delete();
 return [&#039;success&#039; =&gt; true];
 }و متدی رو به ListComponent اضافه میکنم که کاربر رو میگیره و عملیات حذف رو انجام میده. deleteUser(user) {
 if(confirm&#40;&amp;quotAre you sure you want delete user &#039;&amp;quot+user.name+&amp;quot&#039;?&amp;quot&#41;) {
 var self = this;
 axios.delete(&amp;quot/admin/users/&amp;quot+user.id).then(function(res){
 alert&#40;&amp;quotThe user deleted successfully!&amp;quot&#41;;
                    })
                    .catch(function(error) {
 alert&#40;&amp;quotOOPS... something went wrong!&amp;quot&#41;;
                    }).then(function(){
 self.loadUsers();
                    });
                }
            }و در نهایت توی ستون action دکمه ای رو جهت کلیک برای حذف میذارم&lt;td&gt;
 &lt;button type=&amp;quotbutton&amp;quot class=&amp;quotbtn btn-danger btn-circle&amp;quot @click.prevent=&amp;quotdeleteUser(user)&amp;quot&gt;&lt;i class=&amp;quotfa fa-trash&amp;quot&gt;&lt;/i&gt;&lt;/button&gt;
 &lt;/td&gt;برای ساخت قسمت فرم هم اول یه request میسازم.php artisan make:request Admin\UserRequestداخل متد authorize رو به return true تغییر میدم و rules رو به شکل زیر مینویسمpublic function rules()
 {
 return [
 &#039;name&#039; =&gt; &#039;required|string|max:191&#039;,
 &#039;email&#039; =&gt; &#039;required|email|unique:users,email,&#039;.optional($this-&gt;user)-&gt;id.&#039;|max:191&#039;,
 &#039;password&#039; =&gt; ($this-&gt;isMethod(&amp;quotpost&amp;quot)?&#039;required&#039;:&#039;nullable&#039;).&#039;|string|min:6&#039;,
 ];
 }و این کلاس رو جایگزین میکنم توی ورودی های store و update کنترلرممتد view کنترلرم رو ادیت میکنم برای اینکه بتونم به صورت json  به اطلاعات دسترسی داشته باشمpublic function show(Request $request, User $user)
 {
 if($request-&gt;ajax()) {
 return $user;
 }
 return view(&#039;admin.master&#039;);
 }و store و update رو این شکلی با هم مخلوطشون میکنم که دوباره کاری انجام ندم!public function store(UserRequest $request)
 {
 $user = new User;
 return $this-&gt;update($request, $user);
 } public function update(UserRequest $request, User $user)
 {
 $inputs = $request-&gt;only(&#039;name&#039;, &#039;email&#039;, &#039;password&#039;);
 if(empty($inputs[&#039;password&#039;]))
 unset($inputs[&#039;password&#039;]);
 else
 $inputs[&#039;password&#039;] = bcrypt($inputs[&#039;password&#039;]);
 $user-&gt;fill($inputs);
 $user-&gt;save();
 return [&#039;success&#039; =&gt; true];
 } خب آخرین کامپوننتی که باید بسازم فرمی هست که اطلاعات کاربر رو میفرسته (crud/users/FormComponent) و محتویات زیر رو در اون قرار میدم.&lt;template&gt;
 &lt;card-component :title=&amp;quotpageTitle&amp;quot&gt;
 &lt;router-link :to=&amp;quot{ name:&#039;admin.users.index&#039; }&amp;quot type=&amp;quotbutton&amp;quot class=&amp;quotbtn btn-primary&amp;quot&gt;Back&lt;/router-link&gt;
 &lt;router-link v-if=&amp;quot$route.params &amp;&amp; $route.name == &#039;admin.users.show&#039;&amp;quot :to=&amp;quot{ name:&#039;admin.users.edit&#039;, params:{user_id: $route.params.user_id} }&amp;quot type=&amp;quotbutton&amp;quot class=&amp;quotbtn btn-warning&amp;quot&gt;Edit&lt;/router-link&gt;
 &lt;br&gt;&lt;br&gt;
 &lt;div v-for=&amp;quotformError in formErrors&amp;quot class=&amp;quotalert alert-danger&amp;quot&gt;
            {{ formError }}
 &lt;/div&gt;
 &lt;div v-for=&amp;quotformMessage in formMessages&amp;quot class=&amp;quotalert alert-success&amp;quot&gt;
            {{ formMessage }}
 &lt;/div&gt;
 &lt;form role=&amp;quotform&amp;quot&gt;
 &lt;div class=&amp;quotform-group&amp;quot&gt;
 &lt;label&gt;Name&lt;/label&gt;
 &lt;input type=&amp;quottext&amp;quot v-model=&amp;quotuser.name&amp;quot :readonly=&amp;quot$route.name == &#039;admin.users.show&#039;&amp;quot class=&amp;quotform-control&amp;quot&gt;
 &lt;/div&gt;
 &lt;div class=&amp;quotform-group&amp;quot&gt;
 &lt;label&gt;Email&lt;/label&gt;
 &lt;input type=&amp;quotemail&amp;quot v-model=&amp;quotuser.email&amp;quot :readonly=&amp;quot$route.name == &#039;admin.users.show&#039;&amp;quot class=&amp;quotform-control&amp;quot&gt;
 &lt;/div&gt;
 &lt;div class=&amp;quotform-group&amp;quot :hidden=&amp;quot$route.name == &#039;admin.users.show&#039;&amp;quot&gt;
 &lt;label&gt;Password&lt;/label&gt;
 &lt;input type=&amp;quotpassword&amp;quot v-model=&amp;quotuser.password&amp;quot :readonly=&amp;quot$route.name == &#039;admin.users.show&#039;&amp;quot class=&amp;quotform-control&amp;quot&gt;
 &lt;p class=&amp;quothelp-block&amp;quot v-if=&amp;quot$route.name == &#039;admin.users.edit&#039;&amp;quot&gt;Keep empty to prevent changing password&lt;/p&gt;
 &lt;/div&gt;
 &lt;div class=&amp;quotform-group&amp;quot v-if=&amp;quot$route.name == &#039;admin.users.show&#039;&amp;quot&gt;
 &lt;label&gt;Created at&lt;/label&gt;
 &lt;input type=&amp;quotemail&amp;quot v-model=&amp;quotuser.created_at&amp;quot disabled class=&amp;quotform-control&amp;quot&gt;
 &lt;/div&gt;
 &lt;div class=&amp;quotform-group&amp;quot v-if=&amp;quot$route.name == &#039;admin.users.show&#039;&amp;quot&gt;
 &lt;label&gt;Last update&lt;/label&gt;
 &lt;input type=&amp;quotemail&amp;quot v-model=&amp;quotuser.last_update&amp;quot disabled class=&amp;quotform-control&amp;quot&gt;
 &lt;/div&gt;
 &lt;button v-if=&amp;quot$route.name != &#039;admin.users.show&#039;&amp;quot type=&amp;quotbutton&amp;quot class=&amp;quotbtn btn-default&amp;quot @click.prevent=&amp;quotsubmit&amp;quot :disabled=&amp;quotloading&amp;quot&gt;Submit&lt;/button&gt;
 &lt;/form&gt;
 &lt;/card-component&gt;
&lt;/template&gt;


 export default {
 data() {
 return {
 user: {
 name: &amp;quot&amp;quot,
 email: &amp;quot&amp;quot,
 password: &amp;quot&amp;quot,
 created_at: &amp;quot&amp;quot,
 last_update: &amp;quot&amp;quot
                },
 pageTitle: &amp;quotCreate user&amp;quot,
 formErrors: {},
 formMessages: [],
 loading: true
            }
        },
 mounted() {
 if(this.$route.name == &amp;quotadmin.users.edit&amp;quot) {
 this.pageTitle = &amp;quotEdit user&amp;quot
 this.load();
            } else if(this.$route.name == &amp;quotadmin.users.show&amp;quot) {
 this.pageTitle = &amp;quotShow user&amp;quot
 this.load();
            } else {
 this.loading= false;
            }
 document.title = &amp;quotCRUD Example - &amp;quot+this.pageTitle;
        },
 methods: {
 load() {
 var self = this;
 axios.get(&amp;quot/admin/users/&amp;quot+ this.$route.params.user_id)
                .then(function(res){
 self.user = res.data;
 self.loading = false;
                })
                .catch(function(error){
 alert&#40;&amp;quotOOPS... something went wrong!&amp;quot&#41;;
                });
            },
 submit() {
 var self = this;
 this.loading = true;
 this.formErrors = {};
 var errorHandler = function(error){
 if(error.response &amp;&amp; error.response.status == 422) {
 var formErrors = {};
 for(var i in error.response.data.errors)
 formErrors[i] = error.response.data.errors[i][0];
 self.formErrors = formErrors;
                    } else {
 alert&#40;&amp;quotOOPS... something went wrong!&amp;quot&#41;;
                    }
 self.loading = false;
                };
 if(this.$route.name == &amp;quotadmin.users.create&amp;quot) {
 axios.post(&amp;quot/admin/users&amp;quot, this.user)
                    .then(function(res){
 self.formMessages = [&amp;quotNew user added successfully.&amp;quot];
 setTimeout(function(){
 self.$router.push({name: &amp;quotadmin.users.index&amp;quot});
                        }, 2000);
                    })
                    .catch(errorHandler);
                } else if(this.$route.name == &amp;quotadmin.users.edit&amp;quot) {
 axios.put(&amp;quot/admin/users/&amp;quot+this.$route.params.user_id, this.user)
                    .then(function(res){
 self.formMessages = [&amp;quotThe user updated successfully.&amp;quot];
 setTimeout(function(){
 self.$router.push({name: &amp;quotadmin.users.index&amp;quot});
                        }, 2000);
                    })
                    .catch(errorHandler);
                }

            }
        },
    }
و روت هام رو به routes.js اضافه میکنم   { path: &#039;/admin/users/create&#039;, component: require(&amp;quot./components/crud/users/FormComponent.vue&amp;quot), name: &#039;admin.users.create&#039;},
    { path: &#039;/admin/users/:user_id&#039;, component: require(&amp;quot./components/crud/users/FormComponent.vue&amp;quot), name: &#039;admin.users.show&#039;, props: true},
    { path: &#039;/admin/users/:user_id/edit&#039;, component: require(&amp;quot./components/crud/users/FormComponent.vue&amp;quot), name: &#039;admin.users.edit&#039;, props: true}حالا برای دکمه افزودن یه دکمه بالای کامپوننت لیست میسازم&lt;router-link :to=&amp;quot{ name:&#039;admin.users.create&#039; }&amp;quot type=&amp;quotbutton&amp;quot class=&amp;quotbtn btn-success&amp;quot&gt;Create&lt;/router-link&gt;و همچنین برای دکمه های مشاهده و اصلاح آیتم ها کنار هر آیتم و کنار دکمه حذف قرارشون میدم&lt;router-link type=&amp;quotbutton&amp;quot class=&amp;quotbtn btn-success btn-circle&amp;quot :to=&amp;quot{name:&#039;admin.users.show&#039;, params:{user_id:user.id}}&amp;quot&gt;&lt;i class=&amp;quotfa fa-eye&amp;quot&gt;&lt;/i&gt;&lt;/router-link&gt;
 &lt;router-link type=&amp;quotbutton&amp;quot class=&amp;quotbtn btn-warning btn-circle&amp;quot :to=&amp;quot{name:&#039;admin.users.edit&#039;, params:{user_id:user.id}}&amp;quot&gt;&lt;i class=&amp;quotfa fa-cut&amp;quot&gt;&lt;/i&gt;&lt;/router-link&gt;ListCreateEditShowو خب اینم از CRUD ی که با Laravel , Vue ساخته م و برای اینکه چشماتون درد نیاد و هم کدها رو هلو بپر تو گلو دستتون باشه یه نسخه از این رو روی گیت هاب آپلود میکنم.https://github.com/amir9480/laravel-vue-crud-exampleهمچنین اگه دنبال یه روش سریع برای ساخت پنل ادمین میگردین پکیج من برای لاراول رو نگاهی بندازین. https://github.com/sanjabteam/sanjab تو جنگ با باگ هاتون موفق باشین.سایر نوشته هام: https://virgool.io/@amiralizadeh9480/%D8%B3%D8%A7%D8%AE%D8%AA-%DA%A9%D9%88%D8%AA%D8%A7%D9%87-%DA%A9%D9%86%D9%86%D8%AF%D9%87-%D9%84%DB%8C%D9%86%DA%A9-%D8%A8%D8%A7-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-vcrlsheusa5f  https://virgool.io/@amiralizadeh9480/%D8%B3%D8%A7%D8%AE%D8%AA-%D9%81%D8%B1%D9%85-%D8%AA%D9%85%D8%A7%D8%B3-%D8%A8%D8%A7-%D9%85%D8%A7-%D8%B3%D8%A7%D8%AF%D9%87-%D8%AF%D8%B1-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-nlkf9yro0a0c  https://virgool.io/JavaScript8/%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-%D9%81%D8%A7%DB%8C%D9%84-%D9%87%D8%A7%DB%8C-%D8%AA%D8%B1%D8%AC%D9%85%D9%87-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-%D8%AF%D8%B1-%D8%AC%D8%A7%D9%88%D8%A7-%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-mxxpowoydz0z </description>
                <category>&lt;amir&gt;</category>
                <author>&lt;amir&gt;</author>
                <pubDate>Fri, 31 Aug 2018 21:05:41 +0430</pubDate>
            </item>
                    <item>
                <title>ساخت کوتاه کننده لینک با لاراول</title>
                <link>https://virgool.io/laravel-community/%D8%B3%D8%A7%D8%AE%D8%AA-%DA%A9%D9%88%D8%AA%D8%A7%D9%87-%DA%A9%D9%86%D9%86%D8%AF%D9%87-%D9%84%DB%8C%D9%86%DA%A9-%D8%A8%D8%A7-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-vcrlsheusa5f</link>
                <description> به سرم زده یه سایت ساده کوتاه کننده لینک با لاراول بسازم و نشونتون بدم چجوری میشه انجامش داد و اول کار بگم آموزش نیست و احتیاجه از قبل با لاراول آشنا باشین .به نظرم کوتاه کننده لینک ساده ترین وبسایتیه که میشه نوشت،یه جورایی HelloWorldحساب میاد!میخوام فقط یه صفحه بسازم لینک بهش میدی و کوتاه شدش رو تحویلت میده و وقتی لینک کوتاه شده باز میشه میره توهمون صفحه ای که باید بره . لاراول رو نصب میکنم و فایل .env روبرای دسترسی به دیتابیس اصلاح میکنم ومدل ومیگریشن وکنترلررو با آرتیسن میسازم.php artisan make:model Link -m -cپوشه Auth توی کنترلرها و مدلUser ودوتامیگریشن مربوط به کاربرها و ریست پسورد رو هم پاک میکنم چون بهشون احتیاجی ندارم.میگریشن لینکها رو این شکلی مینویسم. Schema::create(&#039;links&#039;, function (Blueprint $table) {
 $table-&gt;bigIncrements(&#039;id&#039;);
 $table-&gt;string(&quot;slug&quot;)-&gt;index()-&gt;nullable(); // لینک کوتاه شده
 $table-&gt;text(&quot;url&quot;);// لینک اصلی
 });و میگریت رو انجام میدم.php artisan migrateخب حالا وقتشه مدل رو آماده کنم.class Link extends Model
{
 public $timestamps = false;
 protected $fillable = [
 &#039;slug&#039;,
 &#039;url&#039;
 ];
}خب توی کنترلم اول یه متد مینویسم که صفحه اصلی رو که شامل فرم کوتاه کننده لینک هستش نشونمون بده.public function show(Request $request)
 {
 return view(&#039;home&#039;);
 }یه View جدید هم حاضر میکنم اسمش رو میذارم home.blade.php .بعد توی web.php روت اصلی رو اصلاح میکنم.Route::get(&#039;/&#039;, &#039;LinkController@show&#039;);حالا میرم سراغ آماده کردن home.blade.php و فرم رو حاضر میکنم.&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;

&lt;head&gt;
 &lt;meta charset=&quot;UTF-8&quot;&gt;
 &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
 &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;ie=edge&quot;&gt;
 &lt;title&gt;کوتاه کننده لینک&lt;/title&gt;

 &lt;link rel=&quot;stylesheet&quot; href=&quot;https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css&quot; integrity=&quot;sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u&quot;
 crossorigin=&quot;anonymous&quot;&gt;
 &lt;link rel=&quot;stylesheet&quot; href=&quot;https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css&quot; integrity=&quot;sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp&quot;
 crossorigin=&quot;anonymous&quot;&gt;
&lt;/head&gt;

&lt;body&gt;
 &lt;div class=&quot;container&quot;&gt;
 &lt;div class=&quot;row&quot;&gt;
 &lt;div class=&quot;col-xs-offset-3 col-xs-6&quot;&gt; 
  &lt;h2 class=&quot;text-right&quot;&gt;کوتاه کننده لینک&lt;/h2&gt; 
 &lt;form&gt;
 &lt;input type=&quot;url&quot; id=&quot;link&quot; class=&quot;form-control&quot; placeholder=&quot;لینک آدرس&quot; required autofocus&gt;
 &lt;br&gt;
 &lt;button class=&quot;btn btn-lg btn-primary btn-block&quot; type=&quot;button&quot;&gt;کوتاه کن&lt;/button&gt;
 &lt;/form&gt;
 &lt;/div&gt;
 &lt;/div&gt;
 &lt;/div&gt;

 &lt;script src=&quot;https://code.jquery.com/jquery-3.3.1.min.js&quot;&gt;&lt;/script&gt;
 &lt;script src=&quot;https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js&quot; integrity=&quot;sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa&quot;
 crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;
&lt;/body&gt;

&lt;/html&gt;
و خب حالا باید یه چیزی بنویسم که بتونم با ajax jqueryبهش وصل شم و درخواست لینک کوتاه شده بدم.قبل از هر چیزی من باید به یه روشی مقدار slugرو پر کنم که هم خیلی کوتاه باشه و هم منحصر به فرد که بعدا کاربری لینک کوتاه شده رو باز کرد اشتباهی جایی نره. پس اول یه تابع مینویسم که آی دی مدل لینک رو بگیره و بر اساس اون یه رشته خیلی کوتاه و منحصر به فرد تحویلم بده.protected function generateSlug($id)
 {
 $id-=1; // چون آی دی ها از یک شروع میشن و رشته ها از صفر یه دونه ازش کم میکنم
 $alpha = &quot;abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789-_&quot;;
 $alphaLen = strlen($alpha);
 $out = &quot;&quot;;
 while($id &gt; 0) { // تبدیل مبنا از عدد به مبنای من در آوردی
 $out.= $alpha[$id%$alphaLen]; // یه دونه از کاراکتر ها رو میگیرم
 $id = intval($id/$alphaLen); // آی دی رو تقسیم میکنم برای گرفتن المنت بعدی
 }
 return $out;
 }معیارم بر اساس alpha خواهد بود. اگه بعدا هر گونه دستکاری توی alpha انجام بدم همه چی به طور کل خراب میشه . به نظرم همینی که هست خوبه!خب حالا وقت به کار انداختن تابع تولید لینک کوتاه هستش.public function requestLink(Request $request)
 {
 // اول ولیدیشن رو انجام میدم
 $this-&gt;validate($request, [ 
 &#039;url&#039; =&gt; &#039;required|url&#039;
 ]);
 // اگه لینک از قبل وجود داشت میگیرم یا یه دونه جدیدش رو میسازم
 $link = Link::where(&#039;url&#039;, $request-&gt;input(&#039;url&#039;))-&gt;firstOrCreate([
 &#039;url&#039; =&gt; $request-&gt;input(&#039;url&#039;)
 ]);
 // مقدار اسلاگ رو بر اساس آیدی تنظیم میکنم مهم نیست از قبل ساخته شده بوده یا نه چون نتیجه بر اساس آی دی هست همیشه همون مقداره
 $link-&gt;slug = $this-&gt;generateSlug($link-&gt;id);
 // سیو میکنم
 $link-&gt;save();
 return [ 
 &#039;slug&#039; =&gt; $link-&gt;slug
 ];
 }و در نهایت به روت هام اضافه ش میکنم.Route::post(&#039;/request-link&#039;, &#039;LinkController@requestLink&#039;)-&gt;name(&quot;request_link&quot;);  حالا وقت نوشتن کد های jquery هست برای کوتاه کردن لینک.&lt;script&gt;
 $(function(){
 $(&quot;form button&quot;).click(function(){
 var button = $(this);
 $(button).prop(&#039;disabled&#039;, true);//  دکمه رو تا زمان دریافت نتیجه غیرفعال میشه
 $(&quot;form .alert&quot;).remove();
 $.ajax({
 url: @json(route(&quot;request_link&quot;)),
 method: &quot;POST&quot;,
 headers: {
 &#039;X-CSRF-TOKEN&#039;: @json(csrf_token())
                    },
 data: $(&quot;form&quot;).serialize(),
 success: function(response) {
 //  اسلاگ رو نمایش میدیم
 $(&quot;form&quot;).prepend(`&lt;div class=&quot;alert alert-success&quot;&gt;
 ${response.slug}
                        &lt;/div&gt;`);
 $(button).prop(&#039;disabled&#039;, false); // دکمه رو فعال میشه
                    },
 error: function(xhr, status, errorThrown) {
 //  ورودی مشکل داره پس ارور ها رو نشون میدیم
 var urlErrors = xhr.responseJSON.errors.url;
 for(var i in urlErrors) {
 $(&quot;form&quot;).prepend(`&lt;div class=&quot;alert alert-danger alert-dismissible&quot;&gt;
                                &lt;a href=&quot;#&quot; class=&quot;close&quot; data-dismiss=&quot;alert&quot; aria-label=&quot;close&quot;&gt;×&lt;/a&gt;
 ${urlErrors[i]}
                            &lt;/div&gt;`);
                        }
 $(button).prop(&#039;disabled&#039;, false); // دکمه رو فعال میشه
                    }
                });
            });
        });
 &lt;/script&gt;خب اینم از این فقط یه چیز دیگه باقی میمونه اونم اینه که به جای این چیز بیخودی یه لینک به جاش به کاربر بدیم که بتونه ازش استفاده کنه.اول متد ریدایرکت کردن رو مینویسم.public function openLink($slug)
 {
 return redirect()-&gt;to(Link::where(&#039;slug&#039;, $slug)-&gt;firstOrFail()-&gt;url);
 }و به روت ها اضافه ش میکنم.Route::get(&#039;/o/{slug}&#039;, &#039;LinkController@openLink&#039;)-&gt;name(&quot;open_link&quot;);و در نهایت  requestLinkرو یه کم اصلاحش میکنم.return [ 
 &#039;slug&#039; =&gt; route(&quot;open_link&quot;, [&#039;slug&#039; =&gt; $link-&gt;slug])
 ];خب اینم از سایت ساده کوتاه کننده لینک و خب چون که توی ویرگول نمیشه کدها رو به خوبی مشاهده کرد من یه نسخه از این رو روی گیت هاب آپلود میکنم که بتونین اونجا مشاهده کنینhttps://github.com/amir9480/laravel-url-shortener-sampleسایر نوشته هام: https://virgool.io/@amiralizadeh9480/%D8%B3%D8%A7%D8%AE%D8%AA-%D9%81%D8%B1%D9%85-%D8%AA%D9%85%D8%A7%D8%B3-%D8%A8%D8%A7-%D9%85%D8%A7-%D8%B3%D8%A7%D8%AF%D9%87-%D8%AF%D8%B1-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-nlkf9yro0a0c  https://virgool.io/Software/%D8%B3%D8%A7%D8%AE%D8%AA-crud-%D8%A8%D8%A7-%D9%84%D8%A7%D8%B1%D9%88%D8%A7%D9%84-%D9%88-vue-oa3s5ageyafv  https://virgool.io/JavaScript8/%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-%D9%81%D8%A7%DB%8C%D9%84-%D9%87%D8%A7%DB%8C-%D8%AA%D8%B1%D8%AC%D9%85%D9%87-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-%D8%AF%D8%B1-%D8%AC%D8%A7%D9%88%D8%A7-%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-mxxpowoydz0z </description>
                <category>&lt;amir&gt;</category>
                <author>&lt;amir&gt;</author>
                <pubDate>Wed, 15 Aug 2018 13:01:02 +0430</pubDate>
            </item>
            </channel>
</rss>