در این سؤال، شما باید یک بلاگ خیلی ساده را پیادهسازی کنید.
# جزئیات
پروژهی اولیه را از [این لینک](/contest/assignments/20699/download_problem_initial_project/67891/) دانلود کنید. ساختار فایلهای این پروژه بهصورت زیر است:
```
simple_blog_initial
├── app
│ ├── Console
│ │ └── Kernel.php
│ ├── Exceptions
│ │ └── Handler.php
│ ├── Http
│ │ ├── Controllers
│ │ │ ├── Controller.php
│ │ │ └── PostController.php
│ │ ├── Middleware
│ │ │ ├── Authenticate.php
│ │ │ ├── EncryptCookies.php
│ │ │ ├── PreventRequestsDuringMaintenance.php
│ │ │ ├── RedirectIfAuthenticated.php
│ │ │ ├── TrimStrings.php
│ │ │ ├── TrustHosts.php
│ │ │ ├── TrustProxies.php
│ │ │ └── VerifyCsrfToken.php
│ │ └── Kernel.php
│ ├── Models
│ │ ├── FavoritePost.php
│ │ ├── Post.php
│ │ └── User.php
│ ├── Override
│ │ ├── Connection.php
│ │ └── QueryBuilder.php
│ └── Providers
│ ├── AppServiceProvider.php
│ ├── AuthServiceProvider.php
│ ├── BroadcastServiceProvider.php
│ ├── DatabaseServiceProvider.php
│ ├── EventServiceProvider.php
│ └── RouteServiceProvider.php
├── bootstrap
│ ├── cache
│ │ ├── packages.php
│ │ └── services.php
│ └── app.php
├── config
│ ├── app.php
│ ├── auth.php
│ ├── broadcasting.php
│ ├── cache.php
│ ├── cors.php
│ ├── database.php
│ ├── filesystems.php
│ ├── hashing.php
│ ├── logging.php
│ ├── mail.php
│ ├── queue.php
│ ├── services.php
│ ├── session.php
│ └── view.php
├── database
│ ├── factories
│ │ └── UserFactory.php
│ ├── migrations
│ │ ├── 2014_10_12_000000_create_users_table.php
│ │ ├── 2014_10_12_100000_create_password_resets_table.php
│ │ ├── 2019_08_19_000000_create_failed_jobs_table.php
│ │ ├── 2020_09_27_124807_create_table_posts.php
│ │ └── 2020_09_27_133130_create_table_favorite_posts.php
│ ├── seeders
│ │ └── DatabaseSeeder.php
│ └── database.sqlite
├── public
│ ├── favicon.ico
│ ├── index.php
│ ├── robots.txt
│ └── web.config
├── resources
│ ├── css
│ │ └── app.css
│ ├── js
│ │ ├── app.js
│ │ └── bootstrap.js
│ ├── lang
│ │ └── en
│ │ ├── auth.php
│ │ ├── pagination.php
│ │ ├── passwords.php
│ │ └── validation.php
│ └── views
│ ├── posts
│ │ ├── create.blade.php
│ │ ├── edit.blade.php
│ │ ├── index.blade.php
│ │ └── show.blade.php
│ └── welcome.blade.php
├── routes
│ ├── api.php
│ ├── channels.php
│ ├── console.php
│ └── web.php
├── storage
│ ├── app
│ │ └── public
│ ├── framework
│ │ ├── cache
│ │ │ └── data
│ │ ├── sessions
│ │ ├── testing
│ │ └── views
│ └── logs
├── tests
│ ├── Feature
│ │ ├── BlogSampleTest.php
│ │ ├── BlogTest.php
│ │ └── OrderByCustomTest.php
│ ├── Unit
│ ├── CreatesApplication.php
│ └── TestCase.php
├── README.md
├── artisan
├── composer.json
├── composer.lock
├── package.json
├── phpunit.xml
├── server.php
└── webpack.mix.js
```
<details class="brown">
<summary>راهاندازی پروژه</summary>
**برای اجرای پروژه، باید `php` و `composer` را از قبل نصب کرده باشید.**
+ ابتدا پروژهی اولیه را دانلود و از حالت فشرده خارج کنید.
+ دستور `composer install` را در پوشهی اصلی پروژه برای نصب نیازمندیها اجرا کنید.
</details>
این بلاگ شامل صفحات زیر است:
1. **صفحهی نوشتن یک پست جدید (`/post/create`):** در این صفحه با وارد کردن یک تیتر و متن محتوای یک پست، آن پست ساخته میشود. پس از ساخت پست، کاربر به صفحهی نمایش آن پست هدایت میشود.
2. **صفحهی ویرایش یک پست (`/post/edit/{id}`):** در این صفحه، تیتر و محتوای فعلی پست نمایش داده میشود و قابل ویرایش است. پس از ویرایش، کاربر به صفحهی نمایش آن پست هدایت میشود.
3. **صفحهی نمایش یک پست (`/post/show/{id}`):** در این صفحه، تیتر و محتوای پست نمایش داده میشود.
4. **صفحه لیست تمام پستها (`/posts`):** در این صفحه، تمامی پستها نمایش داده میشوند و با کلیک بر روی تیتر هر پست، کاربر وارد صفحهی نمایش آن پست میشود.
هر پست شامل یک تیتر و یک متن محتوا است.
هر پست پس از نوشته شدن به لیست پستها در صفحه لیست تمام پستها اضافه میشود.
## مدلها
مدلها در پروژهی اولیه داده شده است. همچنین میتوانید با اجرای دستور `php artisan migrate` مایگریشنها را اجرا کنید و پایگاه داده را بهطور کامل داشته باشید. در این پروژه از پایگاه دادهی *SQLite* استفاده شده است. در ادامه، لیست مدلها و توضیحات آمده است:
1. `Post`: مدل پستها که دارای دو فیلد تیتر (`title`) و محتوا (`contents`) است
2. `FavoritePost`: مدل پستهای مورد علاقه که دارای یک فیلد `post_id` است و مشخصکنندهی پستهای موردعلاقه است. با کلیک روی لینک «اضافه به علاقهمندیها»، در صورتی که پست موردنظر از قبل موردعلاقه نباشد، یک ردیف به این جدول اضافه میشود.
شما باید `PostController` و *view*های مربوطه را طوری کامل کنید که عملیات ساخت، ویرایش و نمایش پستها (بهصورت تکی و در لیست) به درستی کار کند.
در صفحهی نمایش یک پست و همچنین صفحه نمایش لیست پستها، برای هر پست دکمهی «اضافه کردن به علاقهمندیها» وجود دارد. در صفحهی لیست پستها، ابتدا پستهایی که به لیست علاقهمندیها اضافه شدهاند بهترتیب زمان اضافه شدن به علاقهمندی نمایش داده میشوند و سپس بقیهی پستها بهترتیب تاریخ ایجاد.
## کنترلرها
متدهای زیر را در کنترلر `PostController` پیادهسازی کنید:
1. `index()`: این متد باید لیست پستها را با ترتیبی که قبلاً ذکر شد با نام `posts` به *view*`posts.index` ارسال کند.
2. `store(Request $request)`: این متد باید یک پست جدید با اطلاعات ورودی (`title` و `contents`) به پایگاه داده اضافه کرده و کاربر را به صفحهی `/post/show/{id}` هدایت کند.
3. `edit($id)`: این متد باید اطلاعات پست با شناسهی `$id` را با نام `post` به *view* `posts.edit` ارسال کند.
4. `update($id, Request $request)`: این متد باید پست با شناسهی `$id` را با اطلاعات ورودی (`title` و `contents`) بهروزرسانی کرده و کاربر را به صفحهی `/post/show/{id}` هدایت کند.
5. `show($id)`: این متد باید اطلاعات پست با شناسهی `$id` را با نام `post` به *view* `posts.show` ارسال کند.
6. `favorite($id)`: این متد باید پست با شناسهی `$id` را به جدول علاقهمندیها اضافه کرده و کاربر را به صفحهی قبلیاش هدایت کند.
برای نمایش پستهای اضافه شده به علاقهمندیها، شما باید در کلاس `\App\Providers\DatabaseServiceProvider` یک *macro* جدید با نام `orderByCustom` به `QueryBuilder` اضافه کنید. این *macro* باید به اینصورت کار کند:
```php
User::orderByCustom('id', 3, 7, 2, 8)->get();
```
کوئری معادل فراخوانی متد بالا:
```sql
select * from "users" order by (case "id" when 3 then 0 when 7 then 1 when 2 then 2 when 8 then 3 else 4 end)
```
همچنین اگر فقط یک آرگومان به این متد داده شود (یا آرگومانهای دوم به بعد خالی باشند)، نباید تغییری در کوئری اعمال شود.
**توجه:** شما تنها مجاز به تغییر فایلهای موجود در پوشهی `/app` هستید.
# آنچه باید آپلود کنید
پس از اعمال تغییرات، کل پروژه به غیر از پوشهی `vendor` را *Zip* کرده و آپلود کنید. نام فایل *Zip* اهمیتی ندارد.
# قسمت آموزشی
در این قسمت راهنماییهای سوال، به مرور اضافه میشود. مشکلاتتان در راستای حل سوال را میتوانید از بخش ["سوال بپرسید"](https://quera.ir/contest/clarification/20699/) مطرح کنید.
<details class="blue">
<summary>راهنمایی ۱</summary>
برای پیادهسازی *macro* `orderByCustom` باید از عملگر `...` استفاده کرد:
```php
Builder::macro('orderByCustom', function ($column, ...$values) {
if (empty($values)) {
return $this;
}
$orderByQuery = '(case "' . $column . '"';
$i = 0;
foreach ($values as $value) {
$orderByQuery .= ' when ' . $value . ' then ' . ($i++);
}
$orderByQuery .= ' else ' . $i . ' end)';
return $this->orderByRaw($orderByQuery);
});
```
</details>
<details class="blue">
<summary>راهنمایی ۲</summary>
در صفحهی لیست پستها، باید ابتدا پستهایی که به علاقهمندیها اضافه شدهاند نمایش داده شوند و سپس سایر پستها. بنابراین، بدنهی متد `index` در کلاس `PostController` بهصورت زیر خواهد بود:
```php
public function index()
{
$favorites = FavoritePost::pluck('post_id')->flatten()->toArray();
$posts = Post::orderByCustom('id', ...$favorites)->orderBy('created_at', 'desc')->get();
return view('posts.index')->with('posts', $posts);
}
```
</details>
ارسال پاسخ برای این سؤال
در حال حاضر شما دسترسی ندارید.