{"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","funding_links":[],"categories":[],"sub_categories":[],"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, $head","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"}