در این سوال قصد داریم یک کوتاه کننده لینک به کمک لاراول ایجاد کنیم.
طراحی کنترلر های این سیستم به عهده شماست.
# پروژه اولیه
پروژه اولیه را از
[اینجا](http://bayanbox.ir/download/1588563219113169092/url-shortener-initial.zip)
دانلود کنید. ساختار فایلهای این پروژه به صورت زیر است:
```
url-shortener_initial
├─ app
│   ├─ Console
│   │   └─ Kernel.php
│   ├─ Exceptions
│   │   └─ Handler.php
│   ├─ Http
│   │   ├─ Controllers
│   │   │   ├─ Auth
│   │   │   │   ├─ ForgotPasswordController.php
│   │   │   │   ├─ LoginController.php
│   │   │   │   ├─ RegisterController.php
│   │   │   │   ├─ ResetPasswordController.php
│   │   │   │   └─ VerificationController.php
│   │   │   ├─ AdminController.php
│   │   │   ├─ Controller.php
│   │   │   ├─ HomeController.php
│   │   │   └─ OwnerController.php
│   │   ├─ Middleware
│   │   │   ├─ Authenticate.php
│   │   │   ├─ CheckForMaintenanceMode.php
│   │   │   ├─ EncryptCookies.php
│   │   │   ├─ RedirectIfAuthenticated.php
│   │   │   ├─ TrimStrings.php
│   │   │   ├─ TrustProxies.php
│   │   │   └─ VerifyCsrfToken.php
│   │   └─ Kernel.php
│   ├─ Providers
│   │   ├─ AppServiceProvider.php
│   │   ├─ AuthServiceProvider.php
│   │   ├─ BroadcastServiceProvider.php
│   │   ├─ EventServiceProvider.php
│   │   └─ RouteServiceProvider.php
│   ├─ Link.php
│   └─ User.php
├─ bootstrap
│   ├─ cache
│   └─ app.php
├─ config
│   ├─ app.php
│   ├─ auth.php
│   ├─ broadcasting.php
│   ├─ cache.php
│   ├─ database.php
│   ├─ filesystems.php
│   ├─ hashing.php
│   ├─ logging.php
│   ├─ mail.php
│   ├─ queue.php
│   ├─ services.php
│   ├─ session.php
│   └─ view.php
├─ database
│   ├─ factories
│   │   ├─ LinkFactory.php
│   │   └─ UserFactory.php
│   ├─ migrations
│   │   ├─ 2014_10_12_000000_create_users_table.php
│   │   ├─ 2014_10_12_100000_create_password_resets_table.php
│   │   └─ 2018_10_16_141216_create_links_table.php
│   └─ seeds
│       ├─ DatabaseSeeder.php
│       └─ LinksTableSeeder.php
├─ public
│   ├─ css
│   │   └─ app.css
│   ├─ js
│   │   └─ app.js
│   ├─ svg
│   │   ├─ 403.svg
│   │   ├─ 404.svg
│   │   ├─ 500.svg
│   │   └─ 503.svg
│   ├─ .htaccess
│   ├─ favicon.ico
│   ├─ index.php
│   └─ robots.txt
├─ resources
│   ├─ js
│   │   ├─ components
│   │   │   └─ ExampleComponent.vue
│   │   ├─ app.js
│   │   └─ bootstrap.js
│   ├─ lang
│   │   └─ en
│   │       ├─ auth.php
│   │       ├─ pagination.php
│   │       ├─ passwords.php
│   │       └─ validation.php
│   ├─ sass
│   │   ├─ _variables.scss
│   │   └─ app.scss
│   └─ views
│       ├─ layouts
│       │   └─ app.blade.php
│       ├─ admin.blade.php
│       ├─ home.blade.php
│       ├─ login.blade.php
│       └─ owner.blade.php
├─ routes
│   ├─ api.php
│   ├─ channels.php
│   ├─ console.php
│   └─ web.php
├─ storage
│   ├─ app
│   ├─ framework
│   │   ├─ cache
│   │   ├─ sessions
│   │   ├─ testing
│   │   └─ views
│   └─ logs
├─ tests
│   ├─ CreatesApplication.php
│   └─ TestCase.php
├─ .editorconfig
├─ .env.example
├─ .gitattributes
├─ artisan
├─ composer.json
├─ composer.lock
├─ package.json
├─ phpunit.xml
├─ server.php
└─ webpack.mix.js
```
# جزئیات
## کلاسها 
### `App\Http\Controllers\HomeController`
#### `visitLink()`
این تابع باید در صورت معتبر بودن آدرس کوتاه شده ورودی ، آدرس هدف را یافته و کاربر را به آن صفحه `Redirect` کند و در صورت نامعتبر بودن آدرس کوتاه شده، کاربر را با `Session(message)` با محتوای `Invalid` به صفحه اصلی سایت `Redirect` کند.
### `App\Http\Controllers\AdminController`
#### `addLink()`
این تابع باید در صورت معتبر بودن لینک ورودی ، یک آدرس کوتاه شده و یک آدرس رمز بصورت تصادفی ایجاد کند، اطلاعات مربوط به لینک را در پایگاه داده ذخیره کرده و در انتها `Session(shortened)` و `Session(password)` را بطور صحیح تنظیم کند. این تابع در انتها باید کاربر را به صفحه اصلی سایت `Redirect` کند.
#### `adminLink()`
این تابع باید در صورت معتبر بودن آدرس رمز، `View` مربوط به خود (`admin`) را با محتوای صحیح نمایش دهد. در صورت نامعتبر بودن آدرس رمز، کاربر را با `Session(message)` با محتوای `Invalid` به صفحه اصلی سایت `Redirect` کند.
#### `editLink()`
این تابع باید در صورت معتبر بودن آدرس رمز و اطلاعات ورودی، اطلاعات لینک را به اطلاعات ورودی تغییر دهد (در صورت تکراری بودن آدرس رمز یا آدرس کوتاه شده، از تغییر  پارامتر تکراری چشم پوشی کنید) و کاربر را به آدرس رمز `Redirect` کند. . در صورت نامعتبر بودن آدرس رمز، کاربر را با `Session(message)` با محتوای `Invalid` به صفحه اصلی سایت `Redirect` کند.
### `App\Http\Controllers\OwnerController`
#### `index()`
این تابع باید اگر کاربر به عنوان صاحب سایت احراز هویت شده بود `View` مربوط به خود (`owner`) را با محتوای صحیح نمایش دهد. در غیر این صورت کاربر را به صفحه `Login`،  `Redirect` می کند.
#### `login()`
این تابع باید  اگر کاربر به عنوان صاحب سایت احراز هویت نشده بود `View` مربوط به خود (`login`) را نمایش دهد. در غیر این صورت کاربر را به صفحه `Owner`،  `Redirect` می کند.
#### `authenticate()`
این تابع باید معتبر بودن رمز صاحب سایت را بررسی کند، در صورت صحیح بودن، تنظیمات مورد نیاز را انجام داده و سپس کاربر را به صفحه `Owner`،  `Redirect` کند. در غیر این صورت کاربر را به صفحه `Login`،  `Redirect` کند.
+ تمام احراز هویت ها باید با استفاده از `Session(IsOwner)` با مقادیر `true` یا `false` انجام شود.
+ برای بررسی معتبر بودن مقادیر ورودی از  `Validation` استفاده کنید.
+ هر لینک باید تنها برای تعدادی محدودی مشاهده معتبر باشد، که تعداد دفعات باقیمانده مشاهده هر لینک از روی ستون `expire_after_clicks` در جدول `links` بدست می آید و در ابتدا باید برای هر لینک مقدار آن 50 باشد. بعد از 0 شدن این عدد لینک کوتاه شده نامعتبر می شود.
+ رمز صاحب سایت در فایل `.env` با کلید `SUPER_ADMIN_PASS` قرار داده شده است.
# نکات
 - شما تنها مجاز به تغییر فایل های `app/Http/Controllers/AdminController.php` و `app/Http/Controllers/HomeController.php` و `app/Http/Controllers/OwnerController.php` هستید، بقیهی تغییرات نادیده گرفته میشوند.
 - از `view`, `route` , `migration` ها برای فهمیدن آنچه باید بنویسید کمک بگیرید. 
 - پس از اعمال تغییرات کل پروژه به غیر از پوشهی `vendor` را _Zip_ کرده و ارسال کنید.
 - نام فایل Zip اهمیتی ندارد.