میخواهیم برای یک سایت جستجوی فیلم، سامانهای طراحی کنیم که کاربران بتوانند برای فیلمهای موجود نقد و بررسی بنویسند. کاربران می توانند در هر نقد و بررسی، براساس یک یا چند پارامتر به هر فیلم امتیاز دهند. این پارامترها با توجه به ژانر هر فیلم متغیر میباشد.
مثلا برای یک فیلم از ژانر درام، میتوانیم به هرکدام از پارامترهای زیر امتیاز 1 تا 5 بدهیم.
1. شخصیت پردازی در داستان
2. روند منطقی داستان پردازی
3. پایان بندی قابل قبول
توجه کنید که این پارامترها برای هر ژانر کاملا متفاوت بوده و هر پارامتر نمیتواند برای بیش از یک ژانر در نظر گرفته شود.
هر شخص تنها یک بار میتواند در این نطرسنجی شرکت نماید. در صورتی که شخصی بیش از یکبار درخواست ثبت رای را ارسال کند، سیستم باید پیغام `Duplicate Vote` را به عنوان خروجی برگرداند. برای ذخیره سازی فیلمهای نقد و بررسی شده توسط کاربر میتوانید از کوکی استفاده کنید.
پایگاه داده از نوع `Sqlite3` است و ساختار طراحی شده برای آن شامل جدولهای زیر میباشد.
### جدول `parameters`
| ملاحضات | تعریف | نوع | اسم ستون |
|:-:|:-:|:-:|:-:|
| `PRIMARY KEY` | شناسهی پارامتر | `integer` | `id` |
| `NOT NULL UNIQUE` | عنوان پارامتر | `text` | `title` |
| `NOT NULL` | ژانر پارامتر | `text` | `genre` |
### جدول `films`
| ملاحضات | تعریف | نوع | اسم ستون |
|:-:|:-:|:-:|:-:|
| `PRIMARY KEY` | شناسهی فیلم | `integer` | `id` |
| `NOT NULL UNIQUE` | عنوان فیلم | `text` | `title` |
| `NOT NULL` | ژانر فیلم | `text` | `genre` |
### جدول `votes`
| ملاحضات | تعریف | نوع | اسم ستون |
|:-:|:-:|:-:|:-:|
| `NOT NULL` | شناسهی فیلم | `integer` | `film_id` |
| `NOT NULL` | عنوان پارامتر | `integer` | `parameter_id` |
| `NOT NULL` | امتیاز | `integer` | `score` |
## مراحل پیاده سازی
پروژه اولیه را میتوانید از [اینجا](https://quera.ir/qbox/download/fN4cUNniqD/review-system.zip) دانلود کنید.
### آماده سازی
فایل `functions.php`
1. متد `is_installed` را به گونهای پیاده سازی کنید که وضعیت نصب شده بودن سیستم را بررسی نماید. راهکار تعیین وضعیت نصب، برعهده شما می باشد(در مورد نحوه نصب کردن توضیح داده میشود).
2. متد `is_request_get` را به گونهای پیاده سازی کنید که مشخص نماید که آیا درخواست فعلی با استفاده از متد `GET` ایجاد شده است یا خیر.
3. متد `is_request_post` را به گونهای پیاده سازی کنید که مشخص نماید که آیا درخواست فعلی با استفاده از متد `POST` ایجاد شده است یا خیر.
### نصب
فایل `install.php` را به گونهای تغییر دهید که ابتدا یک دیتابیس از نوع `Sqlite3` به نام `_db.sqlite` در کنار فایل `index.php` ایجاد نماید.
سپس جداول `films` ، `parameters` و `votes` را با استفاده از ساختار تعیین شده بالا بر روی آن ایجاد کند.
در مرحله بعد برنامه نصب باید اطلاعات اولیه فیلمها و پارامترهای نقد و بررسی را از فایلهای _JSON_ موجود در پوشه `data` بخواند و وارد جدولهای پایگاه داده نماید.
فولدر `data` دارای دو فایل متفاوت می باشد.
1. `films.json`: اطلاعات فیلمهای قابل نقد و بررسی در این فایل قرار دارد. تابع `read_films` وظیفه خواندن این فایل و بازگرداندن اطلاعات به صورت یک آرایه را بر عهده دارد.
2. `parameters.json`: اطلاعات پارامترهای قابل نقد و بررسی در این فایل قرار دارد. تابع `read_parameters` وظیفه خواندن این فایل و بازگرداندن اطلاعات به صورت یک آرایه را برعهده دارد.
توابع `read_films` و `read_parameters` را به گونه ای پیاده سازی نمایید، که اطلاعات موجود در فایل _JSON_ را به صورت یک آرایه `php` بازگرداند.
توجه کنید که فایل `install.php` تنها یک بار قابلیت اجرا دارد. درصورتی که کاربر چندین بار این فایل را اجرا نماید، باید خطای `Already installed` به کاربر نمایش داده شود.
### دریافت پارامترهای نقد و بررسی
فایل `vote.php`
این فایل ID یک فیلم را از طریق متغیر `$_GET['film_id']` دریافت میکند و در پاسخ باید لیستی از پارامترهای قابل رای دهی برای این فیلم، (با توجه به ژانر) را در آرایهای به شکل نمونه تصادفی زیر برگرداند:
```json
[
[
id: 1,
title: ‘عنوان پارامتر اول’,
],
[
id: 2,
title: ‘عنوان پارامتر دوم,
],
[
id: 3,
title: ‘عنوان پارامتر سوم,
],
]
```
متدها:
+ `get_parameters($film_id)`: این تابع `ID` یک فیلم را به عنوان پارامتر می گیرد و پارامترهای قابل نقد و بررسی برای آن فیلم را به صورت ذکر شده باز می گرداند.
+ `has_voted($film_id)`: این تابع `ID` یک فیلم را به عنوان پارامتر می گیرد و بررسی می کند که آیا کاربر فعلی قبلا برای این فیلم رای خود را ثبت کرده است یاخیر.
### ثبت نقد و بررسی
فایل `vote.php`
این فایل وظیفه دریافت رایهای کاربر و ثبت آنها در پایگاه داده را بر عهده دارد. اطلاعات دریافتی این فایل از طریق متغیر `$_POST` شامل موارد زیر میباشد.
+ `$_POST['film_id']`: ID فیلمی که نقد و بررسی برای آن ارسال شده است
+ `$_POST['scores']`: آرای ثبت شده کاربر به تفکیک پارامترها
ساختار داده امتیازات به صورت زیر میباشد:
```json
[
Parameter_id: Score,
]
```
یک نمونه از متغیر `$_POST['scores']` به صورت زیر میباشد:
```json
[
1: 5,
2: 3,
3: 1
]
```
شما باید تابع `submit_vote($film_id, $scores)` را بگونه ای تغییر دهید که امتیازات کاربر را ثبت نماید.
\*نکته: توجه کنید که اگر فایل `vote.php` با متد `GET`فراخوانی کنیم باید پارامترهای قابل بررسی را نمایش بدهد و درصورتی که با متد `POST` فراخوانی کنیم باید نقد و بررسی را ثبت نماید.
توجه کنید که امتیاز هر پارامتر باید مقداری بین 1 تا 5 باشد. در صورتی که کاربر اعدادی بزرگتر از `5` و یا کوچکتر از `1` را به عنوان رای ارسال کند، سیستم باید به صورت اتوماتیک رای کاربر را در بازه مشخص شده اصلاح نماید. مثلا اگر کاربر برای یک پارامتر امتیاز `7` را وارد کرد، سیستم باید حداکثر امتیار ممکن یعنی `5` را به آن رای اختصاص دهد. و اگر کاربری امتیاز `0` را برای پارامتری ارسال کرد، سیستم باید حداقل امتیاز ممکن یعنی `1` را به آن رای اختصاص دهد.
### نمایش لیست فیلمها
فایل `index.php`
متد `get_films` موجود در این فایل را به گونهای پیاده سازی نمایید که یک آرایه از فیلمهای موجود در جدول `films` به همراه تعداد آرای ثبت شده برای هر فیلم و همچنین میانگین آرای ثبت شده برای هر فیلم را برگرداند.
تعداد رایهای ثبت شده برای هر فیلم برابر ردیف های موجود در جدول `votes` میباشد، به صورتی که `film_id` برابر با `ID` فیلم مورد نظر باشد.
همجنین میانگین رایهای ثبت شده برای یک فیلم، برابر میانگین مقادیر فیلد `score` در جدول `votes` می باشد، به صورتی که `film_id` برابر با `ID` فیلم مورد نظر باشد.
ساختار خروجی این متد باید به شکل زیر باشد:
```json
[
[
'film_id'=> `ID فیلم`,
'title'=> `عنوان فیلم`,
'votes_count'=> `تعداد رایهای ثبت شده`,
'average_score'=> `میانگین رایهای ثبت شده`,
],
[
'film_id'=> `ID فیلم`,
'title'=> `عنوان فیلم`,
'votes_count'=> `تعداد رایهای ثبت شده`,
'average_score'=> `میانگین رایهای ثبت شده`,
],
]
```
### جواب
در انتها فایل های زیر را به صورت یک فایل _zip_ آپلود نمایید. نام فایل _zip_ اهمیتی ندارد.
+ `functions.php`
+ `index.php`
+ `install.php`
+ `vote.php`