{"id":27720632,"url":"https://github.com/doppar/doppar","last_synced_at":"2026-03-14T12:21:27.627Z","repository":{"id":289504519,"uuid":"971478244","full_name":"doppar/doppar","owner":"doppar","description":"Doppar is a PHP framework built to revolutionize the way developers create robust, scalable, and efficient web applications, specifically for developing small, feature-based PHP web applications","archived":false,"fork":false,"pushed_at":"2025-04-25T12:51:02.000Z","size":341,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-27T09:58:53.756Z","etag":null,"topics":["framework","php"],"latest_commit_sha":null,"homepage":"https://doppar.com","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/doppar.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-04-23T15:25:25.000Z","updated_at":"2025-04-25T12:51:05.000Z","dependencies_parsed_at":"2025-04-23T17:00:03.067Z","dependency_job_id":null,"html_url":"https://github.com/doppar/doppar","commit_stats":null,"previous_names":["doppar/doppar"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doppar%2Fdoppar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doppar%2Fdoppar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doppar%2Fdoppar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doppar%2Fdoppar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/doppar","download_url":"https://codeload.github.com/doppar/doppar/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251119576,"owners_count":21539194,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["framework","php"],"created_at":"2025-04-27T09:59:01.925Z","updated_at":"2026-03-14T12:21:27.581Z","avatar_url":"https://github.com/doppar.png","language":"PHP","readme":"\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://laravel.com\" target=\"_blank\"\u003e\n        \u003cimg src=\"https://raw.githubusercontent.com/doppar/doppar/7138fb0e72cd55256769be6947df3ac48c300700/public/logo.png\" width=\"400\"\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://github.com/doppar/doppar/actions/workflows/tests.yml\"\u003e\u003cimg src=\"https://github.com/doppar/doppar/actions/workflows/tests.yml/badge.svg\" alt=\"Build Status\"\u003e\u003c/a\u003e\n\u003ca href=\"https://packagist.org/packages/doppar/framework\"\u003e\u003cimg src=\"https://img.shields.io/packagist/dt/doppar/framework\" alt=\"Total Downloads\"\u003e\u003c/a\u003e\n\u003ca href=\"https://packagist.org/packages/doppar/doppar\"\u003e\u003cimg src=\"https://img.shields.io/packagist/v/doppar/doppar\" alt=\"Latest Stable Version\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/doppar/framework/blob/main/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/github/license/doppar/framework\" alt=\"License\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n## About Doppar\n\nDoppar is a PHP framework built to revolutionize the way developers create robust, scalable, and efficient web applications, specifically for developing small, feature-based PHP web applications.\n- **Getting started**\n  - [Installation](#section-1)\n  - [Configuration](#section-2)\n  - [Directory structure](#section-3)\n  - [Frontend](#section-4)\n  - [Starter kits](#section-5)\n- **Architecture Concepts**\n  - [Request Lifecycle](#section-7)\n  - [Service Container](#section-8)\n  - [Service Providers](#section-9)\n  - [Facades](#section-41)\n- **The Basics**\n  - [Routing](#section-10)\n    - [Route Parameter](#section-11)\n    - [Optional Route Parameter](#section-12)\n    - [Naming Route](#section-13)\n- **Eloquent ORM**\n  - [Model](#section-44)\n    - [Model Properties](#section-45)\n    - [Eloquent ORM Query](#section-46)\n      - [Eloquent Relationships](#section-51)\n        - [Transform Eloquent Collection](#section-52)\n    - [Pagination](#section-47)\n    - [Database Transactions](#section-53)\n    - [Manual Join](#section-54)\n- **Query Builder**\n    - [Database Operations with DB Facade](#section-56)\n- **Digging Deeper**\n  - [Middleware](#section-14)\n    - [Route Middleware](#section-15)\n    - [Global Web Middleware](#section-16)\n    - [Middleware Params](#section-17)\n  - [CSRF Protectection](#section-18)\n  - [Controllers](#section-19)\n  - [Request](#section-20)\n  - [Response](#section-21)\n  - [Views](#section-22)\n  - [Asset Bundling](#section-23)\n  - [Session](#section-24)\n  - [Cookie](#section-50)\n  - [Validation](#section-25)\n  - [Error Handling](#section-26)\n    - [Error Log and Logging](#section-27)\n  - [URL Generation](#section-48)\n  - [Pool Console](#section-28)\n  - [Encryption \u0026 Decryption](#section-30)\n- **Database**\n  - [Database Connection](#section-32)\n  - [Migration](#section-33)\n  - [Seeder](#section-34)\n- **Authentication**\n  - [Hashing](#section-35)\n  - [Authentication](#section-36)\n- **Mail**\n  - [Configuration](#section-37)\n  - [Sending Mail](#section-38)\n    - [Sending Mail with Attachment](#section-39)\n    - [Mail Sending with CC and BCC](#section-40)\n- **File Uploads**\n  - [File Storage](#section-42)\n  - [Uploads](#section-43)\n- **Helpers**\n  - [Helpers](#section-49)\n- **Localization**\n  - [Localization](#section-55)\n- **Package Development**\n  - [Package Development](#section-57)\n- **API Authentication**\n  - [Doppar Flarion](#flarion)\n\n\u003ca name=\"section-1\"\u003e\u003c/a\u003e\n\n## Installation\nBefore creating your first Doppar application, make sure that your local machine has PHP, Composer. If you don't have `PHP` and `Composer` installed on your local machine, the following commands will install PHP, Composer on macOS, Windows, or Linux:\n#### macOS\n```bach\n/bin/bash -c \"$(curl -fsSL https://php.new/install/mac/8.4)\"\n```\n#### Windows PowerShell\n```bach\n# Run as administrator...\nSet-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://php.new/install/windows/8.4'))\n```\n#### Linux\n```bash\n/bin/bash -c \"$(curl -fsSL https://php.new/install/linux/8.4)\"\n```\n\nAfter you have installed PHP, Composer, you're ready to create a new Doppar application.\n#### Create an Application\n```bash\ncomposer create-project doppar/doppar example-app\n```\n\nNow run a command to generate application key that will use to encrypt and decrypt sensitive data.\n```bash\nphp pool key:generate\n```\n\nThis command will set `APP_KEY` in your `.env` file.\n\nNow you are ready to start development server, run this command:\n```bash\nphp pool start\n```\n\nUse `--post` as a params in command to run application in specific post like\n```bash\nphp pool start --port=8081\n```\n\nNow your development server is ready.\n\n\u003ca name=\"section-2\"\u003e\u003c/a\u003e\n\n## Configuration\nAll of the configuration files for the Doppar framework are located in the `config` directory. Each option is documented, so feel free to look through the files and get familiar with the options available to you.\n\u003e **⚠️ Warning:** If you create a new config file, Doppar do not know about it, to let it know to Doppar, need to run\n\u003e \n\u003e ```bash\n\u003e php pool config:clear\n\u003e \n\u003e ```\n\u003e \n\u003e Proceed on now\n\nIf you run system, Doppar cached your newly created config file again. You can cache config file manyally by running this command\n```php pool config:cache```\n\nDoppar's config cache file located `storage/framework/cache/config.php` path\n\n\n### Accessing Configuration Values\nYou may easily access your configuration values using the Config facade or global config function from anywhere in your application. The configuration values may be accessed using \"`dot`\" syntax, which includes the name of the file and option you wish to access. A default value may also be specified and will be returned if the configuration option does not exist:\n```php\n\u003c?php\n\nuse Phaseolies\\Support\\Facades\\Config;\n\n$value = Config::get('app.name');\n\n$value = config('app.name');\n\n// Retrieve a default value if the configuration value does not exist...\n$value = config('app.name', 'Doppar');\n```\n\n### Environment variable\nLet's know about every variable\n```\nAPP_NAME=\"Doppar\"\nAPP_KEY=base64:+cVvutS1oVZxZUZeVGVS4evpiF6M7VaKAjEkiZi7lIM= // App Key that will use to generate encryption and decryption\nAPP_ENV=local\nAPP_DEBUG=true  // If false, system will do not show any error message to browser\nAPP_URL=http://localhost:8000\nAPP_LOCALE=en\n\nAPP_TIMEZOME=UTC\nLOG_CHANNEL=stack  // for details see config/log.php\nFILESYSTEM_DISK=local  // for details see config/filesystem.php\n\nSESSION_DRIVER=file // for details see config/session.php\nSESSION_LIFETIME=120\nSESSION_PATH=/\nSESSION_DOMAIN=\n\nDB_CONNECTION=mysql // for details see config/database.php\nDB_HOST=localhost\nDB_PORT=3306\nDB_DATABASE=doppar\nDB_USERNAME=mahedi\nDB_PASSWORD=123456\n\nMAIL_MAILER=smtp\nMAIL_HOST=sandbox.smtp.mailtrap.io\nMAIL_PORT=2525\nMAIL_USERNAME=\nMAIL_PASSWORD=\nMAIL_ENCRYPTION=tls\nMAIL_FROM_ADDRESS=\"hello@example.com\"\nMAIL_FROM_NAME=\"${APP_NAME}\"\n```\n\n#### Accessing Environment Variable\nTo get the environment varibale data, you can use global `env()` method like\n```php\nenv('APP_KEY', 'default value');\n```\n\n\u003ca name=\"section-3\"\u003e\u003c/a\u003e\n\n## Directory structure\n```\n└── 📁doppar-framework\n    └── 📁app\n        └── 📁Http\n            └── 📁Controllers // Controllers directory\n            └── Kernel.php  // Register Application global and route specific middleware\n            └── 📁Middleware // Middleware located here\n        └── 📁Models // Application model directory\n        └── 📁Mail // Application mail directory\n        └── 📁Providers // Application Service Provider\n    └── 📁bootstrap // Bootstrap application dependency from here\n    └── 📁config // Config files located here\n    └── 📁database \n        └── 📁migrations // Database migration files\n        └── 📁seeds  // Database seeder files\n    └── 📁public // Public directory for assets\n    └── 📁resources\n        └── 📁views // All the views will be located here\n    └── 📁routes // Application routes directory\n    └── 📁storage\n        └── 📁app\n            └── 📁public // Public symlinked to /public/storage directory to storage/app/public directory\n        └── 📁cache // All the views cache and config files cache located here\n        └── 📁logs // System error log and user defined log will be printed here\n        └── 📁sessions // file session driver will be cache here\n    └── .env\n    └── .env.example\n    └── .gitignore\n    └── composer.json\n    └── composer.lock\n    └── config.example\n    └── config.php // Database seeder and migration command setup file\n    └── pool // Pool command\n    └── README.md\n```\n\n\u003ca name=\"section-4\"\u003e\u003c/a\u003e\n\n## Frontend\nDoppar uses its own template engine blade. See some avaiable blade syntax.\n#### Conditionals and Loops\n\n### @if\nChecks if a condition is true.\n```blade\n@if ($condition)\n    // Code to execute if the condition is true\n@endif\n```\n### @elseif\nChecks an additional condition if the previous `@if` or `@elseif` condition is false.\n#### Syntax:\n```blade\n@if ($condition1)\n    // Code for condition1\n@elseif ($condition2)\n    // Code for condition2\n@endif\n```\n### @else\nExecutes code if all previous `@if` and `@elseif` conditions are false.\n\n#### Syntax:\n```blade\n@if ($condition)\n    // Code for condition\n@else\n    // Code if condition is false\n@endif\n```\n### @unless\nExecutes code if the condition is false.\n#### Syntax:\n@unless ($condition)\n    // Code to execute if the condition is false\n@endunless\n\n### @isset\nChecks if a variable is set and not null.\n\n#### Syntax:\n```blade\n@isset ($variable)\n    // Code to execute if the variable is set\n@endisset\n```\n\n### @unset\nUnsets a variable.\n\n#### Syntax:\n```blade\n@unset ($variable)\n```\n\n### @for\nExecutes a loop for a specified number of iterations.\n\n#### Syntax:\n```blade\n@for ($i = 0; $i \u003c 10; $i++)\n    // Code to execute in each iteration\n@endfor\n```\n### @foreach\nIterates over an array or collection.\n\n#### Syntax:\n```blade\n@foreach ($items as $item)\n    // Code to execute for each item\n@endforeach\n```\n\n### @forelse\nIterates over an array or collection, with a fallback if the array is empty.\n\n#### Syntax:\n```blade\n@forelse ($items as $item)\n    // Code to execute for each item\n@empty\n    // Code to execute if the array is empty\n@endforelse\n```\n\n### @while\nExecutes a loop while a condition is true.\n\n#### Syntax:\n```blade\n@while ($condition)\n    // Code to execute while the condition is true\n@endwhile\n```\n\n### @switch\nExecutes a switch-case block.\n\n#### Syntax:\n```blade\n@switch ($variable)\n    @case ($value1)\n        // Code for value1\n        @break\n\n    @case ($value2)\n        // Code for value2\n        @break\n\n    @default\n        // Default code\n@endswitch\n```\n### @break\nBreaks out of a loop or switch-case block.\n\n#### Syntax:\n```blade\n@break\n```\nExample\n```blade\n@foreach ($users as $user)\n    @if ($user-\u003eisBanned)\n        @break\n    @endif\n    \u003cp\u003e{{ $user-\u003ename }}\u003c/p\u003e\n@endforeach\n```\n### @continue\nSkips the current iteration of a loop.\n\n#### Syntax:\n```blade\n@continue\n```\nExample:\n```blade\n@foreach ($users as $user)\n    @if ($user-\u003eisBanned)\n        @continue\n    @endif\n    \u003cp\u003e{{ $user-\u003ename }}\u003c/p\u003e\n@endforeach\n```\n### @php\nExecutes raw PHP code.\n\n#### Syntax:\n```blade\n@php\n    // PHP code\n@endphp\n```\n\n### @json\nEncodes data as JSON.\n\n#### Syntax:\n```blade\n@json ($data)\n```\nExample\n```blade\n\u003cscript\u003e\n    var users = @json($users);\n\u003c/script\u003e\n```\n\n### @csrf\nGenerates a CSRF token for forms.\n\n#### Syntax:\n```blade\n@csrf\n```\nExample\n```blade\n\u003cform method=\"POST\"\u003e\n    @csrf\n    \u003cbutton type=\"submit\"\u003eSubmit\u003c/button\u003e\n\u003c/form\u003e\n```\n### @exit\nUsage\n```blade\n@foreach ($users as $user)\n    @if ($user-\u003eisAdmin())\n        @exit\n    @endif\n@endforeach\n```\n### @empty\nUsage\n```blade\n@empty ($users)\n    //  User is empty\n@endempty\n```\n## Section Directives\n### @extends\n```blade\n@extends('layouts.app')\n```\nExtends a Blade layout.\n\n### @include\n```blade\n@include('partials.header')\n```\nIncludes another Blade view\n### @yield\n```blade\n@yield('content')\n```\nOutputs the content of a section.\n\n### @section\nExample:\n```blade\n@section('content')\n    \u003cp\u003eThis is the content section\u003c/p\u003e\n@endsection\n```\nDefines a section to be yielded later\n\n### @stop\n```blade\n@stop\n```\nStops the current section output.\n\n### @overwrite\n```blade\n@overwrite\n```\nOverwrites the current section content.\n\n### Authentication Directives\n\n### @auth\nChecks if a user is authenticated.\n\n#### Syntax:\n```blade\n@auth\n    // Code to execute if the user is authenticated\n@endauth\n```\n### @guest\nChecks if a user is not authenticated (guest).\n\n#### Syntax:\n```blade\n@guest\n    // Code to execute if the user is not authenticated\n@endguest\n```\n### Flash Message Directives\n### @errors\nChecks if there are any errors messages.\n\n#### Syntax:\n```blade\n@errors\n    // Code to execute if errors messages exist\n@enderrors\n```\nExample\n```blade\n@errors\n    \u003cdiv class=\"alert alert-danger\"\u003e\n        \u003cul\u003e\n            @foreach (session()-\u003eget('errors') as $field =\u003e $messages)\n                @foreach ($messages as $message)\n                    \u003cli\u003e{{ $message }}\u003c/li\u003e\n                @endforeach\n            @endforeach\n        \u003c/ul\u003e\n    \u003c/div\u003e\n@enderrors\n```\n\n### @error\nChecks if a specific error message exists in the flash messages.\n\n#### Syntax:\n```blade\n@error('key')\n    // Code to execute if the error message exists\n@enderror\n```\nExample\n```blade\n@error('email')\n    \u003cp class=\"error\"\u003e{{ $message }}\u003c/p\u003e\n@enderror\n```\n\n\u003ca name=\"section-5\"\u003e\u003c/a\u003e\n\n## Starter kits\nTo give you a head start building your new Doppar application, we are happy to offer application starter kits. These starter kits give you a head start on building your next Doppar application, and include the routes, controllers, and views you need to register and authenticate your application's users.\n```html\nlayout/app.blade.php\n\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"en\"\u003e\n    \u003chead\n        \u003cmeta charset=\"UTF-8\"\u003e\n        \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"\u003e\n        \u003ctitle\u003e@yield('title')\u003c/title\u003e\n        @section('style')\n          // This for loading ondemand page css\n        @show\n    \u003c/head\u003e\n    \u003cbody\u003e\n        \u003cdiv class=\"container mt-4\"\u003e\n            \u003cdiv class=\"row justify-content-center\"\u003e\n                \u003cdiv class=\"col-md-8\"\u003e\n                    @yield('content')\n                \u003c/div\u003e\n            \u003c/div\u003e\n        \u003c/div\u003e\n        @section('script')\n          // This for loading ondemand page script\n        @show\n    \u003c/body\u003e\n\u003c/html\u003e\n```\nExtented content file\n```html\n@extends('layouts.app')\n@section('title') Home Page\n@section('style')\n // Load css\n@append\n@section('content')\n    \u003cdiv class=\"card shadow-lg mb-4\"\u003e\n        \u003cdiv class=\"card-header bg-primary text-white\"\u003e\n            \u003ch5 class=\"mb-0\"\u003eDashboard\u003c/h5\u003e\n        \u003c/div\u003e\n        \u003cdiv class=\"card-body\"\u003e\n            \u003cp class=\"fw-bold fs-5\"\u003e\n                Howdy\n            \u003c/p\u003e\n        \u003c/div\u003e\n    \u003c/div\u003e\n@endsection\n@section('script')\n // Load script\n@append\n```\n\n\u003ca name=\"section-7\"\u003e\u003c/a\u003e\n\n## Request Lifecycle\nUnderstanding how a tool operates makes using it much easier and more intuitive. This principle applies just as much to application development as it does to any other tool in the real world. When you comprehend the inner workings of your development tools, you gain confidence and efficiency in using them.\n\nThis document aims to provide a high-level overview of how the Doppar framework functions. By familiarizing yourself with its core concepts, you’ll reduce the sense of mystery surrounding it and feel more empowered when building applications. Don’t worry if some of the terminology seems unfamiliar at first—focus on grasping the big picture. As you continue exploring the documentation, your understanding will naturally deepen over time.\n### Lifecycle Overview\n#### First Steps\nThe entry point for all requests to a Doppar application is the `public/index.php` file. All requests are directed to this file by your web server (Apache / Nginx) configuration. The index.php file doesn't contain much code. Rather, it is a starting point for loading the rest of the framework.\n\nThe `index.php` file loads the Composer generated autoloader definition, and then retrieves an instance of the Doppar application from `bootstrap/app.php`. The first action taken by Doppar itself is to create an instance of the application service container.\n\n### Second Steps\nAt this stage, Doppar initializes its core configuration and loads the service providers along with their registered methods. Once the core setup is complete, Doppar proceeds to load and execute the boot methods of the registered service providers, ensuring that all necessary services are properly initialized and ready for use.\n\n### Thirds Steps\nAt this stage, Doppar generate global middleware stack. The method signature for the middleware's `__invoke()` method is quite simple: it receives a Request and Closer $next and send the Request and Response to the next Request. Feed it HTTP requests and it will return HTTP responses.\n\n### Final Steps\nOnce the application has been fully bootstrapped and all service providers have been registered, the request is passed to the router for processing. The router is responsible for directing the request to the appropriate route or controller while also executing any route-specific middleware.\n\nMiddleware acts as a powerful filtering mechanism for incoming HTTP requests, allowing the application to inspect, modify, or restrict access before reaching the intended destination. For instance, Doppar includes authentication middleware that verifies whether a user is logged in. If the user is not authenticated, they are redirected to the login screen; otherwise, the request proceeds as expected.\n\nAfter the designated route or controller method processes the request and generates a response, the response begins its journey back through the middleware stack. This allows the application to inspect or modify the outgoing response before it reaches the user.\n\nFinally, as the response completes its trip through the middleware, the __invoke method returns the response object, which then calls the send method. The send method delivers the response content to the user's web browser, marking the completion of Doppar’s request lifecycle.\n\n\u003ca name=\"section-8\"\u003e\u003c/a\u003e\n\n## Service Container\nThe Doppar Service Container is a robust and versatile tool designed to streamline dependency management and facilitate dependency injection within application. At its core, dependency injection is a sophisticated concept that simplifies how class dependencies are handled: instead of a class creating or managing its own dependencies, they are \"injected\" into the class—typically through the constructor or, in certain scenarios, via setter methods. This approach promotes cleaner, more modular, and testable code, making the Doppar framework an ideal choice for modern, scalable web development.\n\nLet's look at a simple example:\n```php\n\u003c?php\n\nnamespace App\\Http\\Controllers;\n\nuse Phaseolies\\Http\\Request;\nuse App\\Service\\UserService;\nuse App\\Http\\Controllers\\Controller;\n\nclass UserController extends Controller\n{\n    public function __construct(protected User $user) {}\n\n    public function index(UserService $userService, Request $request)\n    {\n        $userServiceData = $userService-\u003egetUser();\n        $users = $this-\u003euser-\u003eall();\n\n        return view('welcome', compact('userServiceData','users'));\n    }\n}\n```\n\nIn this example, the UserInterface from controller `index` method and User class from constructor will automatically injected in Doppar's request life cycle and will be automatically instantiated. \n\n### Create Instance Using Container\nDoppar allows you to create object of a class using global `app()` function. If you want to create object that works like a singleton object, you can use the `app()` function\n```php\n$singletonObject = app(SMSService:class); // this is the object of SMSService class\n$singletonObject-\u003esendSms();\n```\nBut if you call just `app()`, it will return the Application instance.\n\n## Binding\n### bind()\nBinds a service to the container. You can bind a class name or a callable (closure) that returns an instance of the service.\n```php\nbind(string $abstract, callable|string $concrete, bool $singleton = false): void\n```\nParameters:\n1. `$abstract:` The service name or interface.\n2. `$concrete:` The class name or a callable that returns an instance.\n3. `$singleton:` Whether the binding should be a singleton (optional, default: false)\n\nExample\n```php\n\u003c?php\n\nnamespace App\\Providers;\n\nuse Phaseolies\\Providers\\ServiceProvider;\nuse App\\Service\\ProductInterface;\nuse App\\Service\\ProductClass;\n\nclass AppServiceProvider extends ServiceProvider\n{\n  public function register(): void\n  {\n    // You can choose any of the below declaration\n    $this-\u003eapp-\u003ebind(ProductInterface::class, fn() =\u003e new ProductClass );\n\n    $this-\u003eapp-\u003ebind(ProductInterface::class, ProductClass::class);\n  }\n\n  public function boot(): void\n  {\n    //\n  }\n}\n```\n\n## Singleton Bindings\n### singleton()\nBinds a service as a singleton. The container will always return the same instance when resolving the service.\nExample\n```php\n$this-\u003eapp-\u003esingleton(ProductInterface::class,fn() =\u003e new ProductClass);\n```\n\n## Conditional Bindings\n#### when()\nConditionally binds a service based on a condition. If the condition is true, the binding is applied.\n\n#### Syntax:\n```php\nwhen(callable|bool $condition): ?self\n```\nExample\n```php\n$this-\u003eapp-\u003ewhen(fn() =\u003e rand(0, 1) === 1)?-\u003esingleton(ProductInterface::class,fn() =\u003e new ProductClass);\n```\n\nThe Doppar Service Container simplifies dependency management by providing a clean and intuitive API for binding and resolving services. Whether you're working with regular bindings, singletons, or conditional logic, the container ensures your application remains modular, testable, and scalable.\n\n\u003ca name=\"section-9\"\u003e\u003c/a\u003e\n\n## Service Providers\nService providers are the central place of all Doppar application bootstrapping. Your own application, as well as all of Doppar's core services, are bootstrapped via service providers.\n\nBut, what do we mean by \"bootstrapped\"? In general, we mean registering things, including registering service container bindings, configuration initialization, middleware, and even routes and all the facades. Service providers are the central place to configure your application.\n\nDoppar uses service providers internally to bootstrap its core services, such as the mailer, cache, facades and others.\n\nAll user-defined service providers are registered in the `config/app.php` file. In the following documentation, you will learn how to write your own service providers and register them with your Doppar application.\n\n### Creating Service Providers\nDoppar provides `make:provider` pool command to create a new service provider.\n```bash\nphp pool make:provider MyOwnServiceProvider\n```\n\n### The Register Method\nAs mentioned previously, within the register method, you should only bind things into the service container. You should never attempt to register other services. Otherwise, you may accidentally use a service that is provided by a service provider which has not loaded yet.\n\nLet's take a look at a basic service provider. Within any of your service provider methods, you always have access to the $app property which provides access to the service container:\n```php\n\u003c?php\n\nnamespace App\\Providers;\n\nuse Phaseolies\\Application;\nuse Phaseolies\\Providers\\ServiceProvider;\n\nclass MyOwnServiceProvider extends ServiceProvider\n{\n    /**\n     * Register any application services.\n     */\n    public function register(): void\n    {\n        $this-\u003eapp-\u003esingleton(Connection::class, function (Application $app) {\n            return new Connection('test');\n        });\n    }\n}\n```\n### The Boot Method\nThis `boot` method is called after all other service providers have been registered, meaning you have access to all other services that have been registered by the framework:\n```php\n\u003c?php\n\nnamespace App\\Providers;\n\nuse Phaseolies\\Providers\\ServiceProvider;\n\nclass MyOwnServiceProvider extends ServiceProvider\n{\n    /**\n     * Bootstrap any application services.\n     */\n    public function boot(): void\n    {\n        // Register services\n    }\n}\n```\n\u003ca name=\"section-41\"\u003e\u003c/a\u003e\n\n## Facades\nThroughout the Doppar documentation, you will see examples of code that interacts with Doppar's features via \"facades\". Facades provide a \"static\" interface to classes that are available in the application's service container. Doppar ships with many facades which provide access to almost all of Doppar's features.\n\nDoppar facades serve as \"static proxies\" to underlying classes in the service container, providing the benefit of a terse, expressive syntax while maintaining more testability and flexibility than traditional static methods. It's perfectly fine if you don't totally understand how facades work - just go with the flow and continue learning about Doppar.\n\nAll of Doppar's facades are defined in the `Phaseolies\\Support\\Facades` namespace. So, we can easily access a facade like so:\n```php\nuse Phaseolies\\Support\\Facades\\Config;\nuse Phaseolies\\Support\\Facades\\Route;\n\nRoute::get('/config', function () {\n    return Config::get('key');\n});\n```\nThroughout the Doppar documentation, many of the examples will use facades to demonstrate various features of the framework.\n\nTo complement facades, Doppar offers a variety of global \"helper functions\" that make it even easier to interact with common Doppar features. Some of the common helper functions you may interact with are view, response, url, config, and more. Each helper function offered by Doppar.\n\nFor example, instead of using the `Phaseolies\\Support\\Facades\\Response` facade to generate a JSON response, we may simply use the response function. Because helper functions are globally available, you do not need to import any classes in order to use them:\n```php\nuse Phaseolies\\Support\\Facades\\Response;\n\nRoute::get('/users', function () {\n    return Response::json([\n        // ...\n    ]);\n});\n\nRoute::get('/users', function () {\n    return response()-\u003ejson([\n        // ...\n    ]);\n});\n```\n\n### When to Utilize Facades\nFacades have many benefits. They provide a terse, memorable syntax that allows you to use Doppar's features without remembering long class names that must be injected or configured manually. Furthermore, because of their unique usage of PHP's dynamic methods, they are easy to test.\n\n### Facades vs. Helper Functions\nIn addition to facades, Doppar includes a variety of \"helper\" functions which can perform common tasks like generating views, firing events, dispatching jobs, or sending HTTP responses. Many of these helper functions perform the same function as a corresponding facade. For example, this facade call and helper call are equivalent:\n```php\nreturn Phaseolies\\Support\\Facades\\Response::view('profile');\n\nreturn view('profile');\n```\n### How Facades Work\nIn a Doppar application, a facade is a class that provides access to an object from the container. The machinery that makes this work is in the Facade class. Doppar's facades, and any custom facades you create, will extend the base `Phaseolies\\Support\\Facades\\BaseFacade` class.\n\nThe Facade base class makes use of the __callStatic() magic-method to defer calls from your facade to an object resolved from the container. In the example below, a call is made to the Doppar cache system. By glancing at this code, one might assume that the static get method is being called on the Cache class:\n```php\n\u003c?php\n\nnamespace App\\Http\\Controllers;\n\nuse App\\Http\\Controllers\\Controller;\nuse Phaseolies\\Support\\Facades\\Config;\n\nclass UserController extends Controller\n{\n    public function getAppName()\n    {\n        return Config::get('app.name');\n    }\n}\n```\nIf we look at that `Phaseolies\\Support\\Facades\\Config` class, you'll see that there is no static method get:\n```php\n\u003c?php\n\nnamespace Phaseolies\\Support\\Facades;\n\nuse Phaseolies\\Facade\\BaseFacade;\n\nclass Config extends BaseFacade\n{\n    protected static function getFacadeAccessor()\n    {\n        return 'config';\n    }\n}\n```\n\n### Facade Class Reference\nBelow you will find every facade and its underlying class. This is a useful tool for quickly digging into the API documentation for a given facade root. The service container binding key is also included where applicable.\n| Facade   | Class   |  Container Binding |\n| -------- | ------- | -------- |\n| Auth  | Phaseolies\\Auth\\Security\\Auth    | auth |\n| Abort  | Phaseolies\\Http\\Support\\Abort   | abort |\n| Config  | Phaseolies\\Config\\Config    | config |\n| Crypt  | Phaseolies\\Support\\Encryption    | crypt |\n| Hash  | Phaseolies\\Auth\\Security\\Hash    | hash |\n| Mail  | Phaseolies\\Support\\Mail\\MailService    | mail |\n| Redirect  | Phaseolies\\Http\\RedirectResponse    | redirect |\n| Response  | Phaseolies\\Http\\Response    | response |\n| Route  | Phaseolies\\Support\\Router    | route |\n| Session  | Phaseolies\\Support\\Session    | session |\n| URL  | Phaseolies\\Support\\UrlGenerator    | url |\n| Storage  | Phaseolies\\Support\\Storage\\StorageFileService    | storage |\n| Log  | Phaseolies\\Support\\LoggerService    | log |\n| Sanitize | Phaseolies\\Support\\Validation\\Sanitizer    | sanitize |\n| Cookie | Phaseolies\\Support\\CookieJar   | cookie |\n\n\u003ca name=\"section-10\"\u003e\u003c/a\u003e\n\n## Routing\nDoppar provides a comprehensive and flexible routing system that allows you to define how your application responds to various HTTP requests. All routes are initialized from the routes/web.php file, making it easy to manage and organize your application's endpoints.\n\n### Supported HTTP Methods\nDoppar supports the following HTTP methods for defining routes:\n\n* `GET`: Used to retrieve data from the server.\n* `POST`: Used to submit data to the server.\n* `PUT`: Used to update existing data on the server.\n* `PATCH`: Used to partially update existing data on the server.\n* `DELETE`: Used to delete data on the server.\n* `HEAD`: Similar to GET, but retrieves only the headers without the body.\n* `OPTIONS`: Used to describe the communication options for the target resource.\n* `ANY`: Matches any HTTP method for the specified route.\n\n```php\n\n\u003c?php\n\nuse Phaseolies\\Support\\Facades\\Route;\nuse App\\Http\\Controllers\\HomeController;\nuse App\\Http\\Controllers\\PageController;\n\nRoute::get('/', [HomeController::class, 'dashboard']);\nRoute::get('/about', [PageController::class, 'about']);\n```\n\n### Available Router Methods\nThe router allows you to register routes that respond to any HTTP verb:\n```php\nRoute::get($uri, $callback);\nRoute::post($uri, $callback);\nRoute::put($uri, $callback);\nRoute::patch($uri, $callback);\nRoute::delete($uri, $callback);\nRoute::options($uri, $callback);\nRoute::any($uri, $callback);\nRoute::head($uri, $callback);\n```\n\n\u003ca name=\"section-11\"\u003e\u003c/a\u003e\n\n## Route Parameter\nYou can pass single or multiple parameter with route as like below\n```php\n\u003c?php\n\nuse Phaseolies\\Support\\Facades\\Route;\nuse App\\Http\\Controllers\\ProfileController;\n\nRoute::get('/user/{id}', [ProfileController::class, 'index']);\n```\nNow accept this param in your controller like:\n```php\n\u003c?php\n\nnamespace App\\Http\\Controllers;\n\nclass ProfileController extends Controller\n{\n    public function index(int $id)\n    {\n        return $id;\n    }\n}\n```\n### Multiple Route Parameters\nYou can pass multiple parameter with route as like below\n```php\n\u003c?php\n\nuse App\\Http\\Controllers\\ProfileController;\n\nRoute::get('/user/{id}/{username}', [ProfileController::class, 'index']);\n```\nNow accept this multiple param in your controller like:\n```php\n\u003c?php\n\nnamespace App\\Http\\Controllers;\n\nclass ProfileController extends Controller\n{\n    public function index(int $id, string $username)\n    {\n        return $id;\n\n        return $username;\n    }\n}\n```\n\n\u003ca name=\"section-12\"\u003e\u003c/a\u003e\n\n## Optional Route Parameter\nDoppar accept optional parameter and for this, you have nothing to do.\n\u003e **⚠️ Warning:** By default, the Doppar controller callback takes parameters as optional. So, if you pass parameters in your route but do not accept them in the controller, it will not throw an error.\n\u003e\nExample\n```php\nRoute::get('/user/{id}/{username}', [ProfileController::class, 'index']);\n```\nif you visit `http://localhost:8000/user/1/mahedi-hasan`\n\n```php\n\u003c?php\n\nnamespace App\\Http\\Controllers;\n\nclass ProfileController extends Controller\n{\n    public function index()\n    {\n        return \"welcome\"; // Still works and you will get the response\n    }\n}\n```\n\n\u003ca name=\"section-13\"\u003e\u003c/a\u003e\n\n## Naming Route\n\nDoppar support convenient naming route structure. To create a naming route, you can do\n\n```php\n\nuse Phaseolies\\Support\\Facades\\Route;\nuse App\\Http\\Controllers\\UserController;\n\nRoute::get('/user/{id}/{name}', [UserController::class, 'profile'])-\u003ename('profile');\n```\nNow use this naming route any where using route() global method.\n```php\n \u003cform action=\"{{ route('profile', ['id' =\u003e 2, 'name' =\u003e 'mahedy']) }}\" method=\"post\"\u003e\n    @csrf\n    \u003cbutton type=\"submit\" class=\"btn btn-primary\"\u003eSubmit\u003c/button\u003e\n\u003c/form\u003e\n```\nIf there is single param in your route, just use\n```php\nRoute::get('/user/{id}', [UserController::class, 'profile'])-\u003ename('profile');\n```\nNow call the route\n```php\n{{ route('profile', 2) }}\n```\n\n### Define PUT, PATCH, DELETE Request Route\nIf you want to define route as a PUT, PATCH or DELETE, need to follow some rules. Assume, we are going to send a PUT request to the server, then you have to use @method('PUT') blade directive inside your HTML form.\n```html\n\u003cform method=\"POST\"\u003e\n    @csrf\n    @method('PUT')    // For PUT Request\n    @method('PATCH')  // For PATCH Request\n    @method('DELETE') // For DELETE Request\n    \u003cbutton type=\"submit\"\u003eSubmit\u003c/button\u003e\n\u003c/form\u003e\n```\n\nNow you are ready to define `PUT` route in `web.php` file\n```php\nRoute::put('/update-profile', [ProfileController::class, 'updateProfile']);\n\n// For DELETE and PATCH\nRoute::delete('/user/{id}', [ProfileController::class, 'delete']);\nRoute::patch('/update-profile', [ProfileController::class, 'updateProfile']);\n```\n\n### Route Group\n`Route::group` is used to group multiple routes under a shared configuration like middleware, URL prefix, namespace, etc. This helps in organizing routes cleanly and applying common logic to them.\n\n#### Syntax\n```php\nRoute::group([\n    'prefix' =\u003e 'your-prefix',\n    'middleware' =\u003e ['middleware-name']\n], function () {\n    // Routes go here\n});\n```\n\n#### Example\nLook at the below example, we are using `prefix` and `middleware` as a group route. You can use either `prefix` or `middleware` or both. See the example\n```php\nRoute::group([\n    'prefix' =\u003e 'login',\n    'middleware' =\u003e ['guest']\n], function () {\n    Route::get('/', [LoginController::class, 'index'])-\u003ename('login'); // url will be example.com/login\n    Route::post('/', [LoginController::class, 'login']); // url will be example.com/login\n});\n```\n`'prefix' =\u003e 'login'` This means all routes inside this group will be prefixed with `/login` and `'middleware' =\u003e ['guest']` Applies the guest` middleware to both routes.\n\n### Route Caching\nDoppar supports route caching for improved performance in production environments. Route caching is controlled by the `APP_ROUTE_CACHE` environment variable: Set to `true` to enable route caching (recommended for production). Set to `false` to disable (default for development) Route cache files are stored in: `storage/framework/cache/`\n#### Cache Routes\nGenerate a route cache file for faster route registration:\n```bash\nphp pool route:cache // Note: This should be run after any route modifications.\n```\n#### Clear Route Cache\n```bash\nphp pool route:clear // Use this when making route changes in production or if experiencing route-related issues.\n```\n\n\u003ca name=\"section-44\"\u003e\u003c/a\u003e\n## Eloquent ORM\n### Introduction\nDoppar features its own powerful data interaction tool, Eloquent, an object-relational mapper (ORM), which simplifies and enhances the way you work with your database. With ORM, every database table is linked to a dedicated \"Data Model\" that serves as your gateway to managing table data seamlessly. Beyond just fetching records, Doppar Data Mapper empowers you to effortlessly insert, update, and delete records, making database interactions intuitive and efficient. Whether you're building complex queries or handling simple data operations, ORM ensures a smooth and enjoyable experience, tailored to streamline your development workflow.\n\n### Creating Model Classes\nTo get started, let's create an Eloquent model. Models typically live in the app\\Models directory and extend the `Phaseolies\\Database\\Eloquent\\Model` class. You may use the `make:model` Pool command to generate a new model:\n```php\nphp pool make:model Invoice\n```\nThis command will generate a new model inside App\\Models directory. Models generated by the make:model command will be placed in the app/Models directory. Let's see a basic model class.\n```php\n\u003c?php\n\nnamespace App\\Models;\n\nuse Phaseolies\\Database\\Eloquent\\Model;\n\nclass Invoice extends Model\n{\n    //\n}\n```\n\n\u003ca name=\"section-45\"\u003e\u003c/a\u003e\n## Model Properties\nBefore diving into Doppar's data management capabilities, it’s important to familiarize yourself with some key model properties that shape how your data is handled. Doppar offers the flexibility to customize these properties to suit your specific needs. Key properties include `$pageSize`, which controls the number of records displayed per page; `$primaryKey`, which defines the unique identifier for your table; `$table`, which specifies the database table associated with the model; `$creatable`, which determines whether new records can be added; and `$unexposable`, which allows you to hide sensitive or irrelevant data from being exposed. With Doppar, you have full control to tweak these properties, ensuring your data interactions are both efficient and secure. Let's see the `User` model as for example.\n\n```php\n\u003c?php\n\nnamespace App\\Models;\n\nuse Phaseolies\\Database\\Eloquent\\Model;\n\nclass User extends Model\n{\n    /**\n     * Page Size\n     *\n     * Defines the number of records to be displayed per page when paginating results.\n     * This property is useful for controlling the size of data chunks returned by queries.\n     *\n     * @var int\n     */\n    protected $pageSize = 10;\n\n    /**\n     * Primary Key\n     *\n     * Specifies the column name that serves as the unique identifier for the table.\n     * By default, this is set to 'id', but it can be customized if your table uses a different primary key.\n     *\n     * @var string\n     */\n    protected $primaryKey = 'id';\n\n    /**\n     * Table Name\n     *\n     * Specifies the database table associated with this model\n     *\n     * @var string\n     */\n    protected $table = 'users';\n\n    /**\n     * Creatable Attributes\n     *\n     * Specifies which attributes can be mass-assigned when creating or updating records.\n     * This helps prevent mass assignment vulnerabilities by explicitly defining safe fields.\n     * Only the attributes listed here can be set in bulk operations.\n     *\n     * @var array\n     */\n    protected $creatable = ['name', 'username', 'email', 'password'];\n\n    /**\n     * Unexposable Attributes\n     *\n     * Specifies which attributes should be hidden when the model is converted to an array or JSON.\n     * This is particularly useful for hiding sensitive information, such as passwords,\n     * from being exposed in API responses or other outputs.\n     *\n     * @var array\n     */\n    protected $unexposable = ['password'];\n\n    /**\n     * Indicates whether the model should maintain timestamps (`created_at` and `updated_at` fields.).\n     *\n     * @var bool\n     */\n    protected $timeStamps = true;\n}\n\n```\n\n\u003ca name=\"section-46\"\u003e\u003c/a\u003e\n## Query Using ORM\n### Retrieving Models\nOnce you have created a model and its associated database table, you are ready to start retrieving data from your database. You can think of each Eloquent model as a powerful query builder allowing you to fluently query the database table associated with the model. The model's `all` method will retrieve all of the records from the model's associated database table:\n```php\nuse App\\Models\\Invoice;\n\nforeach (Invoice::all() as $invoice) {\n    echo $invoice-\u003einvoice_id;\n}\n\n// You can also use Invoice::get() to get all the records\n```\n\n### Building Queries\nThe Eloquent all method will return all of the results in the model's table. However, since each Eloquent model serves as a query builder, you may add additional constraints to queries and then invoke the get method to retrieve the results:\n\n```php\n$flights = Invoice::query()\n    -\u003ewhere('active', '=', 1)\n    -\u003eorderBy('name')\n    -\u003elimit(10)\n    -\u003eget();\n```\n\n### Multiple Where Condition\nYou can write query with multiple where condition by chaining multiple where with the queries\n```php\nUser::query()\n    -\u003ewhere('name', '=', 'Sincere Littel')\n    -\u003ewhere('username', '=', 'doppar')\n    -\u003efirst();\n```\n\nYou can also add `orWhere()` as like below\n```php\nUser::query()\n    -\u003ewhere('name', '=', 'Sincere Littel')\n    -\u003eorWhere('username', '=', 'test')\n    -\u003eget();\n```\n\n### Fetch the First Records\nTo fetch the first records you can use `first` function as like below\n```php\nUser::query()-\u003efirst();\n```\n\n### GroupBy and OrderBy\nYou can also use `groupBy()` and `orderBy()` to handle your records like\n```php\nUser::query()-\u003eorderBy('id', 'desc')-\u003egroupBy('name')-\u003eget();\n```\n\n### toSql()\nYou can get the sql query to see which query is running to fetch the records like\n```php\nUser::query()-\u003eorderBy('id', 'desc')-\u003egroupBy('name')-\u003etoSql();\n```\n\n### Count The Result\nTo see how many records your table has, you can use `count` function as like\n```php\nUser::count();\n// or\nUser::query()-\u003eorderBy('id', 'desc')-\u003egroupBy('name')-\u003ecount();\n// or you can pass the column name which you need to count\nUser::query()-\u003ewhere('active', '=', true)-\u003ecount('id');\n```\n\n### Newest and Oldest Records\nTo fetch the oldest and newest records, Doppar provides two function `newest` and `oldest`. \n```php\nUser::query()-\u003enewest()-\u003eget();\n\n// You can explicitly define which field should be used to retrieve the latest records. By default, it uses the 'id' field.\nUser::query()-\u003enewest('name')-\u003eget()\n\nUser::query()-\u003eoldest()-\u003eget()\n\n// You can explicitly define which field should be used to retrieve the latest records. By default, it uses the 'id' field.\nUser::query()-\u003eoldest('id')-\u003eget()\n```\n\n### select()\nYou may need to fetch only some specific columns not all the columns from a model. you can use select() method in this case like\n```php\nUser::query()-\u003eselect(['name','email'])-\u003eget();\n```\n\n### find() and exists()\nIf you need to retrieve data for a specific primary key, you can use the `find()` function. This method allows you to quickly fetch a single record by its unique identifier, making it a convenient and efficient way to access individual entries in your database.\n```php\nUser::find(1)\n```\n\nTo check whether a specific row exists in your database, you can use the `exists()` function. This method returns a boolean value (`true` or `false`) based on whether the specified condition matches any records. Here's an example:\n```php\nUser::query()-\u003ewhere('id', '=', 1)-\u003eexists(); // Returns `true` if a matching row exists, otherwise `false`.\n```\n\n### Create Data\nTo create data, Doppar uses the `create` method. It retrieves the attributes defined in your model's `$creatable` property and inserts them into the database. For example:\n\n```php\nuse App\\Models\\User;\n\nUser::create([\n    'name' =\u003e 'Doppar'\n]);\n```\n\nOr you also create data using object\n```php\n$user = new User;\n$user-\u003ename = $request-\u003ename;\n$user-\u003eSave();\n```\n\n### saveMany()\nYou may need to insert bacth insert in your model, in this case, you can use `saveMany()` method as like below\n```php\nUser::saveMany([\n    ['name' =\u003e 'John', 'email' =\u003e 'john@example.com', 'password' =\u003e bcrypt('password')],\n    ['name' =\u003e 'Jane', 'email' =\u003e 'jane@example.com', 'password' =\u003e bcrypt('password')],\n    ['name' =\u003e 'Bob', 'email' =\u003e 'bob@example.com', 'password' =\u003e bcrypt('password')]\n]);\n```\n\nIf your dataset is large, you can optionally pass the chunk size as the second parameter like\n```php\nUser::saveMany([\n    ['name' =\u003e 'John', 'email' =\u003e 'john@example.com', 'password' =\u003e bcrypt('password')],\n    ['name' =\u003e 'Jane', 'email' =\u003e 'jane@example.com', 'password' =\u003e bcrypt('password')],\n    ['name' =\u003e 'Bob', 'email' =\u003e 'bob@example.com', 'password' =\u003e bcrypt('password')]\n], 100);\n```\n\n### Update Data\nTo update data, you can use `fill` function like\n```php\n$user = User::find(1);\n$user-\u003efill(['name' =\u003e 'Updated Name']);\n$user-\u003esave();\n```\n\nOr you can use `update` function like\n```php\n\nUser::query()\n    -\u003ewhere('id', '=', 1)\n    -\u003eupdate([\n        'email' =\u003e  'hi@doppar.com'\n    ]);\n```\n\n### updateOrCreate()\nThe updateOrCreate() method is used to either update an existing record or create a new one if no matching record is found. It simplifies handling scenarios where you need to ensure a record exists with specific attributes while updating other fields.\n```php\n$user = User::updateOrCreate(\n    ['email' =\u003e 'hi@doppar.com'], // attributes to match\n    ['name' =\u003e 'Test User'] // values to update/create\n);\n```\n\n### Delete Data\nTo delete data, doppar provides `delete` method\n```php\nUser::find(1)-\u003edelete();\n```\n\n### whereIn()\nThe `whereIn()` method filters records where a column's value matches any value in the given array.\n```php\nreturn User::query()-\u003ewhereIn('id', [1, 2, 4])-\u003eget();\n```\nThis retrieves all users with id values of 1, 2, or 4.\n\n### orWhereIn()\nThe `orWhereIn()` method filters records where a column's value optionally matches any value in the given array.\n```php\nreturn User::query()-\u003eorWhereIn('id', [1, 2, 4])-\u003eget();\n```\n\n### whereBetween()\nThe `whereBetween()` method allows you to filter records where a given column's value falls within a specified range. This is commonly used for date or numerical ranges.\n```php\n return User::query()\n    -\u003ewhereBetween('created_at', ['2025-02-29', '2025-04-29'])\n    -\u003eget();\n```\n\n### whereNotBetween()\nThe `whereNotBetween()` method allows you to filter records where a given column's value do not falls within a specified range. This is commonly used for date or numerical ranges.\n```php\n return User::query()\n    -\u003ewhereNotBetween('created_at', ['2025-02-29', '2025-04-29'])\n    -\u003eget();\n```\n\n### orWhereBetween()\nYou can use `orWhereBetween()` methods together to create complex conditional queries. This allows for more flexible filtering, including combining conditions with OR for specific ranges.\n```php\nreturn Post::query()\n    -\u003ewhere('status', ,'=', 'published') // Filter posts that are published\n    -\u003eorWhereBetween('views', [100, 500]) // Or filter posts where views are between 100 and 500\n    -\u003eget();\n```\n\n### orWhereNotBetween()\nYou can use `orWhereNotBetween()` methods together to create complex conditional queries. This allows for more flexible filtering, including combining conditions with OR for specific ranges.\n```php\nreturn Post::query()\n    -\u003ewhere('status', ,'=', 'published')\n    -\u003eorWhereNotBetween('views', [100, 500])\n    -\u003eget();\n```\n\nWith request input example\n```php\nPost::query()\n    -\u003eif($request-\u003ehas('date_range'), function($query) use ($request) {\n        $query-\u003ewhereBetween('created_at', [\n            $request-\u003einput('date_range.start'),\n            $request-\u003einput('date_range.end')\n        ]);\n    })\n    -\u003eget();\n```\n\n### whereNull()\nThe `whereNull()` method in Eloquent is used to filter records where a specific column contains a NULL value. In your example:\n```php\nreturn Post::query()\n    -\u003ewhereNull('created_at')\n    -\u003eget();\n```\n\n### whereNotNull()\nThe `whereNotNull()` method in Eloquent is used to filter records where a specific column contains a value. In your example:\n```php\nPost::query()\n    -\u003ewhereNotNull('published_at')\n    -\u003eget();\n```\n\n### orWhereNull()\nThe `orWhereNull()` method in Eloquent is used to add an OR condition to the query, checking if a column is NULL. In your example:\n```php\nPost::query()\n    -\u003ewhere('status', '=', 'draft')\n    -\u003eorWhereNull('reviewed_at') // you can also use orWhereNotNull()\n    -\u003eget();\n```\n\n### orWhereNotNull()\nThe `orWhereNotNull()` method in Eloquent is used to add an OR condition to the query, checking if a column is not NULL. In your example:\n```php\nPost::query()\n    -\u003ewhere('status', '=', 'draft')\n    -\u003eorWhereNotNull('reviewed_at')\n    -\u003eget();\n```\n\n### match()\nThe `match()` method in Eloquent is commonly used to filter your query result. It's typically implemented to provide a more flexible and reusable way to filter results based on various conditions.\n```php\nreturn Post::match([\n        'id' =\u003e 1,\n        'user_id' =\u003e 1\n    ])-\u003eget();\n```\n\nComplex filtering with callbacks\n```php\nreturn Post::match(function ($query) {\n        $query-\u003ewhere('views', '\u003e', 100)\n            -\u003ewhereBetween('created_at', ['2023-01-01', '2023-12-31']);\n    })-\u003eget();\n```\n\nRequest data filter, this will fetch data as per requested `title` and `user_id`\n```php\nPost::match($request-\u003eonly(['title', 'user_id']))\n    -\u003epaginate();\n```\n\nCombine simple and complex filters\n```php\nPost::match([\n        'user_id' =\u003e [1, 2, 3], // WHERE IN\n        'created_at' =\u003e null,      // WHERE NULL\n        'active' =\u003e function ($query) {\n            $query-\u003ewhere('active', '=', 1)\n                -\u003eorWhere('legacy', '=', 1);\n        }\n    ])-\u003eorderBy('created_at', 'desc')\n    -\u003eget();\n```\n\n### pluck()\nThe `pluck()` method is used to retrieve the values of a single column from the result set. It returns an array or collection of the specified column's values, making it useful for quickly getting a list of specific data\n```php\nreturn Post::query()-\u003epluck('title');\n```\n\n### useRaw() for Custom Queries with Parameter Bindings\nThe useRaw() method allows you to run raw SQL queries with parameter bindings, which helps prevent SQL injection by safely binding parameters to the query.\n```php\nreturn User::query()-\u003euseRaw(\n    'SELECT * FROM user WHERE created_at \u003e ? AND status = ?',\n    ['2023-01-01', 'active']\n);\n```\nis runs a custom SQL query that retrieves users created after January 1, 2023, and with an active status. The values 2023-01-01 and active are securely bound to the query to prevent SQL injection.\n\n\u003ca name=\"section-51\"\u003e\u003c/a\u003e\n### Introduction\nDatabase tables are often interconnected, representing real-world relationships between data. For instance, a blog post can have multiple comments, or an order may be linked to the user who placed it. Eloquent simplifies handling these relationships, providing built-in support for various types. Doppar supports three eloquent relationships.\n\n- One-to-One\n- One-to-Many\n- Many-to-Many\n\n### Defining Relationships (One-to-One)\nEloquent allows you to define relationships as methods within your model classes, enabling seamless method chaining and advanced query capabilities. This makes it easy to interact with related models while maintaining clean and efficient code.\n\nFor instance, let's assume each `Article` has a single associated `User` (author). We can define this one-to-one relationship in the `Article` model as follows:\n```php\n\u003c?php\n\nnamespace App\\Models;\n\nuse Phaseolies\\Database\\Eloquent\\Model;\n\nclass Article extends Model\n{\n    protected $table = 'articles';\n\n    public function user()\n    {\n         return $this-\u003eoneToOne(\n            User::class,    // Related model class\n            'id',           // Foreign key on related table (users.id)\n            'user_id'       // Local key on this table (articles.user_id)\n        );\n    }\n}\n```\n## Key Parameters for Defining Relationships\n\nWhen defining relationships in your Eloquent models, you'll typically use these key parameters:\n\n* **Related Model:**\n    * This specifies the class name of the model you're establishing a relationship with.\n    * Example: `User::class`\n* **Foreign Key:**\n    * This refers to the column in the *related* table that stores the foreign key, which references the primary key of the current model.\n    * It is the column that makes the connection between the 2 tables.\n* **Local Key:**\n    * This is the column in the *current* model's table that is being referenced by the foreign key in the related table.\n    * Usually this is the primary key of the current table.\n\nOnce defined, you can access the relationship in several ways:\n\n#### As a Property (Lazy Loading)\n```php\n$article = Article::find(1);\n$author = $article-\u003euser; // Automatically loads the related user\n```\n\nFetching all the articles of user id 1\n```php\nreturn User::find(1)\n    -\u003earticles() // fetching all the articles of user id 1\n    -\u003eget();\n```\n\nOr you can fetch above data as follows also\n```php\nreturn User::find(1)-\u003earticles;\n```\n\n#### As a Method (Query Builder)\n```php\n$article = Article::find(1);\n$activeAuthor = $article-\u003euser()\n    -\u003ewhere('status', '=', 1)\n    -\u003efirst();\n```\n\n#### With Eager Loading\n```php\n// Load articles with their authors in a single query\n$articles = Article::query()-\u003eembed('user')-\u003eget();\n\nforeach ($articles as $article) {\n    echo $article-\u003euser-\u003ename; // No additional query executed\n}\n```\n#### embed() with sub query\nThis will return articles with user data where the user status is 1. If the user status is 0, it will return null for the user but still load the articles.\n```php\nreturn Article::query()-\u003eembed(['user' =\u003e function ($query) {\n            $query-\u003ewhere('status', '=', 1);\n        }])-\u003eget();\n```\n\n### Defining Relationships (One-to-Many)\nFor instance, let's assume each `User` has its associated `articles`. We can define this one-to-many relationship in the `User` model as follows:\n```php\n\u003c?php\n\nnamespace App\\Models;\n\nuse Phaseolies\\Database\\Eloquent\\Model;\n\nclass User extends Model\n{\n    protected $table = 'users';\n\n    public function articles()\n    {\n         return $this-\u003eoneToMany(\n            Article::class, // Related model class\n            'user_id', // Foreign key on related table (articles.user_id)\n            'id'       // Local key on this table (users.id)\n        );\n    }\n}\n```\n\nNow you can fetch all the users with their associated articles.\n```php\nreturn User::query()-\u003eembed('articles')-\u003eget();\n```\n\n### Defining Relationships (Many-to-Many)\nDoppar ORM supports many-to-many relationships through an intermediate pivot table. Here's how to implement and work with them. Assume we have a `Post` model and a `Tag` model, where a many-to-many relationship exists between them. This means one post can have multiple tags, and one tag can be associated with multiple posts.\n```php\n// App\\Models\\Post.php\npublic function tags()\n{\n    return $this-\u003emanyToMany(\n        Tag::class,  // Related model\n        'post_id',   // Foreign key for posts in pivot table (post_tag.post_id)\n        'tag_id',    // Foreign key for tags in pivot table (post_tag.tag_id)\n        'post_tag'   // Pivot table name\n    );\n}\n```\nAnd the Tag model will be look like this\n```php\n// App\\Models\\Tag.php\npublic function tags()\n{\n    public function posts()\n    {\n        return $this-\u003emanyToMany(\n            Post::class,  // Related model\n            'tag_id',   // Foreign key for tags in pivot table\n            'post_id',  // Foreign key for posts in pivot table\n            'post_tag'  // Pivot table name\n        );\n    }\n}\n```\nIn a many-to-many relationship between `Post` and `Tag`, the `post_tag` pivot table acts as a bridge, storing the associations between `posts` and `tags`. It contains two columns:\n\n- `post_id` – References the id of a post.\n- `tag_id` – References the id of a tag.\n\nEach row in this table represents a link between a specific post and a specific tag, allowing multiple posts to have multiple tags and vice versa.\n\n#### Retrieving Related Models From Many To Many Relationship\nWe can fetch data from many to many relationship using eager loading like that\n```php\nreturn Post::query()-\u003eembed('tags')-\u003eget();\n```\n\nYou can fetch Tag with posts as well\n```php\nreturn Tag::query()-\u003eembed('posts')-\u003eget();\n```\n\n### Many To Many Relationship with Lazy loading\nIn Doppar, when dealing with a many-to-many relationship, lazy loading allows you to retrieve related records only when they are accessed. For instance, if a Post model has a many-to-many relationship with a Tag model, you can fetch all the tags of a specific post using the following query:\n```php\n$post = Post::find(1);\nreturn $post-\u003etags;\n\n// or simply you can call like that\nreturn $post = Post::find(1)-\u003etags;\n```\n\nFor instance, if a Tag model has a many-to-many relationship with a Post model, you can fetch all the posts of a specific tag using the following query:\n```php\n$tag = Tag::find(1);\nreturn $tag-\u003eposts;\n\n// Get the posts related to a specific tag\nforeach ($tag-\u003eposts as $post) {\n    echo $post-\u003etitle;\n}\n```\n\n### link() with manyToMany\nIn Doppar, the `link()` method is used to associate records in a many-to-many relationship. This method adds entries to the pivot table, establishing a connection between related models\n```php\n// Link tags to a post\n$post = Post::find(1);\n$post-\u003etags()-\u003elink([1, 2, 3]); // Link tags with IDs 1, 2, and 3\n```\n\n### unlink() with manyToMany\nIn Doppar, the `unlink()` method is used to unlink specific records from a many-to-many relationship. It removes the association between the current model (e.g., Post) and the related model (e.g., Tag) by removing the corresponding entries from the pivot table.\n```php\n$post = Post::find(1);\n$post-\u003etags()-\u003eunlink([1, 2, 3]); // Unlink tags with IDs 1, 2, and 3\n```\n\nIf you simply call `unlink()`, it will delete all the tags\n```php\n$post = Post::find(1);\n$post-\u003etags()-\u003eunlink(); // unlink all tags\n```\n\n### relate() with manyToMany\nIn Doppar, the `relate()` method is used to sync the relationships between models in a many-to-many relationship. The `relate()` method will attach the provided IDs and can optionally detach existing relationships, depending on the second argument passed.\n```php\n$post = Post::find(1);\n$post-\u003etags()-\u003erelate([1, 2, 3]);\n$changes = $post-\u003etags()-\u003erelate([1, 2, 4]); // 3 will be removed\n$post-\u003etags()-\u003erelate([1, 2, 3], false); // link tithout unlinking\n```\n\n### Syncing with Pivot Data Using \nIn Doppar, the `relate()` method not only allows you to sync records in a many-to-many relationship, but also provides the ability to attach additional data to the pivot table. This is useful when you need to store extra attributes (such as timestamps or other metadata) along with the relationship between two models.\n```php\n$post = Post::find(1);\n$post-\u003etags()-\u003erelate([\n    1 =\u003e ['created_at' =\u003e now()],\n    2 =\u003e ['featured' =\u003e true],\n    3 =\u003e ['meta' =\u003e ['color' =\u003e 'blue']]\n]);\n```\n\n### Nested Relationship\nTo efficiently retrieve all posts along with their associated comments, replies, and the users who made those replies, use the following query:\n```php\nreturn Post::query()-\u003eembed('comments.reply.user')-\u003eget();\n```\n#### Breakdown:\n- comments → Fetches all comments related to the post.\n- reply → Fetches replies associated with each comment.\n- user → Fetches the user who authored each reply.\n\nBy using eager loading (embed), this query minimizes database queries and optimizes performance, ensuring efficient data retrieval.\n\n\n### Specific Column Selection\nThe embed() method in Doppar ORM allows you to eager load related models and even specify which columns to load for each relationship. This helps optimize queries by only selecting the necessary data.\n```php\nUser::query()\n    -\u003eembed([\n        'comments.reply', // Load all columns of the related comments\n        'posts' =\u003e function ($query) {\n            $query-\u003eselect(['id', 'title', 'user_id']); // Only load specific columns for posts\n        }\n    ])\n    -\u003eget();\n```\n\n#### Fetching Multiple Relationships\nThis query retrieves `users` along with their related `articles` and `address` using the embed method. By embedding multiple relationships, it ensures that all necessary data is fetched in a single query, improving efficiency and reducing additional database calls.\n```php\nreturn User::query()\n        -\u003eembed(['articles','address'])\n        -\u003eget();\n```\n\n### Using `present()` for Handling Present Relationships\nIn Doppar ORM, the `present()` method can be used to load relationships that are present (i.e., do not exist) in the model, or when you want to ensure related data is included, even if it is not empty.\n```php\nreturn Post::query() // Fetch only those posts which have comments\n    -\u003epresent('comments') // Load the 'comments' relationship\n    -\u003eget();\n```\nThis method is useful when you want to include relationships and need to fetch only those data that has relational data.\n\n#### Passing callback with present()\nThe `present()` method can be used to load a relationship with custom query conditions. You can define specific conditions inside the closure passed to `present()` to filter the related data.\n```php\nreturn Post::query()\n    -\u003epresent('comments', function ($query) {\n        $query-\u003ewhere('comment', '=', 'Mrs.') // Filter comments with the text 'Mrs.'\n              -\u003ewhere('created_at', '=', NULL); // Only fetch comments with no creation date\n    })\n    -\u003eget();\n```\n\n### absent() to Fetch Records with Missing Relationships\nThe `absent()` method is used to fetch records where a particular relationship does not exist. This is useful when you want to retrieve records that are missing related data.\n```php\nreturn User::query() // Fetch only those users who have no posts\n    -\u003eabsent('posts') // Filter users with no related posts\n    -\u003eget();\n```\n\n### if() for Conditional Query Execution in Doppar ORM\nDoppar ORM's `if()` method allows you to conditionally add query constraints based on a given condition. If the condition evaluates to true, the corresponding query modification is applied; otherwise, it is skipped.\n```php\nPost::query()\n    -\u003eif($request-\u003einput('search'),\n        fn($q) =\u003e $q-\u003ewhere('title', 'LIKE', \"%{$request-\u003esearch}%\"),\n        fn($q) =\u003e $q-\u003ewhere('is_featured', '=', true) // default if no search is applied, and it is optional\n    )\n    -\u003eget();\n```\n#### Explanation:\n- First condition `($request-\u003einput('search'))`: If the search parameter is provided, the query will filter posts by the title using the LIKE operator.\n- Default case: If no search parameter is provided, it will filter posts where is_featured is true.\n\n### How `if()` Works with Different Conditions\nWill execute when the condition is truthy:\n```php\nPost::query()\n    -\u003eif(true, fn($q) =\u003e $q-\u003ewhere('active', '=', true)) // Executes because true\n    -\u003eif('text', fn($q) =\u003e $q-\u003ewhere('title', '=', 'text')) // Executes because 'text' is truthy\n    -\u003eif(1, fn($q) =\u003e $q-\u003ewhere('views', '=', 1)) // Executes because 1 is truthy\n    -\u003eif([1], fn($q) =\u003e $q-\u003ewhereIn('id', '=', [1])) // Executes because [1] is truthy\n    -\u003eget();\n```\n\nWill NOT execute when the condition is falsy:\n```php\nPost::query()\n    -\u003eif(false, fn($q) =\u003e $q-\u003ewhere('active', '=', false)) // Does not execute because false\n    -\u003eif(0, fn($q) =\u003e $q-\u003ewhere('views', '=', 0)) // Does not execute because 0 is falsy\n    -\u003eif('', fn($q) =\u003e $q-\u003ewhere('title', '=', '')) // Does not execute because empty string is falsy\n    -\u003eif(null, fn($q) =\u003e $q-\u003ewhere('deleted_at', '=', null)) // Does not execute because null is falsy\n    -\u003eif([], fn($q) =\u003e $q-\u003ewhereIn('id', '=',  [])) // Does not execute because empty array is falsy\n    -\u003eget();\n```\nThis makes the if() method powerful for dynamically building queries based on various conditions. It allows for more concise and flexible query building without having to manually check each condition before applying the relevant query changes.\n\n### present() with if()\nYou can chain the `present()` method with `if()` to conditionally load a relationship with specific query constraints, based on dynamic conditions. This allows for more flexible and powerful query building.\n```php\nreturn Post::query()\n    -\u003epresent('comments', function ($query) {\n        $query-\u003ewhere('comment', '=', 'Mrs.') // Filter comments with 'Mrs.'\n            -\u003ewhere('created_at', '=', NULL); // Only include comments with no creation date\n    })\n    -\u003eif($request-\u003etitle, function ($query) use ($request) {\n        $query-\u003ewhere('title', '=', $request-\u003etitle); // Apply title filter if provided in the request\n    })\n    -\u003eget();\n```\n\n### ifExists() check relationship existance\nThe `ifExists()` method in Doppar is used as a conditional check to determine whether a related model (e.g., posts) exists in the database for a given parent model (e.g., users). This method is useful for filtering results based on the existence of related data without requiring explicit joins or additional queries.\n```php\n// Find users who have at least one post\nreturn User::query()-\u003eifExists('posts')-\u003eget();\n```\nWith conditions - find users who have at least one published post\n```php\n return User::query()\n    -\u003eifExists('posts', function ($query) {\n        $query-\u003ewhere('status', '=', 'published');\n    })\n    -\u003eget();\n```\n\n### ifNotExists() check relationship non-existance\nIn the Doppar framework, the `ifNotExists()` method works similarly to the `ifExists()` method but with the inverse logic. Instead of filtering users who have at least one post, it retrieves users who don't have any related posts. This can be useful when you want to find records without any associated data.\n```php\n// Find users who don't have any posts\nreturn User::query()-\u003eifNotExists('posts')-\u003eget();\n```\n\n### Aggregation Queries using ORM\nDoppar ORM provides powerful aggregation functions to perform statistical calculations efficiently. Below are various examples of aggregation queries you can use in your application.\n#### Total Sum of a Column\nCalculate the total sum of a column (e.g., summing up all views values):\n```php\nPost::query()-\u003esum('views');\n```\n\n#### Average Value of a Column\nCompute the average value of a column (e.g., the average views):\n```php\nreturn Post::query()-\u003eavg('views');\n```\n\n#### Maximum Value in a Column\nFind the highest price in the Product table:\n```php\nProduct::query()-\u003emax('price');\n```\n\n#### Minimum Value in a Column\nFind the lowest `price` in the Product table:\n```php\nProduct::query()-\u003emax('price');\n```\n\n#### Standard Deviation Calculation\nCompute the standard deviation of `price`:\n```php\nreturn Product::query()-\u003estdDev('price');\n```\n#### Variance Calculation\nFind the variance of `price`:\n```php\nreturn Product::query()-\u003evariance('price');\n```\n\n#### Multiple Aggregation in One Query\nRetrieve multiple statistics (`count`, `average`, `min`, `max`) in a single query:\n```php\nProduct::query()\n    -\u003eselect([\n        'COUNT(*) as count',\n        'AVG(price) as avg_price',\n        'MIN(price) as min_price',\n        'MAX(price) as max_price'\n    ])\n    -\u003egroupBy('variants')\n    -\u003efirst();\n```\n\n#### Fetching Distinct Rows\nYou can also fetch `distinct` rows from your table by chanining the `distinct()` function as like below. This will fetch unique values from `post` table of `user_id` column\n```php\nPost::query()-\u003edistinct('user_id');\n```\n\n#### Calculating Sum\nSum up sales where title is \"maiores\":\n```php\nProduct::query()\n    -\u003ewhere('title', '=', 'maiores')\n    -\u003esum('price');\n```\n\n#### Total Sales by Category\nCalculate total sales per category by grouping results:\n```php\nreturn Product::query()\n    -\u003eselect(['category_id', 'SUM(price * quantity) as total_sales'])\n    -\u003egroupBy('category_id')\n    -\u003eget();\n```\n\n### increment()\nSometimes, we need to `increment` a specific column. In this case, you can use `increment` as shown below. The example below will `increment` the post by 1.\n```php\n$post = Post::find(1);\n$post-\u003eincrement('views'); // default increment by 1\n$post-\u003eincrement('views',10); // increment by 10\n```\nIncrement a post's views count by 1 while updating the timestamp and modifier:\n```php\n$post-\u003eincrement('views', 1, [\n    'updated_at' =\u003e date('Y-m-d H:i:s'),\n    'modified_by' =\u003e Auth::id()\n]);\n```\n\n### decrement()\nSometimes, we need to `decrement` a specific column. In this case, you can use `decrement` as shown below. The example below will `decrement` the post by 1.\n```php\n$post = Post::find(1);\n$post-\u003edecrement('views'); // default decrement by 1\n$post-\u003edecrement('views',10); // decrement by 10\n```\nIncrement a post's views count by 1 while updating the timestamp and modifier:\n```php\n$post-\u003edecrement('views', 1, [\n    'updated_at' =\u003e date('Y-m-d H:i:s'),\n    'modified_by' =\u003e Auth::id()\n]);\n```\n\n\u003ca name=\"section-52\"\u003e\u003c/a\u003e\n## Transform Eloquent Collection\n\nYou can transform a fetched Eloquent collection using the `map` function. This allows you to modify or format the data before returning it.\n\nHere’s an example of how to extract and return only the name attribute from each user:\n```php\nreturn User::all()-\u003emap(function ($item) {\n    return [\n        'name' =\u003e $item-\u003ename\n    ];\n});\n```\nThis approach is useful when you need to customize the response structure while working with Eloquent collections.\n\n\u003ca name=\"section-47\"\u003e\u003c/a\u003e\n\n## Pagination\nPagination is a powerful feature that allows you to retrieve and display large datasets in smaller, manageable chunks. In Doppar, you can easily paginate your query results using the `paginate()` method. This method automatically handles the logic for splitting data into pages, making it ideal for scenarios like displaying user lists, logs, or any other dataset that requires.\n\n### Example:\nTo paginate a list of users sorted by their id in descending order, you can use the following query:\n```php\n\u003c?php\n\nnamespace App\\Http\\Controllers;\n\nuse App\\Models\\User;\nuse App\\Http\\Controllers\\Controller;\n\nclass AppTestController extends Controller\n{\n    public function index()\n    {\n        $users = User::query()-\u003eorderBy('id', 'desc')-\u003epaginate();\n\n        return view('user', [\n            'data' =\u003e $users\n        ]);\n    }\n}\n```\n### Display Pagination in Views\nWhen working with paginated data in your views, Doppar provides two convenient methods to render pagination links. These methods allow you to display navigation controls for moving between pages, ensuring a smooth user experience.\n#### Available Methods:\n * `linkWithJumps()` method generates pagination links with additional \"jump\" options, such as `dropdown with paging`. It is ideal for datasets with a large number of pages, as it allows users to quickly navigate to the beginning or end of the paginated results.\n * `links()` This method generates standard pagination links, including \"Previous\" and \"Next\" buttons, along with page numbers. It is suitable for most use cases and provides a clean and simple navigation interface.\n\nNow call the pagination for views\n```html\n@foreach ($data['data'] as $user)\n    \u003ctr\u003e\n        \u003ctd\u003e{{ $user-\u003eid }}\u003c/td\u003e\n        \u003ctd\u003e{{ $user-\u003ename }}\u003c/td\u003e\n        \u003ctd\u003e{{ $user-\u003eusername }}\u003c/td\u003e\n        \u003ctd\u003e{{ $user-\u003eemail }}\u003c/td\u003e\n    \u003c/tr\u003e\n@endforeach\n\n{!! paginator($data)-\u003elinks() !!} // \"Previous\" and \"Next\" buttons, along with page numbers.\n{!! paginator($data)-\u003elinkWithJumps() !!} // \"Previous\" and \"Next\" buttons, along with page jump options.\n```\n\n### Customize Default Pagination\nDoppar provides a Bootstrap 5 pagination view by default. However, you can also customize this view to suit your needs. To customize the pagination view, Doppar offers the `publish:pagination` pool command. Running this command will create two files, `jump.blade.php` and `number.blade.php`, inside the `resources/views/pagination` folder. These files allow you to tailor the pagination design to match your application's style.\n\n```bash\nphp pool publish:pagination\n```\n\nOnce you modify the `jump.blade.php` and `number.blade.php` files, the changes will immediately reflect in your pagination view. This allows you to fully customize the appearance and behavior of the pagination links to align with your application's design and requirements. Feel free to update these files as needed to create a seamless and visually consistent user experience.\n\n\u003ca name=\"section-53\"\u003e\u003c/a\u003e\n\n## Database Transactions\nA database transaction is a sequence of database operations that are executed as a single unit. Transactions ensure data integrity by following the ACID properties (Atomicity, Consistency, Isolation, Durability). If any operation within the transaction fails, the entire transaction is rolled back, preventing partial updates that could leave the database in an inconsistent state.\n\nDoppar provides built-in support for handling database transactions using the `DB::transaction()` method, `DB::beginTransaction()`, `DB::commit()`, and `DB::rollBack()`.\n\n### Using DB::transaction() for Simplicity\nThe `DB::transaction()` method automatically handles committing the transaction if no exception occurs and rolls it back if an exception is thrown.\n```php\nDB::transaction(function () {\n    $user = User::create(['name' =\u003e 'Mahedi']);\n    $post = Post::create(['user_id' =\u003e $user-\u003eid, 'title' =\u003e 'First Post']);\n});\n```\n\n### Manually Handling Transactions\nIn cases where more control is needed, transactions can be manually started using DB::beginTransaction(). The operations must then be explicitly committed or rolled back.\n```php\nDB::beginTransaction();\ntry {\n    $user = User::create([\n        'name' =\u003e 'Mahedi',\n        'email' =\u003e fake()-\u003eemail,\n        'password' =\u003e bcrypt('password'),\n    ]);\n\n    Post::create([\n        'title' =\u003e 'My very first post',\n        'user_id' =\u003e $user-\u003eid\n    ]);\n\n    DB::commit();\n} catch (\\Exception $e) {\n    DB::rollBack();\n    throw $e;\n}\n```\n\n### Handling Deadlocks with Transaction Retries\nDeadlocks can occur when multiple transactions compete for the same database resources. Doppar allows setting a retry limit for transactions using a second parameter in `DB::transaction()`.\n```php\nDB::transaction(function () {\n    // Operations that might deadlock\n}, 3); // Will attempt up to 3 times before throwing an exception\n```\nThis approach helps mitigate issues caused by deadlocks by retrying the transaction a set number of times before ultimately failing.\n\nUsing transactions properly ensures database consistency and prevents data corruption due to incomplete operations. Doppar provides flexible methods for handling transactions, allowing both automatic and manual control based on the use case.\n\n\u003ca name=\"section-54\"\u003e\u003c/a\u003e\n\n## Manual Join\nIn Doppar, Eloquent manual joins allow you to retrieve data from multiple tables based on a related column. The join method in Eloquent's Query Builder provides an easy way to combine records from different tables. This document explains how to perform various types of joins manually using Eloquent's Eloquent ORM and Query Builder.\n\n### Basic Join Example\nA simple join operation can be performed using the `join` method to combine records from two tables based on a common key. Below is an example of joining `users` and `posts` tables:\n```php\n$users = User::query()\n    -\u003ejoin('posts', 'users.id', '=', 'posts.user_id')\n    -\u003eget();\n```\nThis will return a dataset containing user data which has at least one post.\n\n### Specifying Join Type\nBy default, Doppar performs an `INNER JOIN`. You can specify the type of join you want by passing the join type as an argument:\n```php\n$users = User::query()\n    -\u003ejoin('posts', 'users.id', '=', 'posts.user_id', 'left')\n    -\u003eget();\n```\nHere, a `LEFT JOIN` is used to include all users, even if they do not have associated posts.\n\n### Applying Conditions in Joins\nYou can apply additional conditions to filter the joined data. The example below joins the posts table and fetches only the users who have published posts:\n```php\n$users = User::query()\n    -\u003ejoin('posts', 'users.id', '=', 'posts.user_id')\n    -\u003ewhere('posts.published', '=', true)\n    -\u003eorderBy('users.name', 'ASC')\n    -\u003eget();\n```\n\n### Performing Multiple Joins\nYou can join multiple tables in a single query. The example below joins the `users`, `posts`, and `comments` tables:\n```php\n$users = User::query()\n    -\u003ejoin('posts', 'users.id', '=', 'posts.user_id')\n    -\u003ejoin('comments', 'posts.id', '=', 'comments.post_id')\n    -\u003eget();\n```\nThis will return data containing users, their posts, and associated comments.\n\n### Selecting Specific Columns\nTo optimize queries and improve performance, you can select specific columns instead of retrieving all fields:\n```php\n$users = User::query()\n    -\u003eselect(['users.name', 'posts.title'])\n    -\u003ejoin('posts', 'users.id', '=', 'posts.user_id')\n    -\u003eget();\n```\nThis query retrieves only the `users.name` and `posts.title` fields, reducing the amount of data transferred.\n\n\u003ca name=\"section-56\"\u003e\u003c/a\u003e\n\n## Database Operations with `DB` Facade\nThe Doppar Framework provides a powerful and elegant DB Facade under the namespace `Phaseolies\\Support\\Facades\\DB`. This facade offers a fluent and expressive interface to interact with your database, allowing you to perform a variety of operations such as `querying`, `inserting`, `updating`, `deleting`, and handling transactions or stored `procedures` with ease.\n\n### Basic Database Operation\nGet a list of all tables in the database\n```php\necho DB::getTables(); // Returns an array of all table names in the connected database.\n```\n\nCheck if a specific table exists\n```php\necho DB::tableExists('user'); // Returns true if the user table exists, otherwise false.\n```\n\nGet the column names of a given table\n```php\necho DB::getTableColumns('user');\n```\n\nGet the table name associated with a model instance\n```php\nDB::getTable(new User()); // Useful for dynamically retrieving the table name from a model class instance.\n```\n\nGet the current active PDO connection instance\n```php\nreturn DB::getConnection(); // Returns the raw PDO connection object used internally.\n```\n\n### Querying the Database using `query()`\nDoppar provides `query()` function and using it, you can pass raw sql and execute it. See the basic example. Get a single row from the user table\n```php\nDB::query(\"SELECT * FROM user WHERE name = ?\", ['Kasper Snider'])-\u003efetch();\n```\nExecutes a query and returns the first matching row as an associative array.\n\nGet all rows that match a query\n```php\nDB::query(\"SELECT * FROM user WHERE name = ?\", ['Kasper Snider'])-\u003efetchAll();\n```\n\n### Modifying the Database using `execute()`\nDoppar provides `execute()` function and using it, you can modify database. See the basic example. Inserts a new user record. Returns the number of affected rows (1 if successful).\n```php\n$inserted = DB::execute(\n    \"INSERT INTO users (name, email, password) VALUES (?, ?, ?)\",\n    ['John Doe', 'john@example.com', bcrypt('secret')]\n);\n```\n\nYou can use transaction here as well\n```php\nDB::transaction(function () {\n    $moved = DB::execute(\n        \"INSERT INTO archived_posts SELECT * FROM posts WHERE created_at \u003c ?\",\n        [date('Y-m-d', strtotime('-1 year'))]\n    );\n\n    $deleted = DB::execute(\n        \"DELETE FROM posts WHERE created_at \u003c ?\",\n        [date('Y-m-d', strtotime('-1 year'))]\n    );\n\n    echo \"Archived {$moved} posts and deleted {$deleted} originals\";\n});\n```\nExecutes multiple statements in a single transaction. Ensures either all queries succeed or none are committed.\n\n### Executing Stored Procedures\nDoppar provides `executeProcedure` method to run your store procedure. See the basic example\n```php\n// Get nested results (original behavior)\n$nestedResults = DB::executeProcedure('sp_GetAllUsers')-\u003eall();\n```\n\nGet flattened first result set\n```php\n$users = DB::executeProcedure('sp_GetAllUsers')-\u003eflatten();\n```\nCalls a procedure and flattens the first result set into a simple array.\n\n\nGet first row only\n```php\n$firstUser = DB::executeProcedure('sp_GetUserById', [1])-\u003efirst();\n```\n\nGet the second result set (index 1) by passing 123 parameter\n```php\n$stats = DB::executeProcedure('sp_GetUserWithStats', [123])-\u003eresultSet(1);\n```\nUseful when a stored procedure returns multiple result sets. This fetches the one at index 1.\n\n### With Multiple Params\n```php\n$totalUsers = 0;\n$results = DB::executeProcedure(\n    'sp_GetPaginatedUsers',\n    [1, 10, 'active', 'created_at', 'DESC'],\n    [\u0026$totalUsers]\n)-\u003eall();\n// $results[0] contains user data\n// $totalUsers contains total count\n```\n\n### Executing View\nDoppar provides `executeView` method to run your `view`. See the basic example\n```php\n$stats = DB::executeView('vw_user_statistics');\n```\n\n### View with WHERE Conditions\nYou can pass `where` condition in your custom view like\n```php\n// 2. View with single WHERE condition\n$nyUsers = DB::executeView(\n    'vw_user_locations', \n    ['state' =\u003e 'New York']\n);\n\n// Equivalent to: SELECT * FROM vw_user_locations WHERE state = 'New York'\n\n// 3. View with multiple WHERE conditions\n$premiumNyUsers = DB::executeView(\n    'vw_user_locations',\n    [\n        'state' =\u003e 'New York',\n        'account_type' =\u003e 'premium'\n    ]\n);\n\n// Equivalent to: \n// SELECT * FROM vw_user_locations \n// WHERE state = 'New York' AND account_type = 'premium'\n```\n\n### View with Parameter Binding\nYou can also pass params with where condition as follows\n```php\n// 4. Using parameter binding for security\n$recentOrders = DB::executeView(\n    'vw_recent_orders',\n    ['status' =\u003e 'completed'],\n    [':min_amount' =\u003e 100] // Additional parameters\n);\n\n// Equivalent to:\n// SELECT * FROM vw_recent_orders \n// WHERE status = 'completed' AND amount \u003e :min_amount\n```\n\n\u003ca name=\"section-14\"\u003e\u003c/a\u003e\n\n## Middleware\nMiddleware acts as a bridge between a request and a response, allowing you to filter or modify incoming requests before they reach the controller. It is useful for authentication, logging, and request modification.\n\nDoppar supports two types of middleware\n* Global Middleware\n* Route Middleware\n\n##### Global Middleware\nGlobal middleware applies to all routes automatically. It is executed on every request, ensuring consistent behavior across the application.\n\n##### Route Middleware\nRoute middleware is applied to specific routes, giving you more control over which requests are affected. You can assign middleware to a route or a group of routes as needed.\n\n\u003ca name=\"section-15\"\u003e\u003c/a\u003e\n\n## Route Middleware\nWe can define multiple route middleware. To define route middleware, just update the `App\\Http\\Kernel.php` file's `$routeMiddleware` array as like below\n\n#### Create New Middleware\nDoppar has command line interface to create a new middleware. Doppar has `make:middleware` command to create a new middleware.\n```\nphp pool make:middleware Authenticate\n```\nThen this command will create a new `Authenticate` for you located inside `App\\Http\\Authenticate` directory\n\n```php\n\u003c?php\n\n/**\n * The application's route middleware.\n *\n * These middleware may be assigned to groups or used individually.\n *\n * @var array\u003cstring, class-string|string\u003e\n */\nprotected $routeMiddleware = [\n    'auth' =\u003e \\App\\Http\\Middleware\\Authenticate::class,\n];\n```\nAnd update your route like:\n```php\n\u003c?php\n\nuse Phaseolies\\Support\\Facades\\Route;\nuse App\\Http\\Controllers\\ProfileController;\n\nRoute::get('/', [ProfileController::class,'index'])-\u003emiddleware('auth');\n```\n\nThe `ProfileController` `index` method is now protected by the auth middleware. Update your middleware configuration to ensure authentication is required before accessing this method.\n\n```php\n\u003c?php\n\nnamespace App\\Http\\Middleware;\n\nuse Phaseolies\\Middleware\\Contracts\\Middleware;\nuse Phaseolies\\Http\\Response;\nuse Phaseolies\\Http\\Request;\nuse Phaseolies\\Support\\Facades\\Auth;\nuse Closure;\n\nclass Authenticate implements Middleware\n{\n    /**\n     * Handle an incoming request\n     *\n     * @param Request $request\n     * @param \\Closure(\\Phaseolies\\Http\\Request) $next\n     * @return Phaseolies\\Http\\Response\n     */\n    public function __invoke(Request $request, Closure $next): Response\n    {\n        if (Auth::check()) {\n            return $next($request);\n        }\n\n        return redirect()-\u003eto('/login');\n    }\n}\n```\n\n\u003ca name=\"section-16\"\u003e\u003c/a\u003e\n\n## Global Middleware\nWe can register multiple global middleware. To register global middleware, just update the `App\\Http\\Kernel.php` file's `$middleware` array.\n\n#### Create New Middleware\nDoppar has command line interface to create a new middleware. Doppar has `make:middleware` command to create a new middleware.\n```\nphp pool make:middleware CorsMiddlware\n```\nThen this command will create a new `CorsMiddleware` for you located inside `App\\Http\\Middleware` directory\n\n```php\n\u003c?php\n\n/**\n * Application global middleware\n */\npublic $middleware = [\n    \\App\\Http\\Middleware\\CorsMiddleware::class,\n];\n```\nNow update your middleware like\n```php\n\u003c?php\n\nnamespace App\\Http\\Middleware;\n\nuse Closure;\nuse Phaseolies\\Request\nuse Phaseolies\\Http\\Response;\nuse Phaseolies\\Middleware\\Contracts\\Middleware;\n\nclass CorsMiddleware implements Middleware\n{\n   /**\n     * Handle an incoming request\n     *\n     * @param Request $request\n     * @param \\Closure(\\Phaseolies\\Http\\Request) $next\n     * @return Phaseolies\\Http\\Response\n     */\n    public function __invoke(Request $request, Closure $next): Response\n    {\n        /**\n         * Code goes here\n         */\n        return $next($request);\n    }\n}\n```\n\n\u003ca name=\"section-17\"\u003e\u003c/a\u003e\n\n## Middleware Params\nWe can define multiple route middleware parameters. To define route middleware, add a `:` after the middleware name. If there are multiple parameters, separate them with a `,` comma. See the example\n\n```php\n\u003c?php\n\nuse Phaseolies\\Route;\nuse App\\Http\\Controllers\\ExampleController;\n\nRoute::get('/', [ExampleController::class, 'index'])-\u003emiddleware(['auth:admin,editor,publisher', 'is_subscribed:premium']);\n```\n\n* In this example:\n  * The auth middleware receives three parameters: `admin`, `editor`, and `publisher`.\n  * The `is_subscribed` middleware receives one parameter: `premium`.\n\n#### Accept Parameters in Middleware\nIn the middleware class, define the handle method and accept the parameters as function arguments:\n```php\n\u003c?php\n\n/**\n * Handle an incoming request\n *\n * @param Request $request\n * @param \\Closure(\\Phaseolies\\Http\\Request) $next\n * @return Phaseolies\\Http\\Response\n */\npublic function __invoke(Request $request, Closure $next, $admin, $editor, $publisher): Response\n{\n    // Parameters received:\n    // $admin = 'admin'\n    // $editor = 'editor'\n    // $publisher = 'publisher'\n\n    // Middleware logic goes here\n\n    return $next($request);\n}\n```\n\n\n\u003ca name=\"section-18\"\u003e\u003c/a\u003e\n\n## CSRF Protectection\n\nCross-site request forgery (CSRF) attacks are a type of security threat where unauthorized actions are executed on behalf of an authenticated user without their knowledge. Fortunately, Doppar provides robust built-in protection to safeguard your application against such attacks.\n\nDoppar simplifies CSRF protection by automatically generating a unique CSRF token for every active user session. This token acts as a secure identifier to ensure that requests made to the application are genuinely coming from the authenticated user. The token is stored in the user's session and is regenerated whenever the session is refreshed, making it virtually impossible for malicious actors to replicate or misuse it.\n\nYou can access the current session's CSRF token either through the request's session data or by using the `csrf_token()` helper function. This seamless integration ensures that your application remains secure while requiring minimal effort on your part. With Doppar, you can focus on building your application with confidence, knowing that CSRF protection is handled efficiently in the background.\n```php\nuse Phaseolies\\Http\\Request;\n\nRoute::get('/token', function (Request $request) {\n    $token = $request-\u003esession()-\u003etoken();\n\n    $token = csrf_token();\n\n    // ...\n});\n```\nAnytime you define a \"POST\" HTML form in your application, you should include a hidden CSRF _token field in the form so that the CSRF protection middleware can validate the request. For convenience, you may use the @csrf Blade directive to generate the hidden token input field:\n```php\n\u003cform method=\"POST\" action=\"/profile\"\u003e\n    @csrf\n\n    \u003c!-- Equivalent to... --\u003e\n    \u003cinput type=\"hidden\" name=\"_token\" value=\"{{ csrf_token() }}\" /\u003e\n\u003c/form\u003e\n```\n\n\n\u003ca name=\"section-19\"\u003e\u003c/a\u003e\n\n## Controllers\nRather than defining all request-handling logic as closures in route files, you can use controller classes to organize related functionality. Controllers centralize request handling, making your code more structured and maintainable. For example, a UserController can manage user-related actions like displaying, creating, updating, and deleting users. By default, controllers are stored in the `app/Http/Controllers` directory.\n\nTo quickly generate a new controller, you may run the `make:controller` Pool command. By default, all of the controllers for your application are stored in the `app/Http/Controllers` directory\n\n```\nphp pool make:controller UserController\n\nphp pool make:controller User/UserController // create controller inside User directory\n```\nLet's take a look at an example of a basic controller. A controller may have any number of public methods which will respond to incoming HTTP requests:\n```php\n\u003c?php\n\nnamespace App\\Http\\Controllers;\n\nuse App\\Models\\User;\n\nclass UserController extends Controller\n{\n    /**\n     * Show the profile for a given user.\n     */\n    public function show(string $id)\n    {\n        return view('user.profile', [\n            'user' =\u003e User::find($id)\n        ]);\n    }\n}\n```\nOnce you have written a controller class and method, you may define a route to the controller method like so:\n```php\nuse Phaseolies\\Support\\Facades\\Route;\nuse App\\Http\\Controllers\\UserController;\n\nRoute::get('/user/{id}', [UserController::class, 'show']);\n```\n### Invokable Controllers\nDoppar also support invokable controllers. You can call it single action controller also. To create a single action controller, need to pass the `--invok` option before create a controller.\n```\nphp pool make:controller ProductController --invok\n```\n\nNow this command will create a invokable controller for you. For invokable controller, route defination will be like\n```php\nRoute::get('/invoke_me', ProductController::class);\n```\nNow `ProductController` __invoke method automatically will be injected by Doppar container. But remember\n\u003e **⚠️ Warning:** Constructor dependency injection won't work for __invokable controllers\n\u003e\n\u003ca name=\"section-20\"\u003e\u003c/a\u003e\n\n## Request\nDoppar's Phaseolies\\Http\\Request class provides an object-oriented way to interact with the current HTTP request being handled by your application as well as retrieve the input, cookies, and files that were submitted with the request.\n#### Accessing the Request Data\nTo access request data, Doppar has some default built in method.\nDoppar provides a powerful `Request` class to handle incoming HTTP requests. This class offers a wide range of methods to access and manipulate request data, making it easy to build robust web applications.\n\n#### HTML Form Request Data\n\nThese methods are used to access data submitted through HTML forms (e.g., POST, GET).\n\n* **Accessing All Data:**\n    * `$request-\u003eall()`: Returns an array of all request data.\n* **Accessing Specific Field Values:**\n    * `$request-\u003ename`: Retrieves the value of the \"name\" field.\n    * `$request-\u003einput('name')`: Equivalent to `$request-\u003ename`, using the `input()` method.\n    * `$request-\u003eget('name')`: Equivalent to previous one\n* **Retrieving Data with Exclusions:**\n    * `$request-\u003eexcept('name')`: Retrieves all data except the \"name\" field.\n    * `$request-\u003eexcept(['name', 'age'])`: Retrieves data excluding \"name\" and \"age\".\n* **Retrieving Specific Fields Only:**\n    * `$request-\u003eonly('name')`: Retrieves only the \"name\" field.\n    * `$request-\u003eonly(['name', 'age'])`: Retrieves only \"name\" and \"age\" fields.\n* **Checking Field Existence:**\n    * `$request-\u003ehas('name')`: Returns `true` if the \"name\" field exists, `false` otherwise.\n* **Accessing Validation Results:**\n    * `$request-\u003epassed()`: Retrieves data that passed validation (if applied).\n    * `$request-\u003efailed()`: Retrieves data that failed validation (if applied).\n* **Accessing Session Results:**\n    * `$request-\u003esession()-\u003etoken()`: Retrieves csrf token data.\n    * `$request-\u003esession()-\u003eget('key')`: Get the session data that is stored in `key`\n    * `$request-\u003esession()-\u003eput('key','value')`: Set the session data that is will be stored in `key`\n    * `$request-\u003esession()-\u003eflush()`: To delete session data\n\n#### Server Request Information\n\nThese methods provide access to server-related request information.\n\n* **Client Information:**\n    * `$request-\u003eip()`: Retrieves the client's IP address.\n    * `$request-\u003euserAgent()`: Retrieves the user agent string (browser/device info).\n    * `$request-\u003ereferer()`: Retrieves the referer URL (where the request came from).\n* **Headers:**\n    * `$request-\u003eheaders()`: Retrieves all request headers as an array.\n    * `$request-\u003eheader('key')`: Retrieves the value of a specific header by key.\n    * `$request-\u003eheaders-\u003eget('host')`: Retrieves the value of a specific header by key.\n    * `$request-\u003eheaders-\u003eset('key','value')`: Set the value to the header.\n* **Request Details:**\n    * `$request-\u003escheme()`: Retrieves the request scheme (e.g., \"http\" or \"https\").\n    * `$request-\u003eisSecure()`: Returns `true` if the request is using HTTPS, `false` otherwise.\n    * `$request-\u003eisAjax()`: Returns `true` if the request is an AJAX request, `false` otherwise.\n    * `$request-\u003eisJson()`: Returns `true` if the request expects a JSON response, `false` otherwise.\n    * `$request-\u003econtentType()`: Retrieves the content type of the request (e.g., \"application/json\").\n    * `$request-\u003econtentLength()`: Retrieves the content length of the request body.\n    * `$request-\u003emethod()`: Retrieves the HTTP method used (e.g., GET, POST).\n    * `$request-\u003equery()`: Retrieves all query parameters (GET data).\n    * `$request-\u003eurl()`: Retrieves the full URL of the request.\n    * `$request-\u003ehost()`: Retrieves the host name (e.g., \"example.com\").\n    * `$request-\u003eserver()`: Retrieves all server variables as an array.\n    * `$request-\u003eserver-\u003eget('key')`: Get the server- by key name\n    * `$request-\u003euri()`: Retrieves the request URI (e.g., \"/path/to/resource\").\n* **Cookies:**\n    * `$request-\u003ecookie()`: Retrieves all cookies sent with the request.\n    * `$request-\u003ecookies-\u003eget('key')`: Get the cookie by key name\n\n#### Authentication\n\nThis method is used to access authenticated user data.\n\n* `$request-\u003eauth()`: Retrieves the authenticated user data.\n* `$request-\u003euser()`: Retrieves the authenticated user data.\n\n#### File Uploads\n\nThese methods handle file uploads from HTML forms.\n\n* **Accessing the File Object:**\n    * `$image = $request-\u003efile('file')`: `'file'` is the HTML form input name.\n* **Retrieving File Information:**\n    * If `$file = $request-\u003efile('file')`:\n        * If `$file-\u003eisValid()`:\n            * `$file-\u003egetClientOriginalName()`: Retrieves the original file name.\n            * `$file-\u003egetClientOriginalPath()`: Retrieves the temporary file path.\n            * `$file-\u003egetClientOriginalType()`: Retrieves the MIME type.\n            * `$file-\u003egetClientOriginalSize()`: Retrieves the file size in bytes.\n            * `$file-\u003egetClientOriginalExtension()`: Retrieves the file extension (e.g., \"jpg\", \"png\").\n            * `$file-\u003egenerateUniqueName()`: Generate a unique name for the uploaded file\n            * `$file-\u003eisMimeType(string|array $mimeType)`: Checks if the uploaded file is of a specific MIME type\n            * `$file-\u003eisImage()`: Check if the uploaded file is an image.\n            * `$file-\u003eisVideo()`: Check if the uploaded file is a video.\n            * `$file-\u003eisDocument()`: Check if the uploaded file is a document.\n            * `$file-\u003emove(string $destination, ?string $fileName = null)`: Moves the uploaded file to a new location.\n            * `$file-\u003egetMimeTypeByFileInfo()`: Get the file's mime type by using the fileinfo extension.\n        * `$file-\u003egetError()`: Gets the error code of the uploaded file.\n\n##### Example\n```php\n// Accessing the uploaded file object\n$image = $request-\u003efile('file'); // 'file' is the HTML form input name\n\n// Retrieving file information\nif ($file = $request-\u003efile('file')) {\n    if ($file-\u003eisValid()) {\n        $file-\u003egetClientOriginalName(); // Retrieves the original file name\n        $file-\u003egetClientOriginalPath(); // Retrieves the temporary file path\n        $file-\u003egetClientOriginalType(); // Retrieves the MIME type\n        $file-\u003egetClientOriginalExtension(); // Retrieves the file extension like jpg, png\n        $file-\u003egetClientOriginalSize(); // Retrieves the file size in bytes\n    }\n}\n```\n\n#### Global `request()` Helper\nThe `request()` helper function in Doppar provides a convenient and globally accessible way to retrieve data from the current HTTP request. It’s an alias for accessing the `Phaseolies\\Http\\Request` instance without needing to inject or typehint it.\n### Basic Usage\n```php\nrequest('key', 'default');\n```\n- Retrieves the value of key from the current request.\n- Returns 'default' if the key does not exist.\n\n### Example:\n```php\n$name = request('name', 'Guest'); // Returns the 'name' from the request or 'Guest' if not set\n```\n\nYou can do the same thing using `request()` object like\n```php\n$name = request()-\u003einput('name', 'Guest'); // as request object\n```\n\n\u003ca name=\"section-21\"\u003e\u003c/a\u003e\n\n## Response\nAll routes and controllers should return a response to be sent back to the user's browser. Doppar provides several different ways to return responses. The most basic response is returning a string from a route or controller. The framework will automatically convert the string into a full HTTP response:\n```php\nRoute::get('/', function () {\n    return 'Hello World';\n});\n```\n\nIn addition to returning strings from your routes and controllers, you may also return arrays.\n```php\nRoute::get('/', function () {\n    return [1, 2, 3];\n});\n```\n\n### Collection \nYou can also return collection like\n```php\nRoute::get('/', function () {\n    return $collection = collect([1, 2, 3, 4]);\n    return $collection-\u003ecount();\n});\n```\n\n### Response Objects\nTypically, you won't just be returning simple strings or arrays from your route actions. Instead, you will be returning full `Phaseolies\\Http\\Response` instances.\n```php\nRoute::get('/', function () {\n    return response()-\u003etext(\"Hello World\", 200);\n});\n```\n\n### Eloquent Models and Collections\nFor Eloquent, Doppar usage its own Eloquent Model and Collection. So you can return Eloquent collection data as `Phaseolies\\Http\\Response`, Doppar automatically convert this data as collection\n```php\nuse App\\Models\\User;\n\nRoute::get('/user', function () {\n    return User::all();\n});\n```\n### Attaching Headers to Responses\nKeep in mind that most response methods are chainable, allowing for the fluent construction of response instances. For example, you may use the `setHeader` method to add a series of headers to the response before sending it back to the user:\n```php\nreturn response()-\u003etext(\"Hello World\", 200)\n    -\u003esetHeader('Content-Type', 'text/plain')\n    -\u003esetHeader('X-Header-One', 'Header Value')\n    -\u003esetHeader('X-Header-Two', 'Header Value');\n```\nOr, you may use the withHeaders method to specify an array of headers to be added to the response:\n```php\nreturn response()-\u003etext(\"Hello World\", 200)\n    -\u003ewithHeaders([\n        'Content-Type' =\u003e 'text/plain',\n        'X-Header-One' =\u003e 'Header Value',\n        'X-Header-Two' =\u003e 'Header Value',\n    ]);\n```\nYou also use the `Response` object as the controller method params and get the same response like\n```php\n\u003c?php\n\nnamespace App\\Http\\Controllers;\n\nuse Phaseolies\\Http\\Response;\nuse App\\Http\\Controllers\\Controller;\n\nclass UserController extends Controller\n{\n    public function index(Response $response)\n    {\n        return $response-\u003etext(\"Hello World\", 200)\n            -\u003ewithHeaders([\n                'Content-Type' =\u003e 'text/plain',\n                'X-Header-One' =\u003e 'Header Value',\n                'X-Header-Two' =\u003e 'Header Value',\n            ]);\n    }\n}\n```\n\nYou can also return response like this, directly using `response()` helper.\n```php\n \n return response($content, $status, $headers);\n \n return response([\n            'name' =\u003e  'doppar'\n        ],200, [\n            'Header-Value' =\u003e 'Your Header value'\n        ]);\n```\n\n### Response Collection Inside Array\nIf you want to return colelction inside a array, you can use `toArray()` method to convert your collection to array\n```php\nreturn response()-\u003ejson([\n        'data' =\u003e User::all()-\u003etoArray()\n    ], 200);\n```\n\n### Attaching Headers to Responses using Response Facades\nYou can also use `Facades` to get the response. You can use `Response` facades like\n```php\nnamespace App\\Http\\Controllers;\n\nuse Phaseolies\\Support\\Facades\\Response;\n\nclass UserController extends Controller\n{\n    public function index()\n    {\n        return Response::text(\"Hello World\", 200)\n            -\u003ewithHeaders([\n                'Content-Type' =\u003e 'text/plain',\n                'X-Header-One' =\u003e 'Header Value',\n                'X-Header-Two' =\u003e 'Header Value',\n            ]);\n    }\n}\n```\n\n### Check Response Status\nYou can check the response status like\n```php\n$response = response()-\u003ejson([\n        'data' =\u003e 'Doppar'\n   ], 200);\n\nreturn $response-\u003eisOk();\n```\n\n### Some Avaialbe Response Method\nThere are so many response method that you can use to check your HTTP response. Some of are\n```php\npublic function isSuccessful(): bool\npublic function isRedirection(): bool\npublic function isClientError(): bool\npublic function isServerError(): bool\npublic function isOk(): bool\npublic function isForbidden(): bool\npublic function isNotFound(): bool\npublic function isRedirect(?string $location = null): bool\npublic function isFresh(): bool\npublic function isValidateable(): bool\npublic function setPrivate(): Response\npublic function setPublic(): Response\npublic function setImmutable(bool $immutable = true): Response\npublic function isImmutable(): bool\npublic function setCache(array $options): static\npublic function isInvalid(): bool\n```\n\n### Redirects Response\nRedirect responses are instances of the `Phaseolies\\Http\\Redirect` class, and contain the proper headers needed to redirect the user to another URL. There are several ways to generate a Redirect instance. The simplest method is to use the global `redirect` helper or even you can use `Redirect` facades\n```php\nuse Phaseolies\\Support\\Facades\\Redirect;\n\nRoute::get('/dashboard', function () {\n\n    // Both will give you the same output\n    return redirect()-\u003eto('/home/dashboard');\n    return Redirect::to('/home/dashboard');\n    \n    // Even you can use\n    redirect('/home/dashboard');\n});\n```\n\n### Redirecting to Named Routes\nWhen you call the redirect helper with no parameters, an instance of `Phaseolies\\Routing\\Redirect` is returned, allowing you to call any method on the `Redirect` instance. For example, to generate a `Redirect` to a named route, you may use the route method:\n```php\nreturn redirect()-\u003eroute('login');\n```\nIf your route has parameters, you may pass them as the second argument to the route method:\n```php\n// For a route with the following URI: /profile/{id}/{username}\nreturn redirect()-\u003eroute('profile', ['id' =\u003e 1, 'username' =\u003e 'mahedy150101']);\n```\n### Redirecting to External Domains\nSometimes you may need to redirect to a domain outside of your application. You may do so by calling the `away` method, which creates a RedirectResponse without any additional URL encoding, validation, or verification:\n```php\nreturn redirect()-\u003eaway('https://www.google.com');\n```\n\n### Redirecting With Flashed Session Data\nRedirecting to a new URL and flashing data to the session are usually done at the same time. Typically, this is done after successfully performing an action when you flash a success message to the session. For convenience, you may create a `RedirectResponse` instance and flash data to the session in a single, fluent method chain:\n```php\n\u003c?php\n\nnamespace App\\Http\\Controllers;\n\nuse Phaseolies\\Http\\Request;\nuse App\\Http\\Controllers\\Controller;\n\nclass LoginController extends Controller\n{\n    public function logout(Request $request)\n    {\n       redirect()-\u003eto('/login')\n            -\u003ewith('success', 'You are successfully logged out');\n    }\n}\n\n```\nYou can show this in many ways. This ways will automatically check is there is any session flash message then display it\n\n```blade\n@if (session()-\u003ehas('success'))\n    \u003cdiv class=\"alert alert-success\"\u003e\n        {{ session()-\u003eget('success') }}\n    \u003c/div\u003e\n@endif\n```\n### View Responses\nIf you need control over the response's status and headers but also need to return a view as the response's content, you should use the view method:\n```php\nreturn response()-\u003eview('welcome')-\u003esetHeader('Content-Type', 'text/html');\n```\n### JSON Responses\nThe json method will automatically set the `Content-Type header to application/json`, as well as convert the given array to JSON using the `json_encode` PHP function:\n```php\n return response()-\u003ejson([\n        'name' =\u003e 'Mahedi Hasan',\n        'age' =\u003e 33\n    ], 200);\n```\n\n### Responses Facades\nYou can using `Response` facades to get the response like above. As example get the json response using Response facades\n```php\nuse Phaseolies\\Support\\Facades\\Response;\n\nreturn Response::json([\n        'name' =\u003e 'Mahedi Hasan',\n        'age' =\u003e 33\n    ], 200);\n```\n\n### File Downloads Response\nThe download method generates a response that triggers a file download in the user’s browser. It takes the file path as its primary argument. Optionally, you can specify a custom download filename as the second argument—this overrides the default name seen by the user. Additionally, an array of custom HTTP headers can be passed as a third argument for further control over the download behavior.\n```php\nreturn response()-\u003edownload($pathToFile);\n\nreturn response()-\u003edownload($pathToFile, $name, $headers);\n```\n\n### Streamed Downloads\nAt times, you may want to convert the string output of an operation into a downloadable response without storing it on disk. The streamDownload method allows you to achieve this by accepting a callback, filename, and an optional array of headers as parameters:\n```php\n\nuse App\\Services\\Facebook;\n\nreturn response()-\u003estreamDownload(function () {\n    echo Facebook::api('repo')\n        -\u003econtents()\n        -\u003ereadme('doppar', 'doppar')['contents'];\n}, 'doppar-readme.md');\n```\n\n### File Responses\nThe file method may be used to display a file, such as an image or PDF, directly in the user's browser instead of initiating a download. This method accepts the absolute path to the file as its first argument and an array of headers as its second argument:\n```php\nreturn response()-\u003efile($pathToFile);\n\nreturn response()-\u003efile($pathToFile, $headers);\n```\n\n### Streamed Responses\nStreaming data to the client as it is generated can greatly reduce memory usage and enhance performance, particularly for extremely large responses.\n```php\npublic function streamedContent(): \\Generator\n{\n    yield 'Hello, ';\n    yield 'World!';\n}\n\nreturn response()-\u003estream(function (): void {\n    foreach ($this-\u003estreamedContent() as $chunk) {\n        echo $chunk;\n        ob_flush();\n        flush();\n        sleep(2); // Simulate delay between chunks...\n    }\n}, 200, ['X-Accel-Buffering' =\u003e 'no']);\n```\n\n### Streamed JSON Responses\nTo stream JSON data incrementally, you can use the `streamJson` method. This is particularly beneficial for large datasets that need to be sent progressively to the browser in a format that JavaScript can easily parse\n```php\nreturn response()-\u003estreamJson([\n    'users' =\u003e User::all(),\n]);\n```\n\n\u003ca name=\"section-22\"\u003e\u003c/a\u003e\n\n## Views\nIn Doppar, it's not practical to return entire HTML document strings directly from your routes and controllers. Fortunately, views offer a clean and structured way to manage your application's UI by keeping HTML in separate files.\n\nViews help separate your application's logic from its presentation layer, improving maintainability and readability. In Doppar, views are typically stored in the resources/views directory. The templating system in Doppar allows you to create dynamic and reusable UI components efficiently. A basic view file might look like this:\n```\n\u003c!-- View stored in resources/views/greeting.blade.php --\u003e\n\n\u003chtml\u003e\n    \u003cbody\u003e\n        \u003ch1\u003eHello, {{ $name }}\u003c/h1\u003e\n    \u003c/body\u003e\n\u003c/html\u003e\n```\nSince this view is stored at resources/views/greeting.blade.php, we may return it using the global view helper like so:\n```\nRoute::get('/', function () {\n    return view('greeting', ['name' =\u003e 'James']);\n});\n```\n### Passing Data to Views\nAs you saw in the previous examples, you may pass an array of data to views to make that data available to the view:\n```php\nreturn view('greetings', ['name' =\u003e 'Victoria']);\n```\n### Optimizing Views\nIn Doppar Framework, Blade template views are compiled on demand. When a request is made to render a view, Doppar checks if a compiled version exists. If the compiled view is missing or outdated compared to its source, Doppar will recompile it dynamically.\n\nHowever, compiling views at runtime introduces a minor performance overhead. To optimize performance, Doppar provides the view:cache command, which precompiles all views ahead of time. This can be particularly useful during deployment.\n```php\nphp pool view:cache\n```\nYou may use the `view:clear` command to clear the view cache:\n```\nphp artisan view:clear\n```\n\n\n\u003ca name=\"section-23\"\u003e\u003c/a\u003e\n\n## Asset Bundling\nIn Doppar, you can easily load CSS, JavaScript, and other asset files from the public folder using the enqueue() functio\n```html\n\u003clink rel=\"stylesheet\" href=\"{{ enqueue('style.css') }}\"\u003e\n\u003clink rel=\"stylesheet\" href=\"{{ enqueue('assets/style.css') }}\"\u003e // Here assets is a folder name\n```\nThis ensures that your asset paths remain dynamic and easily manageable across the project.\n\n\u003ca name=\"section-24\"\u003e\u003c/a\u003e\n\n## Session\nDoppar's `session()` helper method provides a simple and intuitive way to manage session data in your application. Below is a detailed explanation of the available methods and their usage. Like get, put, has, forget, flush, and more, you can easily handle session operations.\n\n### Session Console Command\nTo remove all the session data, you can run\n```bash\nphp pool session:clear\nphp pool session:clear --force\n```\n\n### Put and Get Session Data\nTo store data in the session and retrieve it later, use the `put` and `get` methods.\n#### Syntax\n```php\n$request-\u003esession()-\u003eput($key, $value);\n```\nExample\n```php\n$request-\u003esession()-\u003eput('name', 'doppar');\nreturn $request-\u003esession()-\u003eget('name');\n```\nYou can also get the session data like\n```php\nreturn session('name', 'default');\n```\n\n\nYou can check a key exists or not in a session data by doing this\n```php\nif($rquest-\u003esession()-\u003ehas('name')){\n    // Session key data exists\n}\n```\n\nYou can destroy specific key session data by doing this\n```php\n$rquest-\u003esession()-\u003eforget('key')\n```\nYou can clear all session data by calling `flush()` function\n```php\n$rquest-\u003esession()-\u003eflush();\n```\n\nEven you can destroy session using `destroy` function\n```php\n$request-\u003esession()-\u003edestroy()\n```\n### Set and Get Session ID\nYou can set seesion id and get is also. \n```php\n$rquest-\u003esession()-\u003esetId($id);\n$rquest-\u003esession()-\u003egetId()\n```\n\nIf you want to show all the session data from your application, call `all()` method like\n```php\n$rquest-\u003esession()-\u003eall()\n```\n### Session Facades\nYou can also handle session data using `Session` facades.\n```php\nuse Phaseolies\\Support\\Facades\\Session;\n\nSession::put('name','mahedi');\nSession::get('name');\n```\n\n\u003ca name=\"section-50\"\u003e\u003c/a\u003e\n\n## Cookie\nDoppar provides two ways to manage cookies in the application. One is `Phaseolies\\Support\\Facades\\Cookie` facades and another is `cookie()` helper fucntion. Each approach allows you to store, retrieve, and delete cookies efficiently. Let's explore both methods in detail.\n\n### Storing Cookies\nThe Cookie facade provides a structured way to manage cookies. It allows you to store, retrieve, and remove cookies with additional options like expiration time, path, and security settings. To store cookies, simply use `store()` function.\n```php\nuse Phaseolies\\Support\\Facades\\Cookie;\n\nCookie::store('cookie_name', 'cookie_value');\n\n// Using helper\n\ncookie()-\u003estore('cookie_name', 'cookie_value');\n```\n\n### Cookie With Expiration Time\nIf you want to store cookie using your defined expiration time, follow it\n```php\n// Using timestamp\nCookie::store('user_token', 'abc123', ['expires' =\u003e time() + 3600]);\n\n// Using DateTime\n$expireDate = new \\DateTime('+1 day');\nCookie::store('user_token', 'abc123', ['expires' =\u003e $expireDate]);\n\n// Using string (strtotime compatible)\nCookie::store('user_token', 'abc123', ['expires' =\u003e '+1 week']);\n```\n\nYou can use Carbon also like that\n```php\nCookie::store('temp_data', 'value456', [\n    'expires' =\u003e Carbon::parse('next friday 3pm')\n]);\n```\n\n### Cookie With Path\nTo define cookie with path, you can follow below ways\n```php\nCookie::store('prefs', 'dark', ['path' =\u003e '/settings']);\n```\n\n### Cookie With Domain\nTo add domain in your cookie you can follow as below\n```php\nCookie::store('session', 'xyz789', ['domain' =\u003e '.example.com']);\n```\n\n### Secure \u0026 HttpOnly\nWhen storing cookies, security is a crucial aspect, especially for authentication and sensitive user data. The secure and httponly attributes help protect cookies from attacks such as cross-site scripting (XSS) and man-in-the-middle (MITM) attacks.\n```php\nCookie::store('auth', 'secure123', [\n    'secure' =\u003e true,    // HTTPS only\n    'httponly' =\u003e true   // JavaScript cannot access\n]);\n```\n\n### SameSite Attribute\nFor samesite attribute, you can also set like that\n```php\nCookie::store('csrftoken', 'rand123', [\n    'samesite' =\u003e Cookie::SAMESITE_STRICT\n]);\n```\n\n### Partitioned (for CHIPS)\nSetting `'partitioned' =\u003e true` allows a cookie to be accessed only within a specific cross-site context, without being shared across different origins. This helps prevent third-party tracking while still enabling functionalities like embedded content authentication.\n```php\nCookie::store('tracking', 'user123', [\n    'partitioned' =\u003e true  // For cross-site cookies\n]);\n```\n\n### Raw Cookie (no URL encoding)\nBy default, cookies are URL-encoded, meaning special characters like `=` and \u0026 are automatically converted to a safe format. However, if you need to store data without encoding, you can use the raw option.\n```php\nCookie::store('raw_data', 'some=value', [\n    'raw' =\u003e true  // Disables URL encoding\n]);\n```\n\n### Forever Cookie\nA forever cookie is a cookie that does not expire or is set with a very distant expiration date, ensuring it remains stored in the user's browser for an extended period. These cookies are useful for remembering user preferences, authentication tokens, and long-term tracking. You can store `forever` cookie as like below by using `forever` method.\n```php\nCookie::forever('remember_me', 'yes', [\n    'path' =\u003e '/',\n    'httponly' =\u003e true\n]);\n```\n\n### Retrieving Cookies\nWe can very easily get our stored cookie data using `get` function.\n```php\nCookie::get('user_token');\n\ncookie()-\u003eget('user_token');\n\n\nCookie::retrieve('non_existent', 'default_value'); // with default value\n```\n\n### Check Cookie Existence\nBefore accessing a cookie, it’s best practice to check if it exists to avoid errors. Doppar provides a method to verify whether a specific cookie is present using `Cookie::has()`\n```php\nif (Cookie::has('user_token')) {\n    // Cookie exists\n}\n```\n\n### Delete Cookie\nWhen a cookie is no longer needed, it should be deleted to ensure proper data management and security. Doppar provides a way to remove cookies using the `remove()` method.\n```php\nCookie::remove('user_token');\n\n// With Path/Domain\nCookie::remove('old_cookie', [\n    'path' =\u003e '/special',\n    'domain' =\u003e '.example.com'\n]);\n```\n\n### Advanced Cookie Usage: Create Without Sending\nIn some cases, you might want to create a cookie but not immediately send it to the user's browser. This can be useful for situations where you need to modify the cookie before sending it or store it for later in the same request cycle. Doppar provides a way to create cookies in advanced scenarios like this by using the `make()` method.\n```php\n$cookie = Cookie::make('preview_mode', 'enabled', [\n    'expires' =\u003e '+30 minutes',            // Sets the expiration time to 30 minutes from now\n    'samesite' =\u003e Cookie::SAMESITE_LAX     // Specifies SameSite attribute for better cross-site cookie handling\n]);\n\n// Send later\nCookie::store($cookie);\n```\n\n### Modifying an Existing Cookie\nIn some cases, you may need to update the value or properties of an already created cookie. Doppar provides a convenient way to modify an existing cookie using methods like `withValue()` and `withExpires()`. These methods allow you to change the value or expiration of a cookie after it has been created.\n```php\nCookie::make('existing_cookie', '1')\n    -\u003emodify()\n    -\u003ewithValue('10')\n    -\u003ewithExpires('+1 day')\n    -\u003eupdate();\n```\nYou can extend it also like that\n```php\nCookie::make('existing_cookie', 'light')\n    -\u003emodify()\n    -\u003ewithValue('dark')\n    -\u003ewithPath('/settings')\n    -\u003ewithDomain('.example.com')\n    -\u003ewithSecure(true)\n    -\u003ewithSameSite('lax')\n    -\u003eupdate();\n```\n\n### Fetch All Cookies\nTo get all the cookies, you can like that\n```php\n$request-\u003ecookies-\u003eall();\n\n//or\nCookie::all();\n```\n\n\u003ca name=\"section-25\"\u003e\u003c/a\u003e\n\n## Validation\nDoppar provides a very simple approaches to validate your application's incoming data. It is most common to use the validate method available on all incoming HTTP requests. However, we will discuss other approaches to validation as well. We can validate from and can show error message in blade file very easily. To validate from , just assume we have two routes.\n```php\n\u003c?php\n\nuse Phaseolies\\Support\\Facades\\Route;\nuse App\\Http\\Controllers\\ExampleController;\n\nRoute::get('/register', [ExampleController::class, 'index']);\nRoute::post('/register', [ExampleController::class, 'store']);\n```\nAnd now we can update `App\\Http\\Controllers\\ExampleController.php` like\n```php\n\u003c?php\n\nnamespace App\\Http\\Controllers;\n\nuse Phaseolies\\Http\\Request;\nuse App\\Http\\Controllers\\Controller;\n\nclass ExampleController extends Controller\n{\n    public function store(Request $request)\n    {\n        $data = $request-\u003esanitize([\n            'email' =\u003e 'required|email|unique:users|min:2|max:100',\n            'password' =\u003e 'required|min:2|max:20',\n            'username' =\u003e 'required|unique:users|min:2|max:100',\n            'name' =\u003e 'required|min:2|max:20'\n        ]);\n\n        // If validation passes, proceed to store the user data.\n    }\n}\n```\nHere the `store()` method in the `UserController` is designed to handle user registration form submissions. It ensures that user input is validated and sanitized before being stored in the database.\n\n**Functionality:**\n\n1.  **Request Handling:**\n    * The method receives an instance of the `Request` class (`$request`), which encapsulates all incoming form data.\n\n2.  **Data Sanitization and Validation:**\n    * The `$request-\u003esanitize()` method is employed to validate and filter the incoming data according to the following rules:\n        * `email`:\n            * Must be present (`required`).\n            * Must adhere to a valid email format.\n            * Must be unique within the `users` table.\n            * Must be between 2 and 100 characters in length.\n        * `password`:\n            * Must be present (`required`).\n            * Must be between 2 and 20 characters in length.\n        * `username`:\n            * Must be present (`required`).\n            * Must be unique within the `users` table.\n            * Must be between 2 and 100 characters in length.\n        * `name`:\n            * Must be present (`required`).\n            * Must be between 2 and 20 characters in length.\n\n3.  **Data Storage:**\n    * Upon successful validation, the sanitized and validated data is stored in the `$data` variable.\n    * The method then proceeds to store this data in the database, typically by creating a new record in the `users` table.\n\nYou can also get `failed` and `passed` data from the request. \n```php\n\u003c?php\n\npublic function register(Request $request)\n{\n    $data = $request-\u003esanitize([\n        'email' =\u003e 'required|email|unique:users|min:2|max:100',\n        'password' =\u003e 'required|min:2|max:20',\n        'username' =\u003e 'required|unique:users|min:2|max:100',\n        'name' =\u003e 'required|min:2|max:20'\n    ]);\n\n    $data // validation passed data\n    $request-\u003epassed(); // validation passed data\n\n    // Safely create the user now\n    User::create($request-\u003epassed());\n}\n```\n\n### Show Validation Message\nTo show validation error message in your blade file, doppar has a very elegent syntax. Showing validation error message specific key wise\n```html\n\u003cinput .... class=\"form-control @error('email') is-invalid @enderror value=\"{{ old('email') }}\"\u003e\n@error('email')\n    \u003cdiv class=\"alert alert-danger mt-1 p-1\"\u003e{{ $message }}\u003c/div\u003e\n@enderror\n```\nBut if you want to show all error message in a single call, you can use below way\n```html\n @errors\n    \u003cdiv class=\"alert alert-danger\"\u003e\n        \u003cul\u003e\n            @foreach (session()-\u003eget('errors') as $field =\u003e $messages)\n                @foreach ($messages as $message)\n                    \u003cli\u003e{{ $message }}\u003c/li\u003e\n                @endforeach\n            @endforeach\n        \u003c/ul\u003e\n    \u003c/div\u003e\n@enderrors\n```\n\nDoppar will automatically trace the error message and display here.\n\n## Validation Facades\nDoppar provides `Phaseolies\\Support\\Facades\\Sanitize` facades to sanitize your form request data. you can sanitize your form request data like\n```php\n\u003c?php\n\nnamespace App\\Http\\Controllers\\Auth;\n\nuse Phaseolies\\Support\\Facades\\Sanitize;\nuse Phaseolies\\Http\\Request;\nuse App\\Http\\Controllers\\Controller;\n\nclass LoginController extends Controller\n{\n    public function login(Request $request)\n    {\n        $sanitizer = Sanitize::request($request-\u003eall(), [\n            'email' =\u003e 'required|email|min:2|max:100',\n            'password' =\u003e 'required|min:2|max:20'\n        ]);\n\n        if ($sanitizer-\u003efails()) {\n            return back()-\u003ewithErrors($sanitizer-\u003eerrors())-\u003ewithInput();\n        }\n\n        // validation passed and you can get the sanitized data like\n        $validated = $sanitizer-\u003epassed();\n    }\n}\n```\n\nNow you can show all the error message with session flash method. Let's see the example of session flash error message showing\n```html\n// Use any one of them \n@if (session()-\u003ehas('errors'))\n    \u003cdiv class=\"alert alert-danger\"\u003e\n        \u003cul\u003e\n            @foreach (session()-\u003eget('errors') as $field =\u003e $messages)\n                @foreach ($messages as $message)\n                    \u003cli\u003e{{ $message }}\u003c/li\u003e\n                @endforeach\n            @endforeach\n        \u003c/ul\u003e\n    \u003c/div\u003e\n@endif\n```\n\n### Image validation\nIn Doppar, you can use the $request-\u003esanitize() method to validate and sanitize incoming request data. This ensures that the submitted data meets specific criteria before being processed.\nTo validate an uploaded file, use the following code:\n```php\n$request-\u003esanitize([\n    'file' =\u003e 'required|image|mimes:jpg,png,jpeg|dimensions:min_width=100,min_height=100,max_width=1000,max_height=1000|max:2048'\n]);\n```\nThe following validation rules are applied to image uploads to ensure that only properly formatted and sized images are processed.\n\n**Rules:**\n\n* **`required`**:\n    * Ensures that a file is provided in the upload request. If no file is present, validation will fail.\n* **`image`**:\n    * Verifies that the uploaded file is indeed an image. This rule checks the file's MIME type to confirm it's an image format.\n* **`mimes:jpg,png,jpeg`**:\n    * Restricts the acceptable image file types to JPEG (`jpg`, `jpeg`) and PNG (`png`). Any other image formats or file types will be rejected.\n* **`dimensions:min_width=100,min_height=100,max_width=1000,max_height=1000`**:\n    * Enforces specific size constraints on the image.\n        * `min_width=100` and `min_height=100`: The image must have a minimum width and height of 100 pixels.\n        * `max_width=1000` and `max_height=1000`: The image must not exceed a maximum width and height of 1000 pixels.\n* **`max:2048`**:\n    * Limits the maximum file size to 2048 kilobytes (2 megabytes). Files exceeding this size will be rejected.\n\n**Validation Failure:**\n\nIf the uploaded file fails to meet any of these criteria, the validation process will fail. An error response will be generated, indicating the specific validation failures.\n\n### Date Validation\nTo validate date, you follow this example\n```php\n'date' =\u003e 'required|date|gte:today'\n```\nHere date must date type of field and `gte` means `greater than equal` today. if you use `gt` that means `greater than` today like\n```php\n'date' =\u003e 'required|date|gt:today'\n```\nYou can also use `lte` and `lt` means `less than today` and `less than`. As for example\n```php\n'date' =\u003e 'required|date|lte:today' // date should be less than equal today\n```\n\n### Number Validation\nTo validate number, you follow this example\n```php\n$request-\u003esanitize([\n    'number' =\u003e 'null|int|between:2,5'\n]);\n```\nThe above validation will be applied like that, the number can be nullable and if number provides, it must be integer and digit must in between greater than equal 2 and less than equal 5\n\nTo validate `float` number, you follow this example\n```php\n$request-\u003esanitize([\n    'number' =\u003e 'null|float:2|between:2,5'\n]);\n```\nThe above validation will be applied like that, the number can be nullable and if number provides, it must be float and digit must in between greater than equal 2 and less than equal 5 and decimal after number will be 2 digit to \"have exactly two decimal places\" or \"with two decimal places\" like `3.33` not `3.333`\n\n### Validation Using Form Request Class\nWe can also validate requested data using a class to make our code more clean and maintable. Doppar provides a pool command to create a new form request class.\n```bash\nphp pool make:request LoginRequest\n```\n\nThis command will create a new Request class to handle login request form data inside the `App\\Http\\Validations` folder. In this class, you will find two methods: `authorize()` and `rules()`. If you want to perform validation, ensure that the `authorize()` method returns `true`. See the example\n```php\n\u003c?php\n\nnamespace App\\Http\\Validations;\n\nuse Phaseolies\\Http\\Validation\\FormRequest;\n\nclass LoginRequest extends FormRequest\n{\n    /**\n     * Determine if the user is authorized to make this request.\n     *\n     * @return bool\n     */\n    public function authorize(): bool\n    {\n        return true;\n    }\n\n    /**\n     * Get the validation rules that apply to the request.\n     *\n     * @return array\n     */\n    public function rules(): array\n    {\n        return [\n            'email' =\u003e 'required|email|min:2|max:100',\n            'password' =\u003e 'required|min:2|max:20'\n        ];\n    }\n}\n```\n\nNow you this Request validation class in your controller like\n```php\n\u003c?php\n\nnamespace App\\Http\\Controllers\\Auth;\n\nuse App\\Http\\Validations\\LoginRequest;\nuse App\\Http\\Controllers\\Controller;\n\nclass LoginController extends Controller\n{\n    public function login(LoginRequest $request)\n    {\n        $data = $request-\u003epassed() // validated data\n    }\n}\n```\n\n\u003ca name=\"section-26\"\u003e\u003c/a\u003e\n\n## Error Handling\nDoppar has HttpException class to throw an exception. You can use it like\n```php\n\u003c?php\n\nnamespace App\\Http\\Controllers;\n\nuse App\\Http\\Controllers\\Controller;\nuse Phaseolies\\Http\\Exceptions\\HttpException;\n\nclass UserController extends Controller\n{\n\n    public function index()\n    {\n        try {\n           // code\n        } catch (HttpException $th) {\n            return $th-\u003egetMessage();\n        }\n    }\n}\n\n```\n### Abort Facades\nTo handle error showing in browser is important. Now assume you want to redirect user a 404 page or showing any HTTP status page error. You can use `Phaseolies\\Support\\Facades\\Abort` class or `abort` global helper function.\n```php\nuse Phaseolies\\Support\\Facades\\Auth;\n\nAbort::abort(404);\nabort(404);\n```\nThis will show the user 404 error page. You can also use `abort_if` to add extra condition.\n\n```php\nabort_if(Auth::user()-\u003eid === 1, 404);\n```\n\n### User Define Custom Error Page\nIf you want to use a custom error page, you need to create your error view file inside the `resources/views/errors` directory. For example, to create a custom 404 error page, you would name the file `404.blade.php`, where `404` represents the HTTP status code. Once created, Doppar will automatically use your custom error page for the corresponding status code.\n\n\u003ca name=\"section-27\"\u003e\u003c/a\u003e\n\n## Error Logging and System Monitoring\n\nDoppar provides a comprehensive logging system to facilitate application debugging and monitoring. By leveraging the powerful `Monolog` library, Doppar offers flexible logging capabilities, allowing you to record various events and messages to different channels.\n\n**Logging Channels:**\n\nDoppar supports three primary logging channels, configurable via the `config/log.php` file and your `.env` environment variables:\n\n* **`stack`**: Allows you to group multiple log handlers into a single channel.\n* **`daily`**: Creates a new log file each day, useful for managing large log volumes.\n* **`single`**: Writes all log messages to a single file (`storage/logs/doppar.log`).\n* **`slack`**: Creates log each day in slack channel\n\n**Configuration:**\n\nYou can customize the logging behavior by modifying the `config/log.php` file and the `.env` file. This allows you to select your preferred logging channel, adjust log levels, and configure other logging options.\n\n**Basic Logging with the `Phaseolies\\Support\\Facades\\Log` Facades:**\n\nDoppar provides a convenient `Log` Facades class to simplify the logging process. To log a message, simply use the following syntax:\n\n```php\nuse Phaseolies\\Support\\Facades\\Log;\n\nLog::info('Howdy');\n```\n\nDoppar allow you to create Log using multiple method like\n```php\nLog::warning('Howdy');\nLog::notice('Howdy');\nLog::alert('Howdy');\nLog::emergency('Howdy');\nLog::error('Howdy');\nLog::debug('Howdy');\nLog::critical('Howdy');\n```\n\n### Log channel\nYou can use channel to show Log message, like you want to show Log a daily file or slack channel or single channel, you can use like below\n```php\nLog::channel('stack')-\u003einfo('Howdy');\nLog::channel('daily')-\u003ewarning('Howdy');\nLog::channel('single')-\u003enotice('Howdy');\nLog::channel('slack')-\u003ealert('Howdy');\n```\n\n### Log Helper\nYou can show above all the log data using log helper function like\n```php\ninfo('Howdy');\nwarning('Howdy');\nnotice('Howdy');\nalert('Howdy');\nemergency('Howdy');\nerror('Howdy');\ndebug('Howdy');\ncritical('Howdy');\n```\n\n#### Automatic System Error Logging\nDoppar includes a robust, built-in system for automatically capturing and recording system errors. This crucial feature ensures that critical issues are promptly identified, allowing developers to maintain application stability and effectively troubleshoot problems. Doppar automatically logged system error message in `storage/log/doppar.log` file.\n\n**How It Works:**\n\n* **Automatic Capture:**\n    * When an uncaught exception or error occurs within your Doppar application, the framework's error handling mechanism automatically intercepts the event.\n* **Log Destination:**\n    * These captured system error messages are then written to the `storage/logs/doppar.log` file. This central location acts as a comprehensive repository for all system-level errors.\n* **Purpose:**\n    * This automatic logging empowers developers to:\n        * Identify and diagnose the root cause of errors.\n        * Monitor application health and stability in real-time.\n        * Proactively address potential issues before they escalate.\n\n**Benefits:**\n\n* **Simplified Debugging:**\n    * A centralized log of system errors significantly streamlines the debugging process. Developers can quickly review the log to pinpoint the source of problems, saving valuable time and effort.\n* **Enhanced Monitoring:**\n    * Regularly reviewing the error log enables developers to identify recurring issues, potential vulnerabilities, and performance bottlenecks, leading to a more stable application.\n* **Improved Reliability:**\n    * By promptly addressing logged errors, developers can enhance the overall reliability and stability of their Doppar application, ensuring a consistent and dependable user experience.\n\n**In Essence:**\n\nDoppar's automatic system error logging acts as a vital safety net, ensuring that critical errors are meticulously recorded for thorough analysis and swift resolution. This proactive approach significantly contributes to the development of a more robust, dependable, and maintainable application.\n\n\u003ca name=\"section-48\"\u003e\u003c/a\u003e\n\n## URL Generation\nDoppar provides several helpers to assist you in generating URLs for your application. These helpers are primarily helpful when building links in your templates, or when generating redirect responses to another part of your application. The most basic URL generation will be like assume we want to generate url using route name.\n```php\nuse Phaseolies\\Support\\Facades\\URL;\n\nURL::route('login');\n\n// its equivalent helper method is\nroute('login');\n```\n\n### Signed URL\nAssume you want to generate a URL that will be expire after some times with a signature, you can use `singed` method like\n```php\nURL::signed('/download', ['file' =\u003e 'report.pdf'], 3600);\n\n// This will generate URL like this\nhttp://example.com/download?file=report.pdf\u0026expires=1742400695\u0026signature=14a4f4a5c6b6c96eb8668af1759232591d52eb8456bcf088addb02275b673562\n```\n\nYou can also create this above URL using\n```php\nURL::to('/download')\n    -\u003ewithQuery(['file' =\u003e 'report.pdf'])\n    -\u003ewithSignature(3600)\n    -\u003ewithFragment('about')\n    -\u003emake();\n\n// output\nhttp://localhost:8000/download?file=report.pdf\u0026expires=1742401435\u0026signature=363ef0e47fd9fca7197882490ee8f4c132df6b9b6e9e0041ac0df5c31cc349d3#about\n```\n\nThere are some basic helper method to access URL like\n```php\nURL::full(); // http://example.com/hello?name=doppar\nURL::current(); // http://example.com/hello\n```\n\n### Accessing public assets\nDoppar provides `enqueue()` method to access your public assstes like\n```php\nURL::enqueue('/assets/example.png'); // http://localhost:8000/assets/example.png\n\n// its equivalent helper method is\nenqueue('/assets/example.png');\n```\n\n\u003ca name=\"section-28\"\u003e\u003c/a\u003e\n\n## Pool Console\nPool is the command line interface included with Doppar. Pool exists at the root of your application as the pool script and provides a number of helpful commands that can assist you while you build your application. To view a list of all available Pool commands, you may use the list command:\n```bash\nphp pool list\n```\nIt will shows all the application commands\n**General Commands:**\n\n* `completion`: Dump the shell completion script.\n* `help`: Display help for a command.\n* `list`: List available commands.\n\n**Database Migration Commands:**\n\n* `migrate`: Runs new database migrations.\n* `migrate:fresh`: Rolls back all migrations and re-runs them.\n\n**Cache Management Commands:**\n\n* `cache:clear`: Clear all cache files from the `storage/framework` folder.\n* `config:clear`: Clear all config cache data.\n* `config:cache`: Cache the configuration files into a single file for faster access.\n* `view:cache`: Precompile all views and store them in the `storage/framework/views` folder.\n* `view:clear`: Clear all compiled view files from the `storage/framework/views` folder.\n\n**Database Seeding Commands:**\n\n* `db:seed`: Run database seeds.\n\n**Auth Commands:**\n\n* `make:auth`: Generates Doppar's builtin authentication scaffolding\n\n**Key Generation Commands:**\n\n* `key:generate`: Generate a new application key and set it in the `.env` file.\n\n**Code Generation (Make) Commands:**\n\n* `make:controller`: Creates a new controller class.\n* `make:middleware`: Creates a new middleware class.\n* `make:provider`: Creates a new service provider class.\n* `make:model`: Creates a new model class.\n* `make:migration`: Creates a new Phinx migration class.\n* `make:seed`: Creates a new Phinx seed class.\n\n**Session Management Commands:**\n\n* `session:clear`: Clear all session files from the `storage/framework/sessions` folder.\n\n**Storage Management Commands:**\n\n* `storage:link`: Create a symbolic link from `public/storage` to `storage/app/public`.\n\n**Development Server Command:**\n\n* `start`: Start the Doppar development server.\n\n\u003ca name=\"section-30\"\u003e\u003c/a\u003e\n\n## Encryption\nDoppar's encryption services provide a simple, convenient interface for encrypting and decrypting text via PHP's OpenSSL using `AES-256` and `AES-128` encryption. All of Doppar's encrypted values are signed using a message authentication code (MAC) so that their underlying value cannot be modified or tampered with once encrypted.\n\nBefore using Doppar's encrypter, you must set the key configuration option in your `config/app.php` configuration file. This configuration value is driven by the `APP_KEY` environment variable. You should use the `php pool key:generate` command to generate this variable's value since the `key:generate` command will use PHP's secure random bytes generator to build a cryptographically secure key for your application. Typically, the value of the `APP_KEY` environment variable will be generated for you during Doppar's installation.\n\n#### Encrypting a Value\nYou can use `Phaseolies\\Support\\Facades\\Crypt` facades to `encrypt` a string.\n```php\n\u003c?php\n\nnamespace App\\Http\\Controllers;\n\nuse Phaseolies\\Http\\Request;\nuse Phaseolies\\Support\\Facades\\Crypt;\n\nclass UserController extends Controller\n{\n    public function store(Request $request)\n    {\n        $encrypted = Crypt::encrypt(\"Hello World\");\n\n        $encrypted // This is now encrypted\n    }\n}\n```\n\n#### Decrypting a Value\nYou can use `Phaseolies\\Support\\Facades\\Crypt` facades to `decrypt` a string.\n```php\n\u003c?php\n\nnamespace App\\Http\\Controllers;\n\nuse Phaseolies\\Http\\Request;\nuse Phaseolies\\Support\\Facades\\Crypt;\n\nclass UserController extends Controller\n{\n    public function store(Request $request)\n    {\n        $decrypted = Crypt::decrypt($encrypted);\n\n        $encrypted // This is now decrypted\n    }\n}\n```\n\n\u003ca name=\"section-32\"\u003e\u003c/a\u003e\n\n## Database Connection\nTo connect the database you have to update `.env` configuration file and database related config file located in `config/database.php`. Doppar currently support only MYSQL database.\n```\nDB_CONNECTION=mysql\nDB_HOST=localhost\nDB_PORT=3306\nDB_DATABASE=\nDB_USERNAME=\nDB_PASSWORD=\n```\n\u003ca name=\"section-33\"\u003e\u003c/a\u003e\n\n## Database Migration\nManaging database changes by hand is risky and error-prone. Doppar's migration system takes the guesswork out of the equation by automating and organizing your schema changes — so you can focus more on building features and less on database headaches.\n\nDoppar provides a seamless and structured way to manage your database migrations, making it easy to evolve your database schema over time. With Doppar’s migration system, you can track changes, collaborate with your team, and keep your development, staging, and production environments in sync.\n\n### Create Migration\nTo create a new migration file, run this command\n```bash\nphp pool make:migration create_users_table --create=users\n```\nHere, `users` is the table name. This command will generate a new migration file by returning an anonymous class \ninstance. Now assume we are going to update this for define our database schema.\n\n```php\n\u003c?php\n\nuse Phaseolies\\Support\\Facades\\Schema;\nuse Phaseolies\\Database\\Migration\\Blueprint;\nuse Phaseolies\\Database\\Migration\\Migration;\n\nreturn new class extends Migration\n{\n    /**\n     * Run the migrations\n     *\n     * @return void\n     */\n    public function up(): void\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table-\u003eid();\n            $table-\u003estring('name');\n            $table-\u003estring('email')-\u003eunique();\n            $table-\u003estring('password', 100);\n            $table-\u003estring('remember_token', 100)-\u003enullable();\n            $table-\u003etimestamps();\n        });\n    }\n\n    /**\n     * Reverse the migrations\n     *\n     * @return void\n     */\n    public function down(): void\n    {\n        Schema::dropIfExists('users');\n    }\n};\n```\n### Run Migration\nTo migrate your all file or newly created migration files, run this `migrate` command\n```bash\nphp pool migrate\n```\n\n### Available Fields\nLet's see all the available columns types and options\n#### id()\nCreates an auto-incrementing primary key (unsigned big integer).\n```php\nSchema::create('users', function (Blueprint $table) {\n    $table-\u003eid();\n});\n```\n\n#### string()\nDefines a column with the `VARCHAR` type, ideal for storing short strings like names, titles, or labels. By default, the maximum length is 255 characters.\n```php\nSchema::create('users', function (Blueprint $table) {\n    $table-\u003estring('title');\n    // with custom length\n    $table-\u003estring('title', 100);\n});\n```\n\n### char()\nDefines a column with the `CHAR` type, ideal for storing short strings like names, titles, or labels. By default, the maximum length is 255 characters.\n```php\nSchema::create('users', function (Blueprint $table) {\n    $table-\u003echar('name');\n});\n```\n\n### tinyText()\nDefines a column with the `TINYTEXT` type, ideal for storing small blocks of text such as summaries, excerpts, or \ncontent.\n```php\nSchema::create('posts', function (Blueprint $table) {\n    $table-\u003etinyText('excerpt');\n});\n```\n\n### mediumText()\nDefines a column with the `MEDIUMTEXT` type, ideal for storing longer blocks of text such as summaries, excerpts, or content that exceeds the 255-character limit of a string.\n```php\nSchema::create('posts', function (Blueprint $table) {\n    $table-\u003emediumText('body');\n});\n```\n\n### text()\nDefines a column with the `TEXT` type, ideal for storing longer blocks of text such as summaries, excerpts, or content \nthat exceeds the 255-character limit of a string.\n```php\nSchema::create('posts', function (Blueprint $table) {\n    $table-\u003etext('body');\n});\n```\n\n### longText()\nDefines a column with the `LONGTEXT` type, perfect for storing very large amounts of text, such as full articles, blog post content, or rich HTML.\n```php\nSchema::create('posts', function (Blueprint $table) {\n    $table-\u003elongText('description');\n});\n```\n\n### json()\nDefines a column with the `JSON` type, ideal for storing structured data like arrays, objects, or key-value pairs. Useful when the data format is dynamic or flexible.\n```php\nSchema::create('posts', function (Blueprint $table) {\n    $table-\u003ejson('attributes');\n});\n```\n\n### integer()\nDefines a column with the `INT` type, ideal for storing whole numbers such as counts, IDs, or any data that doesn’t require decimal precision.\n```php\nSchema::create('posts', function (Blueprint $table) {\n    $table-\u003einteger('post_views');\n});\n```\n\n### boolean()\nDefines a column with the `BOOLEAN` type, which stores binary values: `true (1)` or `false (0)`. Typically used for flags or status indicators, such as whether a post is active or published.\n```php\nSchema::create('posts', function (Blueprint $table) {\n    $table-\u003eboolean('status');\n});\n```\n\n### timestamps()\nDefines two columns: `created_at` and `updated_at`. These are automatically managed by Eloquent to track when a record is created and last updated.\n```php\nSchema::create('posts', function (Blueprint $table) {\n    $table-\u003etimestamps();\n});\n```\n\n### unique()\nEnforces a unique constraint on a column, ensuring that no two rows can have the same value for that column. It's often used on columns like email addresses, slugs, or usernames to maintain data integrity.\n```php\nSchema::create('posts', function (Blueprint $table) {\n    $table-\u003estring('slug')-\u003eunique();\n});\n```\n\n### nullable()\nAllows a column to accept `null` values. By default, columns in Doppar are required, but using nullable() makes the \ncolumn optional, meaning it can store `NULL` values.\n```php\nSchema::create('posts', function (Blueprint $table) {\n    $table-\u003estring('excerpt')-\u003enullable();\n});\n```\n\n### default()\nSets a default value for a column if no value is provided during the creation of a record. This is useful for ensuring a column has a predetermined value when it’s not explicitly set.\n```php\nSchema::create('posts', function (Blueprint $table) {\n    $table-\u003eboolean('status')-\u003edefault(true);\n});\n```\n\n### Number Types\nDoppar migration includes various numeric column types to handle different ranges and precisions of data. Here's a quick \noverview:\n```php\n// Signed Integers:\n$table-\u003etinyInteger('tiny_int_column'); // 1 byte, range: -128 to 127\n$table-\u003esmallInteger('small_int_column'); // 2 bytes, range: -32,768 to 32,767\n$table-\u003emediumInteger('medium_int_column'); // 3 bytes, range: -8,388,608 to 8,388,607\n$table-\u003einteger('int_column'); // 4 bytes, range: -2,147,483,648 to 2,147,483,647\n$table-\u003ebigInteger('big_int_column'); // 8 bytes, range: -9.2 quintillion to 9.2 quintillion\n\n// Unsigned Integers (no negative values):\n$table-\u003eunsignedInteger('unsigned_int_column'); // 0 to 255\n$table-\u003eunsignedTinyInteger('unsigned_tiny_int_column'); // 0 to 65,535\n$table-\u003eunsignedSmallInteger('unsigned_small_int_column'); // 0 to 16,777,215\n$table-\u003eunsignedMediumInteger('unsigned_medium_int_column'); // 0 to 4,294,967,295\n\n// Floating Point Types:\n$table-\u003efloat('float_column', 8, 2); // Approximate numeric, total 8 digits, 2 after decimal\n$table-\u003edouble('double_column', 15, 8); // Higher precision float, total 15 digits, 8 after decimal\n$table-\u003edecimal('decimal_column', 10, 2); // Exact numeric, total 10 digits, 2 after decimal (ideal for currency)\n```\n\n### Date/Time Types\nDoppar migration includes a variety of date and time-related columns to cover different temporal data needs:\n```php\n$table-\u003edate('date_column'); // Stores only the date (format: YYYY-MM-DD)\n$table-\u003edateTime('datetime_column'); //  Stores date and time (format: YYYY-MM-DD HH:MM:SS)\n$table-\u003edateTimeTz('datetime_tz_column'); // Like dateTime, but includes time zone support\n$table-\u003etime('time_column'); // Stores only time (format: HH:MM:SS)\n\n// Time Zone Aware Columns:\n$table-\u003etimeTz('time_tz_column'); //  Like time, but with time zone awareness\n$table-\u003etimestamp('timestamp_column'); // Stores date and time, often used for tracking created/updated times\n$table-\u003etimestampTz('timestamp_tz_column'); // Time-stamped with time zone support\n\n$table-\u003eyear('year_column');\n$table-\u003esoftDeletes(); // Adds a deleted_at timestamp column\n```\n\n### Binary Types\nDoppar migration defines several binary and BLOB (Binary Large Object) column types to handle various sizes of binary data:\n```php\n// Standard Binary:\n$table-\u003ebinary('binary_column'); // Creates a BLOB column suitable for storing small binary data (up to 65,535 bytes). \n\n// Extended BLOB Types (MySQL-specific):\n$table-\u003etinyBlob('tiny_blob_column'); // Stores up to 255 bytes.\n$table-\u003eblob('blob_column'); // Stores up to 65,535 bytes.\n$table-\u003emediumBlob('medium_blob_column'); // Stores up to 16 MB.\n$table-\u003elongBlob('long_blob_column'); // Stores up to 4 GB\n```\n\n### Special Types\nDoppar migration utilizes several specialized column types to handle unique data requirements:\n```php\n\n// Defines a column with a set of predefined string  values. Commonly used for status indicators or categorical data.\n$table-\u003eenum('enum_column', ['active', 'pending', 'cancelled']); \n\n// Allows storage of multiple values from a predefined list in a single column.\n$table-\u003eset('set_column', ['red', 'green', 'blue']);\n\n$table-\u003euuid('uuid_column'); // Creates a column to store Universally Unique Identifiers (UUIDs).\n\n$table-\u003eipAddress('ip_address_column'); // Stores IPv4 and IPv6 addresses.\n$table-\u003emacAddress('mac_address_column'); // Stores MAC addresses. Typically stored as strings in the format 00:00:00:00:00:00\n$table-\u003ejson('json_column'); // Stores JSON-formatted data. Supported in MySQL 5.7+\n```\n\n### Spatial Types (GIS)\nDoppar migration utilizes several specialized column types to handle geospatial data, enabling advanced geographical queries and operations:\n```php\n$table-\u003egeometry('geometry_column'); // Stores any type of geometry data.\n$table-\u003epoint('point_column'); // Represents a single location in coordinate space (latitude and longitude).\n$table-\u003elineString('line_string_column'); // Stores a sequence of points forming a continuous line.\n$table-\u003epolygon('polygon_column'); // Defines a shape consisting of multiple points forming a closed loop.\n$table-\u003egeometryCollection('geometry_collection_column'); // Stores a collection of geometry objects.\n$table-\u003emultiPoint('multi_point_column'); // Stores multiple point geometries.\n$table-\u003emultiLineString('multi_line_string_column'); // Stores multiple linestring geometries.\n$table-\u003emultiPolygon('multi_polygon_column'); // Stores multiple polygon geometries.\n```\n\n### Determining Whether a Table Exists\nYou can determine whether or not a table exists by using the `hasTable()` method.\n```php\n\nuse Phaseolies\\Support\\Facades\\Schema;\n\npublic function up()\n{\n    if (Schema::hasTable('users')) {\n        // do something\n    }\n}\n```\n\n### Dropping a Table\nTables can be dropped quite easily using the `drop()` method.\n```php\n\nuse Phaseolies\\Support\\Facades\\DB;\n\nDB::table('users')-\u003edrop()\n```\n\n### Truncate a Table\nTables can be Truncated easily using the `truncate()` method.\n```php\n\nuse Phaseolies\\Support\\Facades\\DB;\n\nDB::table('users')-\u003etruncate()\nDB::table('users')-\u003etruncate(true) // passing true mean force reset auto increment\n```\n\n### Enable Disable Foreign Key Constraints\nYou can easily disable and enable foreign key constraints using Schema facades by calling `disableForeignKeyConstraints()` method to disable and `enableForeignKeyConstraints()` method to enable like\n```php\n\nuse Phaseolies\\Support\\Facades\\Schema;\n\nSchema::disableForeignKeyConstraints();\nSchema::enableForeignKeyConstraints();\n```\n\n### Working With Foreign Keys\nFor creating foreign key constraints on your database tables. Let’s add a foreign key to an example table:\n```php\n\nuse Phaseolies\\Support\\Facades\\Schema;\nuse App\\Models\\User;\n\npublic function up()\n{\n    Schema::create('posts', function (Blueprint $table) {\n        $table-\u003eforeignIdFor(User::class)-\u003enullable();\n\n        // or you can use like that\n        $table-\u003eunsignedBigInteger('user_id');\n        $table-\u003eforeign('user_id')-\u003ereferences('id')-\u003eon('users');\n    })\n}\n```\n\nIn Doppar, when defining foreign key constraints within your migrations, you can specify actions to be taken when the \nreferenced record is deleted. This ensures referential integrity and allows for automatic management of related records.\n\n#### Setting Up CASCADE Actions\nThere are three primary ways to define `CASCADE` actions in Doppar migrations:\n```php\npublic function up()\n{\n     // true for onDeleteCascade and true for onUpdateCascade\n     $table-\u003eforeignIdFor(User::class, true, true);\n\n     // Or\n     $table-\u003eunsignedBigInteger('user_id');\n     $table-\u003eforeign('user_id')\n         -\u003ereferences('id')\n         -\u003eon('users')\n         -\u003eonDelete('CASCADE');\n\n     // Using the cascadeOnDelete Shortcut:\n     $table-\u003eunsignedBigInteger('user_id');\n     $table-\u003eforeign('user_id')\n         -\u003ereferences('id')\n         -\u003eon('users')\n         -\u003ecascadeOnDelete();\n}\n```\n\nYou can also use this method `cascadeOnDelete()`, `restrictOnDelete()`, `nullOnDelete()`, `cascadeOnUpdate()`, \n`restrictOnUpdate()`, `nullOnUpdate()`.\n\n### Refreshing Migrations\nThe `php pool migrate:fresh` command is a powerful tool in Doppar that allows you to reset and re-run all your \nmigrations. This is particularly useful during development when you need to rebuild your database schema without manually rolling back and reapplying each migration.\n\n#### What It Does\nWhen you run:\n```php\nphp pool migrate:fresh\n```\nDoppar performs the following actions\n- Rolls back all existing migrations by executing the down() methods.\n- Re-runs all migrations by executing the up() methods\n\nThis process effectively rebuilds your entire database schema.\n\n\u003ca name=\"section-34\"\u003e\u003c/a\u003e\n\n### Database Seeder\nNo you know that seeder is the most important thing when you develop a web application. Doppar support Database \nSeeding. Doppar includes the ability to seed your database with data using seed classes. All seed classes are stored \nin the `database/seeders` directory. To create a Seeder class, run this command\n```php\nphp pool make:seeder UserSeeder\n```\nNow it will generate a file like\n```php\n\u003c?php\n\nnamespace Database\\Seeders;\n\nuse Phaseolies\\Database\\Migration\\Seeder;\n\nclass UserSeeder extends Seeder\n{\n    /**\n     * Run the database seeds.\n     *\n     * @return void\n     */\n    public function run(): void\n    {\n        //\n    }\n}\n\n```\n\nNow you can seed data from this class by updating run method. You can update run method like\n```php\n\u003c?php\n\nnamespace Database\\Seeders;\n\nuse App\\Models\\User;\nuse Phaseolies\\Database\\Migration\\Seeder;\n\nclass UserSeeder extends Seeder\n{\n    /**\n     * Run the database seeds.\n     *\n     * @return void\n     */\n    public function run(): void\n    {\n        User::create([\n            'name' =\u003e fake()-\u003ename(),\n            'email' =\u003e fake()-\u003eemail(),\n            'password' =\u003e bcrypt('password')\n        ]);\n    }\n}\n```\n\nRemember that `fake()` is a global helper function, so you can use it in your entire application where you want.\n\n### Run The Seed\nTo run the database seeder, there is also pool console command. Run this command to seed database\n```bash\nphp pool db:seed // it will seed all seeder class\nphp pool db:seed UserSeeder // It will only seed UserSeed class\n```\n\n\u003ca name=\"section-35\"\u003e\u003c/a\u003e\n\n## Hashing Configuration\nThe `config/hashing.php` file in Doppar allows you to configure password hashing for your application. This configuration determines the algorithm used to securely store user passwords.\n\n**Key Configuration Options:**\n\n* **`driver`**:\n    * This option specifies the default hashing algorithm to be used.\n    * Doppar supports the following drivers:\n        * `bcrypt`: A widely used and secure hashing algorithm.\n        * `argon`: A modern and secure hashing algorithm.\n        * `argon2id`: The most modern and recommended argon variant.\n    * **Default:** `argon2id` (recommended).\n\n* **`bcrypt`**:\n    * This section configures options for the `bcrypt` hashing algorithm.\n    * **`rounds`**:\n        * Controls the number of rounds used in the bcrypt hashing process.\n        * Higher rounds increase the time taken for hashing, making it more secure but also slower.\n        * The value is read from the `BCRYPT_ROUNDS` environment variable, with a default of 10.\n        * Configure this value in your `.env` file.\n\n* **`argon`**:\n    * This section configures options for the `argon` hashing algorithm.\n    * **`memory`**:\n        * Specifies the amount of memory (in kilobytes) used by the argon hashing algorithm.\n        * Increasing this value enhances security but increases memory usage.\n        * **Default:** `65536`\n    * **`threads`**:\n        * Specifies the number of threads used by the argon hashing algorithm.\n        * Increasing this value can speed up the hashing process on multi-core systems.\n        * **Default:** `1`\n    * **`time`**:\n        * Specifies the number of iterations for the argon hashing algorithm.\n        * Increasing this value increases the time taken for hashing, making it more secure.\n        * **Default:** `4`\n\n**Usage:**\n\n* To change the default hashing driver, modify the `driver` option in the `config/hashing.php` file.\n* To customize the bcrypt rounds, set the `BCRYPT_ROUNDS` environment variable in your `.env` file.\n* To change the argon configuration, modify the 'argon' array in the `config/hashing.php` file.\n\nNow we you create hash password using `bcrypt()` or direct calling `Hash::make()` method.\n```php\n$hashedValue = bcrypt('bcrypt');\n$hashedValue // \"$2y$10$gtr.qSIRWTDh7uh9ubj5duC0/KwQJcwZ0.KpFPOPzeRClpwo2FRSa\"\n```\n### Hash Facades\nWe can create hash password using `Hash::make()` method.\n\n```php\nuse Phaseolies\\Support\\Facades\\Hash;\n\n$hashedValue = Hash::make('password');\n$hashedValue // \"$2y$10$qcxCuljWvI7e1A5ah6axl.qgNsVoNw3ad8HSDFRmnVxyzIoj5/x8m\"\n```\n\n### Checking Hash\nIf you want to check hash data, you need to use `check` method\n```php\nuse Phaseolies\\Support\\Facades\\Hash;\n\nif (Hash::check('plainText', 'hashedValue')) {\n    // Password matched\n}\n```\n\n### Determining if a Password Needs to be Rehashed\nCheck if a password hash needs rehashing (security upgrade). The needsRehash method provided by the Hash class allows you to determine if the work factor used by the hasher has changed since the password was hashed. Some applications choose to perform this check during the application's authentication process:\n```php\nif (Hash::needsRehash($hashed)) {\n    $hashed = Hash::make('plain-text');\n}\n```\n\n\u003ca name=\"section-36\"\u003e\u003c/a\u003e\n\n## Authentication\nDoppar provides built-in authentication features, simplifying user login and logout processes. This section details how to use these features within your application. To generate authentication, Doppar provides a `make:auth` command. \n```bash\nphp pool make:auth\n```\n\nThis command will generate authentication for you. Let's look up the authentication features code.\n\n\n### Login Functionality\n\nDoppar's authentication system allows you to easily verify user credentials and establish a login session. Doppar provides `Phaseolies\\Support\\Facades\\Auth` to create authentication functionalitis\n\n**Implementation:**\n\n1.  **Controller Setup:**\n    * Use the `Phaseolies\\Support\\Facades\\Auth` to access authentication methods.\n\n2.  **Login Method:**\n    * Utilize the `sanitize` method to validate and sanitize user input (e.g., email and password).\n    * Call the `Auth::try()` method, passing the validated credentials (`$request-\u003epassed()`).\n    * If `Auth::try()` returns `true`, the user is successfully logged in.\ny you will get login and logout features. To do login\n```php\n\u003c?php\n\nnamespace App\\Http\\Controllers\\Auth;\n\nuse Phaseolies\\Http\\Request;\nuse Phaseolies\\Support\\Facades\\Auth;\nuse App\\Http\\Controllers\\Controller;\n\nclass LoginController extends Controller\n{\n    public function login(Request $request)\n    {\n        $request-\u003esanitize([\n            'email' =\u003e 'required|email|min:2|max:100',\n            'password' =\u003e 'required|min:2|max:20',\n        ]);\n\n        if (Auth::try($request-\u003epassed())) {\n            // User is logged in\n        }\n    }\n}\n\n```\n\n### Auth Via Remember Me\nIf you want to create auth using remember me, then you just need to pass, true as the second parameter in try method like\n```php\nif (Auth::try($request-\u003epassed(), true)) {\n    // User is logged in\n}\n```\n\n### Auth using login()\nIf you want to create auth using user object, then you just need to pass the use object, like\n```php\nif (Auth::login($user)) {\n    // User is logged in\n}\n```\n\nYou can also use login() via `remember_token` by passing true as the second argument.\n```php\nif (Auth::login($user, true)) {\n    // User is logged in with remember_token token\n}\n```\n### Auth using loginUsingId()\nThis method logs in a user persistently, meaning the authentication is stored in the `session`.\n```php\nif (Auth::loginUsingId($user-\u003eid)) {\n    // User is logged in\n}\n```\n\n### Auth using onceUsingId()\nThis method logs in a user for a single request only, meaning authentication is not stored in the `session` or `cookies`.\n```php\nif (Auth::onceUsingId(1)) {\n    // User is logged in\n}\n```\n\n### Custom Authentication Key\nIn some applications, authentication is not based on email but instead uses a `mobile number` or `username`. By default, Doppar uses `email` and `password` for authentication. However, you can change this behavior by overriding the `getAuthKeyName()` method in your `User` model.\n#### How to Customize the Authentication Key\nTo switch from `email-based authentication` to `username-based authentication`, override the getAuthKeyName() method in your model:\n\n```php\n/**\n * Get the authentication key name used for identifying the user.\n * @return string\n */\npublic function getAuthKeyName(): string\n{\n    return \"username\"; // set any key for authentication like phone\n}\n```\nNow, instead of logging in with an `email`, Doppar will use the `username` field for authentication.\n\n### Get Authenticated User Data\nTo get the current authenticated user data, Doppar has `Auth::user()` method and `auth()` helper. Simply call\n```php\nAuth::user(); // Current authenticated user data\nauth()-\u003euser() // Current authenticated user data using auth() helper\n\n// or you can use\n$request-\u003euser();\n\n// or you can use also request() helper\nrequest()-\u003euser();\n\n// or you can use also auth() helper\nrequest()-\u003eauth();\n```\n\n### Logout\nTo destroy user session, simply call `logout` function.\n```php\n\u003c?php\n\nnamespace App\\Http\\Controllers\\Auth;\n\nuse Phaseolies\\Http\\Request;\nuse Phaseolies\\Support\\Facades\\Auth;\nuse App\\Http\\Controllers\\Controller;\n\nclass LoginController extends Controller\n{\n    public function logout()\n    {\n        Auth::logout(); // User login session is now destroyed\n    }\n}\n\n```\n\u003ca name=\"section-37\"\u003e\u003c/a\u003e\n\n## Mail Configuration\nDoppar provides a convenient way to setup your mail configuration. Doppar currently support only `smtp` driver for mail configuration. Need to update `.env`'s mail configuration before starting with mail features. Doppar usage `PHPMailer` tp send mail.\n```\nMAIL_MAILER=smtp\nMAIL_HOST=\nMAIL_PORT=2525\nMAIL_USERNAME=\nMAIL_PASSWORD=\nMAIL_ENCRYPTION=tls\nMAIL_FROM_ADDRESS=\"hello@example.com\"\nMAIL_FROM_NAME=\"${APP_NAME}\"\n```\n\nNow you can check also mail related configuration from `config/mail.php` file. Remember, if you update, `config/mail.php` file, don't forget to clear your system cache.\n```bash\nphp pool cache:clear // to clear the cache\nphp pool config:cache // to cache again\n```\n\nNow if you setup with your `smtp` mail credentials, now you are ready to go.\n\n\u003ca name=\"section-38\"\u003e\u003c/a\u003e\n\n## Sending Mail\nWhen building Doppar applications, each type of email sent by your application is represented as a \"mailable\" class. These classes are stored in the `app/Mail` directory. Don't worry if you don't see this directory in your application, since it will be generated for you when you create your first mailable class using the `make:mail` Pool command:\n```bash\nphp pool make:mail InvoicMail\n```\n\n### Configuring the Sender\nYou specify a global \"`from`\" address in your `config/mail.php` configuration file. This address will be used to send mail.\n```\n'from' =\u003e [\n    'address' =\u003e env('MAIL_FROM_ADDRESS', 'hello@example.com'),\n    'name' =\u003e env('MAIL_FROM_NAME', 'Example'),\n],\n```\n\n### Configuring the Subject\nBy time to time, every Mail has a subject. Doppar allows you to define a Mail subject in a very convenient way. To define Mail subject, just need to update the subject method from your mailable class.\n```php\n/**\n * Define mail subject\n * @return Phaseolies\\Support\\Mail\\Mailable\\Subject\n */\npublic function subject(): Subject\n{\n    return new Subject(\n        subject: 'New Mail'\n    );\n}\n```\n\n### Configuring the View\nWithin a mailable class's content method, you may define the view, or which template should be used when rendering the email's contents. Since each email typically uses a Blade template to render its contents, you have the full power and convenience of the Blade templating engine when building your email's HTML:\n```php\n/**\n * Set the message body and data\n * @return Phaseolies\\Support\\Mail\\Mailable\\Content\n */\npublic function content(): Content\n{\n    return new Content(\n        view: 'Optional view.name'\n    );\n}\n```\n\nIf you want to pass the data without views, you can pass string or array data.\n```php\npublic function content(): Content\n{\n    return new Content(\n        data: [\n           'order_status' =\u003e true\n        ]\n    );\n}\n```\n\nEven you can send mail without passing any data to Content. Suppose you just want to pass attachment only. you can do in this case, just make content empty.\n```php\npublic function content(): Content\n{\n    return new Content();\n}\n```\n\n### Complete Example of Sending Mail\nDoppar provides `to` and `send` method primaritly to send a basic mail. You can use `Phaseolies\\Support\\Facades\\Mail` call to handle mail functionalities.\n```php\n\u003c?php\n\nnamespace App\\Http\\Controllers;\n\nuse Phaseolies\\Support\\Facades\\Mail;\nuse App\\Models\\User;\nuse App\\Http\\Controllers\\Controller;\nuse App\\Mail\\InvoiceMail;\n\nclass OrderController extends Controller\n{\n    public function index()\n    {\n        $user = User::find(1);\n\n        $data = [\n            'order_status' =\u003e 'success',\n            'invoice_no' =\u003e '123-123'\n        ];\n\n        Mail::to($user)-\u003esend(new InvoiceMail($data));\n\n        // or you can send mail by passing only mail address\n        Mail::to('recipient@example.com')-\u003esend(new InvoiceMail($data));\n\n        // also by passing name as the second argument\n        Mail::to('recipient@example.com', 'recipient_name')-\u003esend(new InvoiceMail($data));\n    }\n}\n```\n\nNow update your `InvoiceMail` mailable class like\n```php\n\u003c?php\n\nnamespace App\\Mail;\n\nuse Phaseolies\\Support\\Mail\\Mailable\\Subject;\nuse Phaseolies\\Support\\Mail\\Mailable\\Content;\nuse Phaseolies\\Support\\Mail\\Mailable;\n\nclass InvoiceMail extends Mailable\n{\n    public function __construct(protected $data) {}\n\n    public function subject(): Subject\n    {\n        return new Subject(\n            subject: \"Order Shipped Confirmation\"\n        );\n    }\n\n    public function content(): Content\n    {\n        return new Content(\n            view: 'emails.order.invoice', // 'resources/views/emails/order/invoice.blade.php'\n            data: $this-\u003edata // Passing data will be available in invoice.blade.php, access it via {{ $data }}\n        );\n    }\n\n    public function attachment(): array\n    {\n        return [];\n    }\n}\n```\n\n\u003ca name=\"section-39\"\u003e\u003c/a\u003e\n\n## Sending Mail with Attachment\nTo send mail with attachment, you have to pass data attachment path using `attachment` method.\n```php\npublic function attachment(): array\n{\n    return [\n        storage_path('invoice.pdf') =\u003e [\n            'as' =\u003e 'rename_invoice.pdf', // The file will be sent using this name\n            'mime' =\u003e 'application/pdf',  // file mime types\n        ]\n    ];\n}\n```\n\n### Multiple Attachments with Mime Types\nYou can also send mail with multiple attachment. Just pass your file arrays in the attachment method like\n```php\npublic function attachment(): array\n{\n    return [\n        storage_path('invoice_1.pdf') =\u003e [\n            'as' =\u003e 'invoice_3.pdf',\n            'mime' =\u003e 'application/pdf',\n        ],\n        storage_path('invoice_2.pdf') =\u003e [\n            'as' =\u003e 'invoice_3.pdf',\n            'mime' =\u003e 'application/pdf',\n        ],\n        storage_path('invoice_3.pdf') =\u003e [\n            'as' =\u003e 'invoice_3.pdf',\n            'mime' =\u003e 'application/pdf',\n        ],\n    ];\n}\n```\n\nHere both `as` and `mime` is optional, you can simply send email attachment like\n```php\npublic function attachment(): array\n{\n    return [\n        storage_path('invoice_1.pdf'),\n        storage_path('invoice_2.pdf'),\n        storage_path('invoice_3.pdf')\n    ];\n}\n```\n\u003ca name=\"section-40\"\u003e\u003c/a\u003e\n## Sending Mail with CC and BCC\nYou are not limited to just specifying the \"to\" recipients when sending a message. You are free to set \"to\", \"cc\", and \"bcc\" recipients by chaining their respective methods together:\n```php\nuse Phaseolies\\Support\\Mail\\Mail;\n\nMail::to($request-\u003euser())\n    -\u003ecc($moreUsers)\n    -\u003ebcc($evenMoreUsers)\n    -\u003esend(new OrderShipped($order));\n```\n\n\u003ca name=\"section-42\"\u003e\u003c/a\u003e\n## File Storage\nDoppar's filesystem configuration file is located at `config/filesystems.php`. Within this file, you may configure all of your filesystem \"`disks`\". Each disk represents a particular storage driver and storage location. Example configurations for each supported driver are included in the configuration file so you can modify the configuration to reflect your storage preferences and credentials.\n\nYou may configure as many disks as you like and may even have multiple disks that use the same driver. But if you change any of your configuration, and that is not wokring, please clean the application configuration by running the command `config:clear`.\n\n## The Local Driver\nWhen using the local driver, all file operations are relative to the root directory defined in your filesystems configuration file. By default, this value is set to the `storage/app/` directory. Therefore, the following method would write to `storage/app/example.txt`.\n\n```php\nuse Phaseolies\\Support\\Facades\\Storage;\n\nStorage::disk('local')-\u003estore($request-\u003efile('file'));\n```\n\n## The Public Disk\nThe public disk included in your application's filesystems configuration file is intended for files that are going to be publicly accessible. By default, the public disk uses the local driver and stores its files in `storage/app/public`.\n\nIf your public disk uses the local driver and you want to make these files accessible from the web, you should create a `symbolic link` from source directory `storage/app/public` to target directory `public/storage`:\n\nTo create the symbolic link, you may use the `storage:link` Pool command:\n```bash\nphp pool storage:link\n```\n\nOnce a file has been stored and the symbolic link has been created, you can create a URL to the files using the `enqueue` helper:\n```php\necho enqueue('storage/file.txt');\n```\n\n\u003ca name=\"section-43\"\u003e\u003c/a\u003e\n## File Upload\nTo upload file, you can use `Phaseolies\\Support\\Facades\\Storage` facades or you can use direct file object. To upload a image using Storage facades\n\n```php\nuse Phaseolies\\Support\\Facades\\Storage;\n\nStorage::disk('public')-\u003estore('profile', $request-\u003efile('file'));\n```\n\nThis will store file into `storage/app/public/profile` directory. here `profile` is the directory name that is optional. If you do not pass `profile`, it will storage file to its default path like `storage/app/public`. You can also uploads file into `local` disk that is a private directory.\n\n```php\nuse Phaseolies\\Support\\Facades\\Storage;\n\nStorage::disk('local')-\u003estore('profile', $request-\u003efile('file'));\n```\n\nThis will store file into `storage/app/profile` directory. here `profile` is the directory name that is optional. If you do not pass `profile`, it will storage file to its default path like `storage/app`. You can also uploads file into `local` disk that is a private directory.\n\n### Upload with custom file name\nIf you want to upload file using your customize file name, then remember, `store()` third parameter as `$fileName`. see the example\n\n```php\n$file = uniqid() . '_' . $request-\u003efile('file')-\u003egetClientOriginalName();\n\nStorage::disk('local')-\u003estore('profile', $request-\u003efile('file'), $file);\n```\n\n### Get the uploaded File\nNow if you want to get the uploaded file path, simply you can use `get()` method\n```php\nreturn Storage::disk('local')-\u003eget('profile.png'); // it will return the file path\n```\n\n### Get the uploaded file contents\nTo get the uploaded file contents, you can call `contents()` method, like\n```php\nreturn Storage::disk('local')-\u003econtent('product/product.json');\n```\n\n### Delete file\nTo delete file from storage disk, you can call `delete()` method\n```php\nreturn Storage::disk('local')-\u003edelete('product/product.json');\n```\n\n### Upload File Except Storage\nYou can upload file any of your application folder. Doppar allows it also. To upload file without `Storage` facades, \n```php\n$request-\u003efile('file')-\u003estore('product');\n```\n\nNow your file will be stored in profuct directory inside storage folder. You can also use the `storeAs` method by passing your custom file name. \n```php\n$request-\u003efile('file')-\u003estoreAs('product-cart', 'my_customize_file_name');\n```\nNow your file will be stored in `product-cart` directory with the name of `my_customize_file_name`. You can also pass callback with `storeAs` method like\n```php\n$admin = 0;\n$request-\u003efile('file')-\u003estoreAs(function ($file) use ($admin) {\n    if (! $admin) {\n        return true;\n    }\n}, 'product-cart', 'file_name');\n```\nYou can also use `move` method to upload your file.\n```php\n$file = $request-\u003efile('invoice');\n$file-\u003emove($destinationPath, $fileName)\n```\n\n### File Downloads\nThe download method generates a response that triggers a file download in the user’s browser. It takes the file path as its primary argument. Optionally, you can specify a custom download filename as the second argument—this overrides the default name seen by the user. Additionally, an array of custom HTTP headers can be passed as a third argument for further control over the download behavior.\n```php\nreturn response()-\u003edownload($pathToFile);\n\nreturn response()-\u003edownload($pathToFile, $name, $headers);\n```\n### File Responses\nThe file method may be used to display a file, such as an image or PDF, directly in the user's browser instead of initiating a download. This method accepts the absolute path to the file as its first argument and an array of headers as its second argument:\n```php\nreturn response()-\u003efile($pathToFile);\n\nreturn response()-\u003efile($pathToFile, $headers);\n```\n\n### Streamed Responses\nStreaming data to the client as it is generated can greatly reduce memory usage and enhance performance, particularly for extremely large responses.\n```php\npublic function streamedContent(): \\Generator\n{\n    yield 'Hello, ';\n    yield 'World!';\n}\n\nreturn response()-\u003estream(function (): void {\n    foreach ($this-\u003estreamedContent() as $chunk) {\n        echo $chunk;\n        ob_flush();\n        flush();\n        sleep(2); // Simulate delay between chunks...\n    }\n}, 200, ['X-Accel-Buffering' =\u003e 'no']);\n```\n\n### Streamed JSON Responses\nTo stream JSON data incrementally, you can use the `streamJson` method. This is particularly beneficial for large datasets that need to be sent progressively to the browser in a format that JavaScript can easily parse\n```php\nreturn response()-\u003estreamJson([\n    'users' =\u003e User::all(),\n]);\n```\n\n\u003ca name=\"section-49\"\u003e\u003c/a\u003e\n\n## Helpers\nDoppar provides a collection of global helper functions in PHP. While many of these functions are integral to the framework’s internal operations, they are also available for use in your own projects whenever they prove useful.\n\n### env()\nThe `env()` function in Doppar is used to retrieve environment variables from the application's configuration. It allows you to define environment-specific settings in a .env file and access them throughout your application. If the specified variable is not found, you can provide a default value as a fallback.\n```php\n$databaseHost = env('DB_HOST', 'localhost');\n```\nIn this example, `DB_HOST` is fetched from the environment file, and if it's not set, 'localhost' is returned as the default.\n\n### app()\nThe `app()` function provides access to the service container instance in thouht it return the `Application` instance of Doppar. It can be used to resolve dependencies, retrieve bound services, or access the container itself.\n```php\n$app = app(); // This returns the global Application instance.\n```\nBut if your pass a class like\n```php\n$logger = app(Logger::class); // This fetches an instance of Logger.\n```\nYou can Resolve a service with parameters as well\n```php\n$service = app(MyService::class, ['param1' =\u003e 'value']);\n```\nThis retrieves `MyService` while passing custom parameters. This function simplifies dependency injection, making it easier to manage and access services within the application.\n\n### url()\nThe `url()` function is a convenient helper for creating a new instance of the UrlGenerator class, which is responsible for handling urls in Doppar. By calling this function, you can easily manage urls.\n```php\n return url()\n    -\u003eto('/profile')\n    -\u003ewithQuery('foo=bar\u0026baz=qux') // you can pass here array also like ['foo' =\u003e 'bar', 'baz' =\u003e 'qux']\n    -\u003ewithFragment('about')\n    -\u003ewithSignature(3600)\n    -\u003esetSecure(true)\n    -\u003emake();\n\n// it will generate url like that\n// http://example.com/profile?foo=bar\u0026baz=qux\u0026expires=1742923201\u0026signature=2cd1656d3557f64a433de7dcb01abbb64c2dc9daa85983b8dad88f8ac732a935#about\n```\n\nYou can also generate url by passing parameters like\n```php\nurl('/profile'); // http://example.com/profile\n\nurl()-\u003eto('profile')-\u003emake(); // http://example.com/profile\n\nurl('profile', ['id' =\u003e 123]); http://example.com/profile?id=123\n```\n\n### Full URL and Current URL\nIf you need to get the `full` url and `current` url, you can follow this\n```php\nurl()-\u003efull(); // it will return url with query string\nurl()-\u003ecurrent(); // it will return url without query string\n```\n### Base URL\nYou can get the application base url like\n```php\nurl()-\u003ebase(); // you can also do it base_url('/foo') -\u003e http://example.com/foo\n```\n\n### Route URL\nYou can also create URL from the route name.\n```php\nRoute::get('/home', [HomeController::class, 'home'])-\u003ename('dashboard');\n\nurl()-\u003eroute('dashboard'); // here dashboard is the route name\n```\n\n### Signed URL\nYou can generate signed url like that\n```php\nurl()-\u003esigned('dashboard') // http://example.com/dashboard?expires=1742924701\u0026signature=403e835e62dd107314167399cb04a4a50897467c5248c3059a5e53f7388d0760\n```\n\n### URL with Secure HTTPS\nYou can also generate url with https by calling `setSecure()` method like\n```php\nurl()-\u003esetSecure(true)-\u003esigned('dashboard');\n// https://example.com/dashboard?expires=1742924773\u0026signature=e92792a28fe270e3539a297d452a5856fd1787a24ed65ea65a87ee333f068086\n```\n\n### Check Valid URL\nYou can check a URL is valid or not using `isValid()` method like\n```php\nurl()-\u003eisValid('example.com');\n```\n\n### request()\nThe `request()` function is a convenient helper for creating a new instance of the Request class, which is responsible for handling HTTP requests in Doppar. By calling this function, you can easily access the incoming request data, such as `GET`, `POST` parameters, `headers`, `cookies`, and more.\n```php\n$request = request();\n```\nThis returns a new instance of the Request class, allowing you to interact with the current HTTP request. To access the request data, such as retrieving a query parameter:\n```php\n$name = request()-\u003equery('name');\n```\nThis function simplifies the process of working with HTTP requests by providing direct access to the request object, streamlining data retrieval and manipulation.\n\n### More Usage\n```php\nrequest('key', 'default');\n```\n- Retrieves the value of key from the current request.\n- Returns 'default' if the key does not exist.\n\n### Example:\n```php\n$name = request('name', 'Guest'); // Returns the 'name' from the request or 'Guest' if not set\n```\n\nYou can do the same thing using `request()` object like\n```php\n$name = request()-\u003einput('name', 'Guest'); // as request object\n```\n\n### response()\nThe `response()` function in Doppar is a helper used to generate and return HTTP response instances. It provides a flexible way to create a response, whether it’s with content or just an empty response, and allows setting the HTTP status code and headers.\n```php\nreturn response('Hello, World!', 200, ['Content-Type' =\u003e 'text/plain']);\n```\nCreate a response without content (just a status and headers):\n```php\nreturn response(null, 404);\n```\nCreate a response factory when no arguments are passed:\n```php\n$responseFactory = response();\n```\nIf no arguments are passed, the function returns a ResponseFactory instance, which can be used to generate responses later.\n\n### view()\nThe `view()` function in Doppar is a helper used to render a view with the given data and return a response containing the rendered content. It simplifies the process of rendering views and sending them as HTTP responses, while also allowing you to add custom headers if needed.\n```php\nreturn view('home', ['name' =\u003e 'John']);\n```\nThis renders the home view, passing the data array ['name' =\u003e 'John'] to the view and returning a response with the rendered content. as third parameters, it accept headers also\n```php\nreturn view('welcome', ['user' =\u003e 'Alice'], ['X-Custom-Header' =\u003e 'Value']);\n```\nThis function provides a simple way to return rendered views as HTTP responses, while also giving you the flexibility to set custom headers and pass data to the views.\n\n### redirect()\nThe `redirect()` function in Doppar is a helper for creating and returning HTTP redirects. It simplifies the process of redirecting the user to a different URL, optionally with a specific HTTP status code, headers, and security (HTTPS) settings.\n```php\nreturn redirect('/home');\n```\nRedirect with headers and security (HTTPS):\n```php\nreturn redirect('/profile', 302, ['X-Redirect-Notice' =\u003e 'Redirecting...'], true);\n```\nGet the redirect instance without redirection (factory usage):\n```php\n$redirect = redirect();\n```\nIf no arguments are provided, it returns the RedirectResponse instance, which can be used to perform redirects later. This helper function streamlines the process of handling HTTP redirects in doppar application, providing flexibility for status codes, headers, and security options.\n\n### back()\nThe `back()` function in Doppar is a helper used to create a redirect response to the previous location (the referring page), which is commonly used for scenarios like redirecting a user back after a form submission or an action that requires them to return to where they were.\n```php\nreturn back();\n```\nThis redirects the user back to the previous location using the default status code (302). A RedirectResponse instance, which will redirect the user either to the previous location or the fallback location.\n```php\n// Redirect back with default 302 status\nreturn back();\n\n// Redirect back with a custom status code and headers\nreturn back(301, ['Cache-Control' =\u003e 'no-store']);\n\n// Redirect back with a fallback URL if the referer is not available\nreturn back(302, [], '/home');\n```\n### session()\nThe `session()` function in Doppar is a helper used to interact with the session data. It provides a convenient way to retrieve, set, or manage session data. This helper simplifies working with sessions by abstracting some of the underlying complexities and making session data access more straightforward.\n```php\n$value = session('user_id');\n```\nThis retrieves the value stored in the session under the key 'user_id'. \n```php\n// Retrieve session value for 'user_id'\n$userId = session('user_id');\n\n// Set session value for 'user_id'\nsession('user_id', 123);\n\n// Retrieve session value with a default fallback\n$username = session('user_name', 'Guest');\n\n// Store multiple session values at once\nsession(['user_id' =\u003e 123, 'user_name' =\u003e 'John']);\n\n// Access the entire session instance\n$session = session();\n```\n\n### cookie()\nThe cookie() function is a helper designed to interact with HTTP cookies in Doppar. It allows you to retrieve, create, and manage cookies within your application. Cookies are used to store small pieces of data on the user's browser, such as session identifiers, authentication tokens, or user preferences.\n#### Example\n```php\n// Access the entire cookie instance\n$cookie = cookie();\n\n// Store cookie values\ncookie()-\u003estore('cookie_name', 'cookie_value');\n\n// Get cookie value\ncookie()-\u003eget('cookie_name', 'default');\n```\n\n### csrf_token()\nThe `csrf_token()` function is a helper designed to fetch the CSRF (Cross-Site Request Forgery) token from the session. CSRF tokens are used to protect forms from malicious attacks by ensuring that the request originates from the intended user and not from a potential attacker.\n```php\n$token = csrf_token();\n```\n### bcrypt()\nThe `bcrypt()` function is a helper designed to hash a plain text password using the Bcrypt hashing algorithm. This function is commonly used in authentication systems to store passwords securely by converting them into a hashed value that cannot be easily reversed.\n```php\n$hashedPassword = bcrypt('myPlainTextPassword');\n```\n### old()\nThe `old()` function is a helper used to retrieve the old input value for a given key from the session. This is particularly useful in scenarios like form validation, where you want to repopulate form fields with the user's previously entered data after a validation failure.\n```php\n$value = old('email');\n```\nThis will return the previously entered value for the input field with the key `email`, or null if no old value is found.\n#### Example\n```html\n// Example in a form input field\n\u003cinput type=\"text\" name=\"username\" value=\"{{ old('username') }}\"\u003e\n\n// If the user previously entered 'john_doe' and the form was submitted with errors,\n// the input field will be repopulated with 'john_doe' after the validation failure.\n```\n\n### fake()\nThe `fake()` function is a helper designed to create and return an instance of the Faker generator, which is used to generate fake data. This can be particularly useful for seeding a database with random data, testing, or generating sample data for development purposes.\n```php\n$faker = fake();\n$name = $faker-\u003ename;\n$email = $faker-\u003eemail;\n```\n### route()\nThe `route()` function is a helper used to generate a full URL for a named route. It allows you to easily create links to specific routes in your application based on their name and any parameters they might require.\n```php\n$url = route('route.name', ['parameter1' =\u003e 'value1']);\n```\nThis will return the full URL for the named route route.name, replacing any required parameters with the provided values.\n#### Example\n```php\n// If you have a route named 'file' with a parameter 'id' in your routes file:\nRoute::get('/file/1', [FileController::class, 'index'])-\u003ename('file');\n$url = route('file',1);\n// The result might be something like 'http://example.com/file/1'\n```\n\n### config()\nThe `config()` function is a helper used to retrieve configuration values by key. It allows you to access values from the configuration files in your application, providing a centralized way to manage various settings.\n```php\n$value = config('app.name');\n```\nThis retrieves the value associated with the `app.name` configuration key.\n#### Example\nIf you have a configuration file `config/app.php` with the following content:\n```php\nreturn [\n    'name' =\u003e 'My Application',\n    'env' =\u003e 'local',\n    'timezone' =\u003e 'UTC',\n];\n```\nYou can retrieve the value like this:\n```php\n$timezone = config('app.timezone', 'America/New_York'); // 'UTC'\n```\nIf the key doesn’t exist, and you provide a default value:\n\n### is_auth()\nThe `is_auth()` function is a helper used to check if a user is authenticated (i.e., logged in). It allows you to easily determine whether the current user has been authenticated through the application's authentication system.\n```php\nif (is_auth()) {\n    // The user is logged in\n} else {\n    // The user is not logged in\n}\n```\n### base_path()\nThe `base_path()` function is a helper used to retrieve the base path of the application, with an optional path appended to it. It provides an easy way to get the root directory of your application, and optionally append additional subdirectories or files to the base path.\n```php\n// Get the base path of the application\n$basePath = base_path(); // /var/www/html/doppar\n\n// Get the base path with a specific subdirectory or file\n$fullPath = base_path('storage/logs'); // /var/www/html/doppar/storage/logs\n```\n### base_url()\nThe `base_url()` function is a helper that retrieves the base URL of the application, with an optional path appended to it. This function is used to generate the full URL to your application, considering both the environment (e.g., local development, production) and any given subpath.\n```php\n// Get the base URL of the application\n$baseUrl = base_url();\n\n// Get the full URL with a specific path\n$fullUrl = base_url('images/logo.png'); // http://example.com/images/logo.png\n```\n\n### storage_path()\nThe `storage_path()` function is a helper that retrieves the storage path of the application, with an optional path appended to it. This function is used to generate the full path to the storage directory of your application, allowing you to easily access or store files in a consistent manner.\n```php\n// Get the base storage path\n$storagePath = storage_path();\n\n// Get the full storage path with a specific subdirectory or file\n$fullPath = storage_path('uploads/images/logo.png');\n```\n\n### public_path()\nThe `public_path()` function is a helper that retrieves the public path of the application, with the option to append a specific path to it. This function is useful for determining the full path to the public directory of your application, enabling easier access to publicly accessible resources, such as assets, uploaded files, and other public files.\n```php\n// Get the base public path\n$publicPath = public_path();\n\n// Get the full public path with a specific subdirectory or file\n$fullPath = public_path('images/logo.png');\n```\n\n### resource_path()\nThe `resource_path()` function is a helper that retrieves the application's resource path, with an optional ability to append a specific subdirectory or file path. This function is particularly useful when dealing with application resources such as views, language files, and configuration files that are stored in the resources directory.\n```php\n// Get the base resources path\n$resourcesPath = resource_path();\n\n// Get the full resources path with a specific subdirectory or file\n$fullPath = resource_path('views/layouts/app.blade.php');\n```\n\n### config_path()\nThe `config_path()` function is a helper that retrieves the configuration path of the application, with an optional path appended to it. This function is used to generate the full path to the configuration directory of your application, allowing you to easily access or store configuration files in a consistent manner.\n```php\n// Get the base config path\n$configPath = config_path();\n\n// Get the full config path with a specific subdirectory or file\n$fullPath = config_path('app.php');\n```\n\n### database_path()\nThe `database_path()` function is a helper designed to retrieve the application's database path, with the ability to append a specific subdirectory or file path if necessary. This function is particularly useful for accessing the database configuration, migration files, and other database-related files that are stored within the database directory.\n```php\n// Get the base database path\n$databasePath = database_path();\n\n// Get the full database path with a specific subdirectory or file\n$fullPath = database_path('migrations/');\n```\n### enqueue()\nThe `enqueue()` function is a helper designed to generate the URL for assets (such as CSS, JavaScript, images, etc.) located in the public directory of the application. This function allows you to generate a full URL for assets, either with or without a secure (HTTPS) scheme, depending on the provided parameters.\n```php\n// Generate the URL for a public asset (e.g., CSS, JS, image)\n$assetUrl = enqueue('assets/css/styles.css');\n\n// Generate the URL for a public asset with a secure (HTTPS) scheme\n$secureAssetUrl = enqueue('assets/js/app.js', true);\n```\nGenerating a Secure (HTTPS) URL for a JavaScript File: If you want to load a JavaScript file over HTTPS:\n```php\n$jsUrl = enqueue('assets/js/app.js', true);\n```\n\n### abort()\nThe `abort()` function is a helper that allows you to immediately stop the current request and return an HTTP response with a specific status code and an optional message. This is particularly useful for handling error scenarios or preventing further processing when a certain condition is met.\n```php\n// Abort with a 404 Not Found status and an optional message\nabort(404, 'Page not found');\n\n// Abort with a 500 Internal Server Error status and a custom message\nabort(500, 'Something went wrong on the server');\n```\n### abort_if()\nThe `abort_if()` function is a helper designed to automatically abort the request and send a specific HTTP status code with an optional message when a condition is true. It provides a shorthand way to handle conditional error situations and terminate the request early if a specific condition is met.\n```php\n// Abort the request if a condition is true\nabort_if($userNotAuthenticated, 401, 'Unauthorized access');\n\n// Abort the request if a file does not exist\nabort_if(!file_exists($filePath), 404, 'File not found');\n```\n## String Helper function\nDoppar provides a collection of global string helper functions in PHP. While many of these functions are integral to the framework’s internal operations, they are also available for use in your own projects whenever they prove usefull. All the string function, you can access it via global `str()` function or you can use `Phaseolies\\Support\\Facades\\Str` facades\n\n### mask()\nThe `mask()` function is a helper designed to mask parts of a given string while keeping a specified number of characters visible at the start and the end. This can be useful for hiding sensitive information (like credit card numbers, emails, or phone numbers) while displaying a portion of it for the user to verify.\n```php\nuse Phaseolies\\Support\\Facades\\Str;\n\n// Mask a credit card number except for the last four digits\n$maskedCard = str()-\u003emask('1234 5678 9876 5432', 4, 4, '*');\n$maskedCard = Str::mask('1234 5678 9876 5432', 4, 4, '*');\n\n// Mask a phone number except for the first three and last four digits\n$maskedPhone = str()-\u003emask('123-456-7890', 3, 4, '#');\n$maskedPhone = Str::mask('123-456-7890', 3, 4, '#');\n```\n### Example\nMasking Credit Card Numbers: To display only the last 4 digits of a credit card number for security reasons, you can use the mask() function:\n```php\n$maskedCard = str()-\u003emask('1234 5678 9876 5432', 4, 4); // Output: 1234 ******** 5432\n```\nMasking Phone Numbers: For masking a phone number except for the first 3 and last 4 digits:\n```php\n$maskedPhone = str()-\u003emask('123-456-7890', 3, 4, '#'); // Output: 123-###-7890\n```\nMasking Email Addresses: To hide part of an email address except for the first and last characters:\n```php\n$maskedEmail = str()-\u003emask('john.doe@example.com', 1, 1); // Output: j********e.com\n```\n\n### truncate()\nThe `truncate()` function is a helper designed to truncate a string to a specified maximum length. If the string exceeds this length, it appends a suffix (such as ellipsis ...) to indicate that the string has been shortened.\n```php\n$shortDescription = str()-\u003etruncate('This is a long description that should be shortened for previews.', 30, '... Read More');\n$shortDescription = Str::truncate('This is a long description that should be shortened for previews.', 30, '... Read More');\n// Output: \"This is a long description... Read More\"\n```\n### snake()\nThe `snake()` function is a helper designed to convert a camelCase string into a snake_case string. This is useful when you need to transform variable names, keys, or identifiers from camelCase (often used in programming) into snake_case (commonly used in database column names or URL routing).\n```php\n// Convert a camelCase string to snake_case\n$snakeString = str()-\u003esnake('camelCaseString'); // Output: 'camel_case_string'\n```\n### camel()\nThe `camel()` function is a helper designed to convert a snake_case string into a camelCase string. This is useful when you need to transform variable names, keys, or identifiers from snake_case (commonly used in databases or file names) into camelCase (often used in programming languages like JavaScript and PHP for variable names).\n```php\n// Convert a snake_case string to camelCase\n$camelString = str()-\u003ecamel('snake_case_string'); // Output: 'snakeCaseString'\n```\n\n### random()\nThe `random()` function is a helper designed to generate a random alphanumeric string of a specified length. This is useful when you need to generate secure random tokens, passwords, or unique identifiers.\n```php\n// Generate a random alphanumeric string of default length 16\n$randomString = str()-\u003erandom(); // Output: 'a1B2c3D4e5F6g7H8'\n\n// Generate a random alphanumeric string of a custom length (e.g., 8)\n$randomString = str()-\u003erandom(8); // Output: 'Xy7GzH8Q'\n```\n### isPalindrome()\nThe `isPalindrome()` function is a helper designed to check whether a given string is a palindrome. A palindrome is a word, phrase, or sequence that reads the same backward as forward (ignoring spaces, punctuation, and capitalization).\n```php\n// Check if a string is a palindrome\n$isPalindrome = str()-\u003eisPalindrome('racecar'); // Output: true\n\n// Check if a string is not a palindrome\n$isPalindrome = str()-\u003eisPalindrome('hello'); // Output: false\n```\n### countWord()\nThe `countWord()` function is a helper designed to count the number of words in a given string. This is useful when you need to determine the word count of a sentence, paragraph, or any text input.\n```php\n// Count the number of words in a string\n$wordCount = str()-\u003ecountWord('This is a test sentence.'); // Output: 5\n\n// Count the number of words in a string with punctuation\n$wordCount = str()-\u003ecountWord('Hello, world!'); // Output: 2\n```\n### Log Helpers\nThese are helper functions designed to simplify logging at different levels of severity. They utilize Doppar's built-in Log facade to log messages with various log levels. Each function accepts a payload (which can be any type of data) and logs it accordingly at the specified level.\n```php\n// Log an informational message\ninfo('This is an info message.'); // Logs an info-level message\n\n// Log a warning message\nwarning('This is a warning message.'); // Logs a warning-level message\n\n// Log an error message\nerror('This is an error message.'); // Logs an error-level message\n\n// Log an alert message\nalert('This is an alert message.'); // Logs an alert-level message\n\n// Log a notice message\nnotice('This is a notice message.'); // Logs a notice-level message\n\n// Log an emergency message\nemergency('This is an emergency message.'); // Logs an emergency-level message\n\n// Log a critical message\ncritical('This is a critical message.'); // Logs a critical-level message\n\n// Log a debug message\ndebug('This is a debug message.'); // Logs a debug-level message\n```\n### collect()\nThe `collect()` function is a helper designed to create a new instance of a Doppar Collection. It simplifies the process of creating and working with collections in your application. Collections allow you to work with arrays in a more expressive and fluent way, providing additional methods for filtering, transforming, and manipulating data.\n```php\n// Create a new collection with an array of items\n$collection = collect([1, 2, 3, 4]); // Returns a Collection instance containing [1, 2, 3, 4]\n\n// Create an empty collection\n$emptyCollection = collect(); // Returns an empty Collection instance\n```\n### Example Usage\nSee some basic example of collection, how you can use it\n\n### filter()\nThe `filter()` method allows you to filter a collection based on a given condition.\n\n```php\n$collection = collect([1, 2, 3, 4, 5, 6]);\n\n// Filter to get only even numbers\n$evenNumbers = $collection-\u003efilter(function ($value) {\n    return $value % 2 === 0;\n});\n\nreturn $evenNumbers; // [2,4,6]\n```\n### map()\nThe map() method allows you to transform each item in the collection using a callback function.\n```php\n$collection = collect([1, 2, 3, 4]);\n\n// Multiply each number by 2\n$doubledNumbers = $collection-\u003emap(function ($value) {\n    return $value * 2;\n});\n\nreturn $doubledNumbers;\n```\n### first()\nThe first() method retrieves the first item in the collection.\n```php\n// Create a collection of numbers\n$collection = collect([10, 20, 30, 40]);\n\n// Get the first item\n$firstItem = $collection-\u003efirst();\n\necho $firstItem; // Output: 10\n```\n\n### delete_folder_recursively()\nThe `delete_folder_recursively()` function is a helper designed to delete a folder and all its contents, including subfolders and files. It performs a recursive deletion, ensuring that every file and folder inside the target folder is deleted before the folder itself is removed.\n```php\n// Delete a folder and its contents recursively\n$result = delete_folder_recursively('/path/to/folder'); // Returns true on success, false on failure\n```\n### title()\nThe `title()` function is a helper designed to convert a given string into title case, where the first letter of each word is capitalized, and the rest of the letters are in lowercase. This is commonly used for formatting titles or headings.\n```php\n// Convert a string to title case\n$title = str()-\u003etitle(\"hello world\"); // Returns \"Hello World\"\n```\n\n### slug()\nThe `slug()` function is a helper designed to generate a URL-friendly slug from a given string. A slug is typically used in URLs, where spaces and special characters are replaced with hyphens (or another separator), and all letters are converted to lowercase.\n```php\n// Generate a URL-friendly slug\n$slug = str()-\u003eslug(\"Hello World!\"); // Returns \"hello-world\"\n```\n\nThe word separator used in the slug. By default, this is a hyphen (-), but you can specify another separator if needed.\n```php\n// Generate a URL-friendly slug with the default separator (hyphen)\n$slug = str()-\u003eslug(\"Hello World!\"); // Returns \"hello-world\"\n\n// Generate a URL-friendly slug with a custom separator (underscore)\n$slug = str()-\u003eslug(\"Hello World!\", '_'); // Returns \"hello_world\"\n```\n\n### contains()\nThe `contains()` function is a helper designed to check if a given string (the haystack) contains another string (the needle), performing a case-insensitive search.\n```php\n// Check if a string contains another string (case-insensitive)\n$contains = str()-\u003econtains(\"Hello World\", \"world\"); // Returns true\n```\n### limitWords()\nThe `limitWords()` function is a helper designed to limit the number of words in a string. If the string contains more words than the specified limit, the function truncates the string and appends an optional ending suffix (such as ...).\n```php\n// Limit the number of words in a string\n$truncatedString = str()-\u003elimitWords(\"This is a test string\", 3); // Returns \"This is a...\"\n```\n\nThe function returns the truncated string with a specified number of words and the optional suffix. If the string has fewer words than the specified limit, it remains unchanged.\n```php\n// Limit the number of words to 3, append \"...\"\n$truncatedString = str()-\u003elimitWords(\"This is a test string\", 3); // Returns \"This is a...\"\n\n// Limit the number of words to 2, append custom suffix\n$truncatedString = str()-\u003elimitWords(\"Hello there, how are you?\", 2, '...more'); // Returns \"Hello there...more\"\n```\n\n### removeWhiteSpace()\nThe `removeWhiteSpace()` function is a helper designed to remove all whitespace characters (spaces, tabs, newlines, etc.) from a given string. This is useful when you need to clean up strings for processing or formatting purposes\n```php\n// Remove spaces from a string\n$cleanedString = str()-\u003eremoveWhiteSpace(\"Hello   World\"); // Returns \"HelloWorld\"\n\n// Remove all whitespace including tabs and newlines\n$cleanedString = str()-\u003eremoveWhiteSpace(\"Hello \\tWorld\\n\"); // Returns \"HelloWorld\"\n```\n\n### uuid()\nThe `uuid()` function is a helper designed to generate a UUID v4 (Universally Unique Identifier), which is a random 128-bit value represented as a string. UUIDs are commonly used for generating unique identifiers in distributed systems, databases, and APIs.\n```php\n// Generate a UUID v4 string\n$uuid = str()-\u003euuid();\n// or\n$uuid = uuid(); // Returns something like \"f47ac10b-58cc-4372-a567-0e02b2c3d479\"\n```\n\n## startsWith()\nThe `startsWith()` function is a helper designed to check if a given string (the haystack) starts with another string (the needle). This check is case-sensitive.\n```php\n// Check if a string starts with a specific substring\n$startsWith = str()-\u003estartsWith(\"Hello World\", \"Hello\"); // Returns true\n$startsWith = str()-\u003estartsWith(\"Hello World\", \"world\"); // Returns false (case-sensitive)\n```\n\n### endsWith()\nThe `endsWith()` function is a helper designed to check if a given string (the haystack) ends with another string (the needle). This check is case-sensitive.\n```php\n// Check if a string ends with a specific substring\n$endsWith = str()-\u003eendsWith(\"Hello World\", \"World\"); // Returns true\n$endsWith = str()-\u003eendsWith(\"Hello World\", \"world\"); // Returns false (case-sensitive)\n```\n\n### studly()\nThe `studly()` function is a helper designed to convert a given string into StudlyCase (also known as PascalCase), where the first letter of each word is capitalized, and there are no spaces or underscores between words.\n```php\n// Convert a snake_case string to StudlyCase\n$studlyString = studly(\"hello_world\"); // Returns \"HelloWorld\"\n\n// Convert a more complex string to StudlyCase\n$studlyString = studly(\"convert_this_string_to_studly_case\"); // Returns \"ConvertThisStringToStudlyCase\"\n```\n\n### everse()\nThe reverse() function is a helper designed to reverse the characters in a given string while correctly handling multi-byte characters (such as characters in non-Latin alphabets or special symbols). This ensures that characters are reversed properly, without corrupting multi-byte sequences.\n```php\n// Reverse a regular string\n$reversedString = reverse(\"Hello World\"); // Returns \"dlroW olleH\"\n```\n\n### extractNumbers()\nThe `extractNumbers()` function is a helper designed to extract all numeric digits from a given string. It removes any non-numeric characters, leaving only the digits.\n```php\n// Extract digits from a string containing letters and symbols\n$numbers = str()-\u003eextractNumbers(\"Hello 123, World 456!\"); // Returns \"123456\"\n\n// Extract digits from a string with mixed content\n$numbers = str()-\u003eextractNumbers(\"Price: $123.45, Discount: 10%\"); // Returns \"1234510\"\n```\n\n### longestCommonSubstring()\nThe `longestCommonSubstring()` function is a helper designed to find the longest common substring shared between two given strings. A common substring is a contiguous sequence of characters that appears in both strings.\n```php\n// Example with overlapping words\n$commonSubstring = str()-\u003elongestCommonSubstring(\"hello world\", \"yellow world\"); // Returns \"llo world\"\n\n// Example with no common substring\n$commonSubstring = str()-\u003elongestCommonSubstring(\"abcdef\", \"xyz\"); // Returns \"\"\n\n// Example with a single common character\n$commonSubstring = str()-\u003elongestCommonSubstring(\"banana\", \"bandana\"); // Returns \"bana\"\n```\n\n### leetSpeak()\nThe `leetSpeak()` function is a helper designed to convert a given string into leetspeak (1337), a playful encoding style where certain letters are replaced with similar-looking numbers or symbols.\n```php\n// Convert a simple phrase\n$leetString = str()-\u003eleetSpeak(\"leet speak\"); // Possible output: \"l33t sp34k\"\n\n// Convert a more complex phrase\n$leetString = str()-\u003eleetSpeak(\"programming is fun\"); // Possible output: \"pr0gr4mm1ng 15 fun\"\n```\n\nCommon Leetspeak Replacements:\n```\nA -\u003e 4   B -\u003e 8   C -\u003e (   E -\u003e 3   G -\u003e 6   H -\u003e #\nI -\u003e 1   L -\u003e 1   O -\u003e 0   S -\u003e 5   T -\u003e 7   Z -\u003e 2\n```\nThis function is great for fun text transformations, gaming usernames, or encoding messages in a way that is still somewhat readable.\n\n### extractEmails()\nThe `extractEmails()` function is a helper designed to extract all email addresses from a given string. It scans the string for valid email formats and returns them as an array.\n```php\n// Extract email addresses from a string\n$emails = str()-\u003eextractEmails(\"Contact us at support@example.com or sales@example.org\");\n// Returns: [\"support@example.com\", \"sales@example.org\"]\n```\n\n### highlightKeyword()\nThe `highlightKeyword()` function is a helper designed to highlight all occurrences of a specified keyword in a given string using HTML tags. This is useful for emphasizing search results, user input matches, or key terms in displayed content.\n```php\n// Default behavior with \u003cstrong\u003e tag\n$text = \"Doppar is awesome. Learn Doppar now!\";\n$highlighted = str()-\u003ehighlightKeyword($text, \"Doppar\"); \n// Returns: \"\u003cstrong\u003eDoppar\u003c/strong\u003e is awesome. Learn \u003cstrong\u003eDoppar\u003c/strong\u003e now!\"\n\n// Using a \u003cspan\u003e tag for custom styling\n$highlighted = str()-\u003ehighlightKeyword($text, \"Doppar\", \"span class='highlight'\"); \n// Returns: \"\u003cspan class='highlight'\u003eDoppar\u003c/span\u003e is awesome. Learn \u003cspan class='highlight'\u003eDoppar\u003c/span\u003e now!\"\n```\n\n\u003ca name=\"section-55\"\u003e\u003c/a\u003e\n\n## Localization\nDoppar provides multiple ways to handle localization in your application. You can set, retrieve, and translate language strings efficiently using various helpers and facades. Language files located in your root `lang` directory\n\n### Setting the Locale\nTo change the application's active language, use:\n```php\nuse Phaseolies\\Support\\Facades\\App;\n\nApp::setLocale('en');\n```\n\n### Example\nSet language based on user preference\n```php\nif ($user-\u003elanguage === 'es') {\n    App::setLocale('es');\n} else {\n    App::setLocale('en');\n}\n```\n\n### Get the Current local\nTo retrieve the currently set language:\n```php\nuse Phaseolies\\Support\\Facades\\App;\n\n$currentLang = App::getLocale()\n```\n\n### Fetching Translations\nAssume we have a language file inside `lang/en/messages.php` and that conatins this.\n```php\n\u003c?php\n\nreturn [\n    'welcome' =\u003e 'Thank you for choosing Doppar :version. Build something amazing',\n];\n```\n\nNow you can retrieve translations using multiple approaches:\n#### Using the lang() Helper\n```php\nlang()-\u003eget('messages.welcome', ['version' =\u003e Application::VERSION]);\n// or\nlang()-\u003etrans('messages.welcome', ['version' =\u003e Application::VERSION]);\n```\n\n#### Using the Lang Facade\n```php\nuse Phaseolies\\Supports\\Facades\\Lang;\n\n$message = Lang::trans('messages.welcome', ['version' =\u003e Application::VERSION]);\n```\n\n### Using the trans() Helper\n```php\n$message = trans('messages.welcome', ['version' =\u003e Application::VERSION]);\n```\n\n\u003ca name=\"section-57\"\u003e\u003c/a\u003e\n\n## Doppar Framework – Package Development Guide\nWelcome to the official Doppar Framework Package Development Guide! This document walks you through the full lifecycle of creating, structuring, and maintaining packages within the Doppar PHP ecosystem.\n\nWhether you're building internal modules or reusable packages for others, this guide helps you create clean, organized, and pluggable components for your Doppar applications.\n\n### Overview\nIn Doppar, a package is a self-contained module that can include:\n- Configuration files\n- Routes\n- Views\n- Migrations\n- Commands\n- Service classes\n\nPackages are registered via Service Providers and integrated seamlessly into your application.\n\n### Creating a New Package\nStart by creating a directory structure similar to this:\n```markdown\npackages/\n└── VendorName/\n    └── PackageName/\n        ├── config/\n        │   └── packagename.php\n        ├── routes/\n        │   └── web.php\n        ├── views/\n        │   └── (Blade files)\n        ├── database/\n        │   └── migrations/\n        ├── src/\n        │   └── PackageServiceProvider.php\n        └── composer.json\n```\nKeep all business logic under a `src/` folder for cleaner autoloading and separation of concerns.\n\n### Building the Service Provider\nThe Service Provider is the heart of your package. It connects your package to the Doppar framework.\n```php\n\nnamespace Vendor\\PackageName;\n\nuse Phaseolies\\Providers\\ServiceProvider;\n\nclass PackageServiceProvider extends ServiceProvider\n{\n    public function register()\n    {\n        //\n    }\n\n    public function boot()\n    {\n       //\n    }\n}\n```\n\n### Register Service Provider\nTo integrate your package into a Doppar application, you need to register your package's service provider. The service provider is the entry point that tells Doppar how to load your package's components such as routes, views, config, and migrations.\n\nOpen your application's configuration file `config/app.php` and add your service provider with the `providers` array\n```php\n'providers' =\u003e [\n    // Other service providers...\n    Vendor\\PackageName\\PackageServiceProvider::class,\n],\n```\nReplace `Vendor\\PackageName\\PackageServiceProvider` with the actual namespace and class name of your service provider.\n\n### Configuration Files\nPlace default configuration in `config/packagename.php`. To allow users to customize, publish it via:\n```php\npublic function register()\n{\n    $this-\u003emergeConfig(__DIR__.'/config/packagename.php', 'packagename'); // merging config\n}\n```\n\nNow you can echo your package config name like\n```php\necho config('packagename.key', 'default')\n```\n\nYou can publish configuration file by running this command\n```php\nphp pool vendor:publish --tag=config\n```\n\n### Routing\nPut your package routes in `routes/web.php`. Load them with:\n```php\npublic function boot()\n{\n    $this-\u003eloadRoutes(__DIR__ . '/routes/web.php'); // loading routes\n}\n```\nUse route groups and prefixes to avoid conflicts.\n\n### Views\nStore your Blade templates in `views/` and reference them with a `namespace` packagename:\n```php\npublic function boot()\n{\n    $this-\u003eloadViews(__DIR__ . '/views', 'packagename'); // loading views and packagename is the namespace\n\n    $this-\u003epublishes([\n        __DIR__ . '/views' =\u003e resource_path('views/vendor/packagename'),\n    ]);\n}\n```\n\nNow you can allow doppar to load your views using `namespace` like this\n```php\nview('packagename::welcome');\n```\nAllow users to override by publishing them to:\n```php\n// php pool vendor:publish --tag=views\nresources/views/vendor/packagename\n```\n\n### Migrations\nInclude database migrations in `database/migrations`. They will auto-load on boot, but can also be published and customized by users.\n```php\npublic function boot()\n{\n    $this-\u003eloadMigrations(__DIR__ . '/database/migrations');\n\n    $this-\u003epublishes([\n        __DIR__ . '/database/migrations' =\u003e database_path('migrations'),\n    ]);\n}\n```\n```php\nphp pool vendor:publish --tag=migrations\nphp pool migrate\n```\n\nYou can override vendor publish file by adding `--force`\n```php\nphp pool vendor:publish --force // override existing files\n```\n\n### Publishing Your Package\nIf you want to share your package, Add a proper `composer.json` with psr-4 autoloading:\n```php\n\"autoload\": {\n    \"psr-4\": {\n        \"Vendor\\\\PackageName\\\\\": \"src/\"\n    }\n}\n```\nPush it to GitHub or publish to Packagist and Install via Composer:\n```bash\ncomposer require vendor/packagename\n```\n\nCreating packages in Doppar is all about clean separation, reusability, and plug-and-play integration. Whether you're building UI components, authentication systems, or developer tools, this guide helps you build consistent and scalable packages.\n\n\u003ca name=\"flarion\"\u003e\u003c/a\u003e\n\n## Doppar Flarion\nFlarion provides a lightweight API authentication system for the Doppar framework.\n\nFlarion allows each user of Doppar application to generate and manage multiple API tokens. These tokens are stateless and designed for use in mobile apps, third-party clients, or any frontend that communicates via a simple token-based API.\n\nEach token can be assigned specific abilities, defining what the token is allowed to do within the system. This makes it easy to implement fine-grained access control across your API routes, without relying on cookies or session state — fully aligned with Doppar's stateless architecture.\n\n### How it Works\nDoppar Flarion exists to solve one problems. Let's discuss it before digging deeper into the library.\n\n### API Tokens\nFlarion is a lightweight authentication package for the Doppar framework that allows you to issue API tokens to your users without the complexity of OAuth. This functionality is inspired by platforms like GitHub, where users can generate personal access tokens from their account settings. For example, your Doppar application might have a settings page where users can create API tokens to integrate with external services or automate workflows.\n\nFlarion handles the generation, storage, and management of these tokens. Tokens are stored in a dedicated database table and can be assigned specific abilities (scopes) to control access. They typically have a long lifespan (often lasting for years), but users can delete them at any time for security.\n\nIncoming HTTP requests are authenticated by checking the Authorization header for a valid token. If the token exists and is valid, Flarion will resolve the corresponding user and authorize the request accordingly — all in a stateless, token-based manner ideal for API-first applications.\n\n### Installation\nYou may install Doppar Flarion via the `composer require` command:\n```bash\ncomposer require doppar/flarion\n```\n\n### Publish Configuration\nNow we need to publish the configuration files by running this pool command\n```bash\nphp pool vendor:publish --provider=\"Phaseolies\\Flarion\\FlarionServiceProvider\"\n```\n\nNow run migrate command to migrate `personal_access_token` table\n```bash\nphp pool migrate\n```\n\n### Register Provider\nNext, register the Flarion service provider so that Doppar can initialize it properly. Open your `config/app.php` file and add the `FlarionServiceProvider` to the providers array:\n```\n'providers' =\u003e [\n    // Other service providers...\n    Flarion\\FlarionServiceProvider::class,\n],\n```\nThis step ensures that Doppar knows about Flarion and can load its functionality when the application boots.\n\n### API Token Authentication\nFlarion allows you to issue API tokens / personal access tokens that may be used to authenticate API requests to your application. When making requests using API tokens, the token should be included in the Authorization header as a `Bearer token`.\n\nTo begin issuing tokens for users, your User model should use the `Doppar\\Flarion\\Tokenable` trait:\n```php\n\u003c?php\n\nnamespace App\\Models;\n\nuse Phaseolies\\Database\\Eloquent\\Model;\nuse Doppar\\Flarion\\Tokenable;\n\nclass User extends Model\n{\n    use Tokenable;\n}\n\nTo issue a token, you may use the `createToken` method. The `createToken` method returns a Doppar\\Flarion\\NewAccessToken instance. \n```php\nuse Phaseolies\\Http\\Request;\n\nRoute::post('create/token', function (Request $request) {\n    $token = $request-\u003euser()-\u003ecreateToken($request-\u003etoken_name);\n\n    return ['token' =\u003e $token-\u003eplainTextToken];\n});\n```\n\nYou may access all of the user's tokens using the tokens Eloquent relationship provided by the HasApiTokens trait:\n```php\nforeach ($user-\u003etokens as $token) {\n    // ...\n}\n```\n\n### Token Abilities\nFlarion allows you to assign \"abilities\" to tokens. Abilities serve a similar purpose as OAuth's \"scopes\". You may pass an array of string `abilities` as the third argument to the `createToken` method:\n```php\nreturn $user-\u003ecreateToken('token-name', null, ['post-update'])-\u003eplainTextToken;\n```\n\nWhen handling an incoming request authenticated by Flarion, you may determine if the token has a given ability using the middleware and `tokenCan` method:\n```php\nRoute::post('token_scope', [PostController::class, 'update'])\n    -\u003emiddleware('auth-api:post-update');\n```\n\nOr you can did the same job like\n```php\nif ($user-\u003etokenCan('post-update')) {\n    // ...\n}\n```\n\n### Check Multiple Abilities\nYou can also check for multiple abilities by joining them with an ampersand (\u0026). The token must have all listed abilities to pass the check:\n```php\nRoute::post('token_scope', [PostController::class, 'update'])\n    -\u003emiddleware('auth-api:post-update\u0026post-another');\n```\nEach ability must exactly match one of the abilities assigned to the token. If any of the specified abilities are missing from the token, the request will be rejected with a `unauthorized` response.\n\n### Protecting Routes\nTo ensure that all incoming API requests are authenticated, you should apply the Flarion authentication guard to any protected routes in your application — typically inside your `routes/api.php` file.\n\nFlarion handles stateless authentication using API tokens, so every request must include a valid token in the Authorization header. This makes it perfect for mobile apps, external clients, or any token-driven access.\n```php\nuse Phaseolies\\Http\\Request;\n\nRoute::get('/user', function (Request $request) {\n    return $request-\u003euser();\n})-\u003emiddleware('auth-api');\n```\n\n### Revoking Tokens\nYou may \"revoke\" tokens by deleting them from your database using the tokens relationship that is provided by the `Doppar\\Flarion\\Tokenable` trait:\n```php\n// Revoke all tokens...\n$user-\u003etokens()-\u003edelete();\n\n// Revoke the token that was used to authenticate the current request...\n$request-\u003euser()-\u003etokens()-\u003ewhere('token', '=', $tokenId)-\u003edelete();\n$request-\u003euser()-\u003ecurrentAccessToken()-\u003edelete();\n\n// Revoke a specific token...\n$user-\u003etokens()-\u003ewhere('id', '=', $tokenId)-\u003edelete();\n```\n\n### Token Expiration\nBy default, Flarion tokens never expire and may only be invalidated by revoking the token. However, if you would like to configure an expiration time for your application's API tokens, you may do so via the expiration configuration option defined in your application's `flarion` configuration file. This configuration option defines the number of minutes until an issued token will be considered expired:\n```php\n'expiration' =\u003e 5,\n```\nIf you would like to specify the expiration time of each token independently, you may do so by providing the expiration time as the second argument to the `createToken` method:\n\n```php\nreturn $user-\u003ecreateToken('token-name',  now()-\u003eaddMinutes(5))-\u003eplainTextToken;\n```","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdoppar%2Fdoppar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdoppar%2Fdoppar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdoppar%2Fdoppar/lists"}