{"id":26645920,"url":"https://github.com/pocketframe/docs","last_synced_at":"2025-03-24T22:46:44.715Z","repository":{"id":284224718,"uuid":"954239001","full_name":"Pocketframe/docs","owner":"Pocketframe","description":null,"archived":false,"fork":false,"pushed_at":"2025-03-24T19:49:17.000Z","size":17,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-24T20:29:24.253Z","etag":null,"topics":["framework","php","php-framework","pocketframe"],"latest_commit_sha":null,"homepage":"https://pocketframe.github.io/docs/","language":"CSS","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Pocketframe.png","metadata":{"files":{"readme":"README.md","changelog":null,"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}},"created_at":"2025-03-24T19:17:10.000Z","updated_at":"2025-03-24T20:01:47.000Z","dependencies_parsed_at":"2025-03-24T20:40:26.948Z","dependency_job_id":null,"html_url":"https://github.com/Pocketframe/docs","commit_stats":null,"previous_names":["pocketframe/docs"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Pocketframe%2Fdocs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Pocketframe%2Fdocs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Pocketframe%2Fdocs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Pocketframe%2Fdocs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Pocketframe","download_url":"https://codeload.github.com/Pocketframe/docs/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245366201,"owners_count":20603439,"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","php-framework","pocketframe"],"created_at":"2025-03-24T22:46:43.897Z","updated_at":"2025-03-24T22:46:44.692Z","avatar_url":"https://github.com/Pocketframe.png","language":"CSS","readme":"# Pocketframe Documentation\n\n### Table of Contents\n\n- [Introduction](#introduction)\n- [Getting Started](#getting-started)\n- [Installation](#installation)\n- [Configuration](#configuration)\n- [Core Concepts](#core-concepts)\n- [Service Container](#service-container)\n- [Routing](#routing)\n- [Middleware](#middleware)\n- [Controllers](#controllers)\n- [CSRF Protection](#csrf-protection)\n- [Requests](#requests)\n- [Responses](#responses)\n- [Database](#database)\n- [Error Handling](#error-handling)\n- [Logging](#logging)\n- [Views](#views)\n- [Pocket View Templating](#pocket-views)\n- [Session](#session)\n- [Validation](#validation)\n- [CLI](#cli)\n\u003c!-- - [Advanced Topics](#advanced-topics) --\u003e\n\u003c!-- - [Custom Middleware](#custom-middleware) --\u003e\n- [Helper Functions](#helper-functions)\n- [Contributing](#contributing)\n\n---\n\n## Getting Started\n\nPocketframe is a lightweight yet powerful PHP framework designed to simplify modern web application development. With its intuitive structure, elegant syntax, and modular approach, Pocketframe helps developers build scalable, high-performance applications effortlessly.\n\nThis section will help you get up and running with your first Pocketframe application.\n\n### Prerequisites\n\nBefore you begin, ensure you have:\n- PHP 8.1 or higher installed\n- Composer package manager\n- Basic understanding of PHP and MVC patterns\n\n\n### Installation\n\nTo install Pocketframe, you need to have PHP and Composer installed on your system.\n\nTo create a new Pocketframe project, run the following command in your terminal:\n\n```bash\ncomposer create-project pocketframe/application demo-app --stability dev\n```\n\n### Set Up Environment:\n\nCopy the `.env.example` to `.env` and configure your environment variables.\n\nAfter adding you .env file, you can use the following command to generate an encryption key for your application:\n\n```bash\nphp pocket add:key\n```\n\n\n### Run Your Server\n\nTo start the development server, run the following command:\n\n```bash\nphp pocket serve\n```\n\n## Configuration\n\nPocketframe uses a configuration directory to manage settings.\n\n### Key configuration files include:\n- `config/app.php`: Application settings.\n- `config/database.php`: Database connection settings.\n- `config/middleware.php`: Middleware configuration.\n\n## Core Concepts\n\n### Service Container\nThe service container is a powerful tool for managing class dependencies and performing dependency injection (DI). It is used to bind and resolve classes throughout the application.\n\n```php\n$container-\u003ebind(Database::class, function () {\n  $config = require config_path('database');\n  return new Database($config['database']);\n});\n```\n\n## Routing\nRouting in Pocketframe is managed by the Router class. Routes are defined in routes/web.php and routes/api.php.\n\nThe Router class is responsible for handling HTTP requests and dispatching them to the appropriate controller action.\n\n```php\n$router-\u003eget('/', ['HomeController', 'index'], name: 'home.index');\n```\n\u003e [!NOTE]\n\u003e The first parameter of the get method is the route **path**, the second parameter is an array containing the **controller** and **action**, and the third parameter is the **name** of the route.\n\nYou can also define middleware for routes using route groups.\n```php\n$router-\u003egroup(['middleware' =\u003e 'auth'], function ($router) {\n  $router-\u003eget('/dashboard', ['DashboardController', 'index'], name: 'dashboard.index');\n});\n  ```\n\nIf you want to define prefix routes, you can use the group method.\n\n```php\n$router-\u003egroup(['prefix' =\u003e 'admin'], function ($router) {\n  $router-\u003eget('/dashboard', ['DashboardController', 'index'], name: 'dashboard.index');\n});\n```\n\nApart from add prefixes and middlewares, you can also group routes by their controllers as follows:\n\n```php\nuse App\\Controllers\\PostsController;\n\n$router-\u003egroup(['controller' =\u003e PostsController::class], function ($router) {\n  $router-\u003eget('/posts', 'index', name: 'posts.index');\n  $router-\u003eget('/posts/create', 'create', name: 'posts.create');\n});\n```\n\nCombining all of these features, you can create a route like this:\n\n```php\nuse App\\Controllers\\PostsController;\n\n$router-\u003egroup([\n  'prefix'     =\u003e 'posts',\n  'middleware' =\u003e [AuthMiddleware::class, CsrfMiddleware::class],\n  'controller' =\u003e PostsController::class\n  ], function ($router) {\n  $router-\u003eget('/', 'index', name: 'posts.index');\n  $router-\u003eget('/posts/create', 'create', name: 'posts.create');\n});\n```\n\n**Available Methods:**\n\n- `get()`: Define a route for GET requests.\n- `post()`: Define a route for POST requests.\n- `put()`: Define a route for PUT requests.\n- `delete()`: Define a route for DELETE requests.\n- `group()`: Define a group of routes.\n\n## Middleware\n\nMiddleware provides a convenient mechanism for filtering HTTP requests entering your application. Global middleware is applied to all routes, while route-specific middleware can be applied to individual routes or groups.\n\n**Global Middleware:**\n\nAll global middleware is defined in the `config/middleware.php` file. These middleware will run on every request through the application.\n\n```php\nreturn [\n    /**\n     * Global middleware that runs on every request\n     *\n     * @var array\u003cclass-string\u003e\n     */\n    'global' =\u003e [\n        CsrfMiddleware::class,\n        SessionMiddleware::class,\n    ],\n];\n```\n\n**Route-Specific Middleware:**\n\nYou can apply middleware to a specific route or group of routes by using the group method with a closure. To apply middleware to a group of routes, you can use the group method. This is useful for applying middleware to a group of routes that share the same middleware.\n```php\n$router-\u003egroup(['middleware' =\u003e [CsrfMiddleware::class]], function ($router) {\n    $router-\u003eget('/posts', 'App\\Controllers\\Web\\Posts\\PostsController@index');\n});\n```\n\nYou can also define middleware groups in the `config/middleware.php` file. If you register middleware in the `config/middleware.php` file, it will be applied to the routes in the web.php file.\n\n```php\n/**\n * Middleware groups\n * These middleware groups are applied to the routes in the web.php file\n *\n * @var array\u003cstring, array\u003cclass-string\u003e\u003e\n */\n'groups' =\u003e [\n  'web' =\u003e [\n    AuthMiddleware::class,\n  ],\n];\n```\n\n**Creating Middleware:**\nOn top of the all ready middleware, you can create your own middleware. That you can register in the `config/middleware.php` file or apply to a specific route or group of routes.\n\n**Example:**\n```php\n\u003c?php\n\nnamespace App\\middleware;\n\nuse Closure;\nuse Pocketframe\\Contracts\\MiddlewareInterface;\nuse Pocketframe\\Http\\Request\\Request;\nuse Pocketframe\\Http\\Response\\Response;\n\nclass ExampleMiddleware implements MiddlewareInterface\n{\n  public function handle(Request $request, Closure $next): Response\n  {\n    // Pre-middleware logic\n    $response = $next($request);\n\n    // Post-middleware logic\n    return $response;\n  }\n}\n```\n\n## Controllers\nControllers are responsible for handling incoming requests and returning responses. Controllers can group related request handling logic into a single class. They are stored in the app/Controllers directory.\n\n**Creating a Controller:**\n\nTo help you create a controller, run the following pocket command:\n```bash\nphp pocket controller:create HomeController\n```\n\u003e [!IMPORTANT]\n\u003e All controllers are stored in the `app/Controllers` directory. Inside the Controllers directory, there are two subdirectories: `Web` and `Api`. The `Web` directory is used for web routes and the `Api` directory is used for API routes.\n\n**Basic Controller Example:**\n\n```php\n\u003c?php\n\nnamespace App\\Controllers\\Web\\Posts;\n\nuse Pocketframe\\Database\\DB;\nuse Pocketframe\\Http\\Response\\Response;\n\nclass PostsController\n{\n  public function index(): Response\n  {\n    $posts = DB::table('posts')\n      -\u003eselect(['id', 'title'])\n      -\u003eorderByDesc('id')\n      -\u003epaginate(10);\n\n    return Response::view('posts/index', [\n      'posts' =\u003e $posts,\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\n```php\n$router-\u003eget('/posts', [PostsController::class, 'index']);\n```\nWhen a request is made to the `/posts` route, the `index()` method of the `PostsController` class will be executed.\n\n### Single Action Controllers\nSingle action controllers are a simple way to define a controller that only has a single action. They are basically have a single method called `__invoke()` that handles the incoming request\n\nTo create a single action controller, you can run the following pocket command:\n```bash\nphp pocket controller:create DashboardController --invokable\n```\n\u003e [!TIP]\n\u003e You can also abbreviate the command to\n\u003e\n\u003e `php pocket controller:create DashboardController -i`\n\n**Example:**\n```php\nuse Pocketframe\\Http\\Request\\Request;\n\nclass PostsController\n{\n   public function __invoke(Request $request)\n    {\n       //\n    }\n}\n```\n\n### Resource Controllers\nResource controllers are a type of controller that is used to handle CRUD operations. They are a great way to organize your code and make it easier to maintain.\n\nIf you want to generate a resource controller, you can run the following pocket command:\n```bash\nphp pocket controller:create PostsController --resource\n```\n\n\u003e [!TIP]\n\u003e You can also abbreviate the command to\n\u003e\n\u003e `php pocket controller:create PostsController -r`\n\n\nAvailable actions in a resource controller:\n\n| HTTP Verb | URI             | Action  | Route Name   |\n| --------- | --------------- | ------- | ------------ |\n| GET       | /post           | index   | post.index   |\n| GET       | /post/create    | create  | post.create  |\n| POST      | /post           | store   | post.store   |\n| GET       | /post/{id}      | show    | post.show    |\n| GET       | /post/{id}/edit | edit    | post.edit    |\n| PUT       | /post/{id}      | update  | post.update  |\n| DELETE    | /post/{id}      | destroy | post.destroy |\n\n### API Controllers\nYou can also generate a controller specifically for the API. API controllers only contains `index`, `store`, `show`, `update` and `destroy` To do this, you can run the following pocket command:\n```bash\nphp pocket controller:create PostsController --api\n```\n\n## CSRF Protection\n\nCross-site request forgeries are a type of malicious exploit whereby unauthorized action is performed on behalf of the user. In other words, a user is tricked into submitting a malicious form without their knowledge. By default, Pocketframe includes a middleware that will protect your application against cross-site request forgeries.\n\n### Preventing CSRF Attacks\nTo prevent CSRF attacks, you should include a CSRF token in all your forms. You can generate a CSRF token using the `csrf_token()` helper function.\n\n```php\n\u003cform method=\"POST\" action=\"/profile\"\u003e\n    \u003c% csrf_token() %\u003e\n\n    \u003c!-- same as below --\u003e\n    \u003cinput type=\"hidden\" name=\"_token\" value=\"\u003c% SESSION['csrf_token'] %\u003e\" /\u003e\n\u003c/form\u003e\n```\n\n\u003e [!IMPORTANT]\n\u003e If you are using a framework like Vue or React, you should not use the `csrf_token()` helper function. Instead, you should use the `_token()` helper function. This will generate a CSRF token that is unique to the current user.\n\n## Requests\nThis class is used to handle the incoming request. It allows you to access request data, headers, and more.\n\n**How to use the Request class:**\n\nYou can access the request data using the `Request` class. The request class can be injected into the controller method. This is useful when you need to access the request data in the controller method and will allow you access all the methods and properties of the request class.\n\n```php\n\u003c?php\n\nnamespace App\\Controllers\\Web\\Posts;\n\nuse Pocketframe\\Http\\Request\\Request;\n\nclass PostsController\n{\n  public function store(Request $request)\n  {\n    $request-\u003epost('title');\n  }\n}\n\n```\n\n**Available Methods:**\n\n- **Get the HTTP method of the request (GET, POST, etc.)**\n\n  If you want to get the HTTP method of the request, you can use the `method()` method.\n\n  ```php\n  $request-\u003emethod();\n  ```\n\n- **Check the HTTP method of the request**\n\n  If you want to check the HTTP method of the request, you can use the `isMethod($method)` method. This method will return true if the HTTP method of the request matches the method passed to the method.\n\n  ```php\n  $request-\u003eisMethod('get');\n  ```\n\n- **Get the URI of the request**\n\n  If you want to get the URI of the request, you can use the `uri()` method. This method will return the URI of the request.\n\n  ```php\n  $request-\u003euri();\n  ```\n\n- **Get all request data as an array (GET, POST, FILES)**\n\n  If you want to get all the request data as an array, you can use the `all()` method. This method will return an array of all the request data.\n\n  ```php\n  $request-\u003eall();\n  ```\n\n - **Get a value from the GET parameters**\n\n    If you want to get a value from the GET parameters, you can use the `get($key)` method. This method will return the value of the GET parameter passed to the method.\n\n    ```php\n    $request-\u003eget($id);\n    ```\n\n- **Get a value from the POST parameters**\n\n  If you want to get a value from the POST parameters, you can use the `post($key)` method. This method will return the value of the POST parameter passed to the method.\n\n  ```php\n  $request-\u003epost('name');\n  ```\n\n- **Get a value from the JSON request body**\n\n  If you want to get a value from the JSON request body, you can use the `json($key)` method. This method will return the value of the JSON request body passed to the method.\n\n  ```php\n  $request-\u003ejson('name');\n  ```\n\n- **Check if the request contains JSON data**\n\n  If you want to check if the request contains JSON data, you can use the `isJson()` method. This method will return true if the request contains JSON data.\n\n  ```php\n  $request-\u003eisJson();\n  ```\n\n- **Get an uploaded file by key**\n\n  If you want to get an uploaded file by key, you can use the `file($key)` method. This method will return the uploaded file passed to the method.\n\n  ```php\n  $request-\u003efile('image');\n  ```\n\n- **Check if a file was uploaded for the given key**\n\n  If you want to check if a file was uploaded for the given key, you can use the `hasFile($key)` method. This method will return true if the file was uploaded for the given key.\n\n  ```php\n  $request-\u003ehasFile($key);\n  ```\n\n- **Check if a parameter exists in the request**\n\n  If you want to check if a parameter exists in the request, you can use the `has($key)` method. This method will return true if the parameter exists in the request.\n\n  ```php\n  $request-\u003ehas('name');\n  ```\n\n- **Check if parameter exists and is not empty**\n\n  If you want to check if a parameter exists and is not empty, you can use the `filled($key)` method. This method will return true if the parameter exists and is not empty.\n\n\n  ```php\n  $request-\u003efilled('name');\n  ```\n\n- **Sanitize input data to prevent XSS attacks**\n\n  If you want to sanitize input data to prevent XSS attacks, you can use the `sanitize($input)` method. This method will sanitize the input data passed to the method.\n\n    ```php\n    $request-\u003esanitize('name');\n  ```\n\n- **Check if request expects JSON response**\n\n  If you want to check if the request expects a JSON response, you can use the `expectsJson()` method. This method will return true if the request expects a JSON response.\n\n  ```php\n  $request-\u003eexpectsJson();\n  ```\n\n- **Get a request header value**\n\n  If you want to get a request header value, you can use the `header($key, $default)` method. This method will return the value of the request header passed to the method.\n\n  ```php\n  $request-\u003eheader('X-Header-Name'\n  ```\n\n- **Get a cookie value**\n\n  If you want to get a cookie value, you can use the `cookie($key, $default)` method. This method will return the value of the cookie passed to the method.\n\n\n  ```php\n  $request-\u003ecookie('name');\n  ```\n\n- **Check if request is an AJAX request**\n\n  If you want to check if the request is an AJAX request, you can use the `isAjax()` method. This method will return true if the request is an AJAX request.\n\n\n  ```php\n  $request-\u003eisAjax();\n  ```\n\n- **Get the full URL of the request**\n\n  If you want to get the full URL of the request, you can use the `url()` method. This method will return the full URL of the request.\n\n  ```php\n  $request-\u003eurl();\n  ```\n\n- **Get the URL of the previous request**\n\n  If you want to get the URL of the previous request, you can use the `previous()` method. This method will return the URL of the previous request.\n\n  ```php\n  $request-\u003eprevious();\n  ```\n\n- **Create redirect response to previous URL**\n\n  If you want to create a redirect response to the previous URL, you can use the `back()` method. This method will redirect the user to the previous URL.\n\n  ```php\n  $request-\u003eback();\n  ```\n\n- **Get the user agent string**\n\n  If you want to get the user agent string, you can use the `userAgent()` method. This method will return the user agent string of the request.\n\n  ```php\n  $request-\u003euserAgent();\n  ```\n\n- **Get the client IP address**\n\n  If you want to get the client IP address, you can use the `ip()` method. This method will return the client IP address of the request.\n\n  ```php\n  $request-\u003eip();\n  ```\n\n- **Check if request was made over HTTPS**\n\n  If you want to check if the request was made over HTTPS, you can use the `isSecure()` method. This method will return true if the request was made over HTTPS.\n\n  ```php\n  $request-\u003eisSecure();\n  ```\n\n- **Set session data**\n\n  If you want to set session data, you can use the `setSession($data)` method. This method will set the session data passed to the method.\n\n  ```php\n  $request-\u003esetSession($data);\n  ```\n\n- **Get all session data**\n\n  If you want to get all the session data, you can use the `session()` method. This method will return all the session data.\n\n  ```php\n  $request-\u003esession();\n  ```\n\n- **Check if request wants JSON response**\n\n  If you want to check if the request wants a JSON response, you can use the `wantsJson()` method. This method will return true if the request wants a JSON response.\n\n  ```php\n  $request-\u003ewantsJson();\n  ```\n\n\n## Responses\n\nRoutes and controllers can return a response which will be sent to the user. The response class is used to send HTTP responses. It supports various response types, including views, JSON, redirects and more. This class also supports status codes and headers.\n\n```php\nreturn Response::view('home');\n```\n\n**Available status codes:**\n\nThis class has has the following status codes.\n\n```php\nResponse::OK\nResponse::CREATED\nResponse::REDIRECT\nResponse::BAD_REQUEST\nResponse::UNAUTHORIZED\nResponse::FORBIDDEN\nResponse::NOT_FOUND\nResponse::METHOD_NOT_ALLOWED\nResponse::PAGE_EXPIRED\nResponse::INTERNAL_SERVER_ERROR\n\n```\n\n**Available Methods:**\n\n- **Render a view with optional data and status code**\n\n  If you want to render a view with optional data and status code, you can use the `view()` method. This method will render the view passed to the method and return a response.\n\n  ```php\n  Response::view('home', ['name' =\u003e 'John Doe']);\n  ```\n\n- **Return JSON response with optional status code**\n\n  If you want to return a JSON response with optional status code, you can use the `json()` method. This method will return a JSON response with the data passed to the method and the status code passed to the method.\n\n  ```php\n  Response::json(['name' =\u003e 'John Doe']);\n  ```\n\n- **Send the response to the client**\n\n  If you want to send the response to the client, you can use the `send()` method. This method will send the response to the client.\n\n  ```php\n  Response::send();\n  ```\n\n- **Redirect to a URL with optional status code**\n\n  If you want to redirect to a URL with optional status code, you can use the `redirect()` method. This method will redirect the user to the URL passed to the method and the status code passed to the method.\n\n  ```php\n  Response::redirect('/posts');\n  ```\n\n- **Return plain text response with optional status code**\n\n  If you want to return a plain text response with optional status code, you can use the `text()` method. This method will return a plain text response with the text passed to the method and the status code passed to the method.\n\n  ```php\n  Response::text('Hello, world!');\n  ```\n\n- **Return empty response with 204 status code**\n\n  If you want to return an empty response with 204 status code, you can use the `noContent()` method. This method will return an empty response with the status code 204.\n\n  ```php\n  Response::noContent();\n  ```\n\n- **Return file download response**\n\n  If you want to return a file download response, you can use the `file()` method. This method will return a file download response with the path passed to the method and the name passed to the method.\n\n  ```php\n  Response::file('path/to/file.pdf', 'file.pdf');\n  ```\n\n- **Stream response content**\n\n  If you want to stream response content, you can use the `stream()` method. This method will stream the response content passed to the method.\n\n  ```php\n  Response::stream(function () {\n    echo 'Hello, world!';\n  });\n  ```\n\n- **Set response header**\n\n  If you want to set a response header, you can use the `setHeader()` method. This method will set the header passed to the method.\n\n  ```php\n  Response::setHeader('X-Header-Name', 'X-Header-Value');\n  ```\n\n- **Get all response headers**\n\n  If you want to get all response headers, you can use the `getHeaders()` method. This method will return an array of all the response headers.\n\n  ```php\n  Response::getHeaders();\n  ```\n\n- **Set response cookie**\n\n  If you want to set a response cookie, you can use the `setCookie()` method. This method will set the cookie passed to the method. The cookie will be set for the current request.\n\n  ```php\n  Response::setCookie('name', 'value', 0, '/', '', false, false);\n  ```\n  **Parameters available:**\n\n   - name: the name of the cookie\n   - value: the value of the cookie\n   - expire: the expiration date of the cookie\n   - path: the path of the cookie\n   - domain: the domain of the cookie\n   - secure: whether the cookie is secure\n   - httponly: whether the cookie is httponly\n\n- **Enable response caching**\n\n  If you want to enable response caching, you can use the `cacheFor()` method. This method will cache the response for the number of minutes passed to the method.\n\n  ```php\n  Response::cacheFor(10);\n  ```\n\n- **Disable response caching**\n\n  If you want to disable response caching, you can use the `noCache()` method. This method will disable response caching.\n\n  ```php\n  Response::noCache();\n  ```\n\n- **Return JSONP response**\n\n  If you want to return a JSONP response, you can use the `jsonp()` method. This method will return a JSONP response with the data passed to the method and the callback parameter passed to the method.\n\n  ```php\n  Response::jsonp(['name' =\u003e 'John Doe'], 'callback');\n  ```\n\n- **Return formatted JSON response**\n\n  If you want to return a formatted JSON response, you can use the `prettyJson()` method. This method will return a formatted JSON response with the data passed to the method and the status code passed to the method.\n\n  ```php\n  Response::prettyJson(['name' =\u003e 'John Doe']);\n  ```\n\n- **Add response header**\n\n  If you want to add a response header, you can use the `withHeader()` method. This method will add a response header with the name and value passed to the method.\n\n  ```php\n  Response::withHeader('X-Header-Name', 'X-Header-Value');\n  ```\n\n- **Check if response is successful**\n\n  If you want to check if response is successful, you can use the `isOk()` method. This method will return true if the response is successful.\n\n  ```php\n  Response::isOk();\n  ```\n\n- **Check if response is redirect**\n\n  If you want to check if response is redirect, you can use the `isRedirect()` method. This method will return true if the response is redirect.\n\n  ```php\n  Response::isRedirect();\n  ```\n\n- **Check if response is client error**\n\n  If you want to check if response is client error, you can use the `isClientError()` method. This method will return true if the response is client error.\n\n  ```php\n  Response::isClientError();\n  ```\n\n- **Check if response is server error**\n\n  If you want to check if response is server error, you can use the `isServerError()` method. This method will return true if the response is server error.\n\n  ```php\n  Response::isServerError();\n  ```\n\n- **Set response as file attachment**\n\n  If you want to set response as file attachment, you can use the `attachment()` method. This method will set the response as a file attachment with the filename passed to the method.\n\n  ```php\n  Response::attachment('file.pdf');\n  ```\n\n\n## Database\n\n#### Configuration\n\nYou can configure the database by adding the following to the `.env` file.\n\n```\nDB_CONNECTION=mysql\nDB_HOST=127.0.0.1\nDB_PORT=3306\nDB_DATABASE=your_database\nDB_USERNAME=your_username\nDB_PASSWORD=your_password\n```\n\nAfter configuring the database, you can use the `DB` class to interact with the database.\n\n\n```php\n$posts = DB::table('posts')-\u003eget();\n```\n\n**Available Methods:**\n\n  - **table(string $table)**\n\n    Sets the table name for the query. You can pass the table name to the method.\n    ```php\n    DB::table('users')\n    ```\n    **Parameters:**\n    - `$table`: The name of the table to query.\n\n  - **select(array $columns)**\n\n    Specifies which columns to select from the table. You can pass an array of columns to select from the table.\n    ```php\n    DB::table('users')-\u003eselect(['id', 'name', 'email'])\n    ```\n    **Parameters:**\n    - `$columns`: An array of columns to select from the table.\n\n  - **where(string $column, string $operator, mixed $value)**\n\n    Adds a WHERE clause to filter results.\n    ```php\n    DB::table('users')-\u003ewhere('age', '\u003e', 18)\n    ```\n    **Parameters:**\n    - `$column`: The column to filter by.\n    - `$operator`: The operator to use in the filter.\n    - `$value`: The value to filter by.\n\n  - **orWhere(string $column, string $operator, string $value)**\n\n    Adds an OR WHERE clause to filter results.\n    ```php\n    DB::table('users')-\u003ewhere('age', '\u003e', 18)-\u003eorWhere('role', '=', 'admin')\n    ```\n    **Parameters:**\n    - `$column`: The column to filter by.\n    - `$operator`: The operator to use in the filter.\n    - `$value`: The value to filter by.\n\n  - **andWhere(string $column, string $operator, string $value)**\n\n    Adds an AND WHERE clause to filter results.\n    ```php\n    DB::table('users')-\u003ewhere('age', '\u003e', 18)-\u003eandWhere('active', '=', 1)\n    ```\n    **Parameters:**\n    - `$column`: The column to filter by.\n    - `$operator`: The operator to use in the filter.\n    - `$value`: The value to filter by.\n\n  - **whereNull(string $column)**\n\n    Adds a WHERE IS NULL clause.\n    ```php\n    DB::table('users')-\u003ewhereNull('deleted_at')\n    ```\n    **Parameters:**\n    - `$column`: The column to filter by.\n\n  - **whereNotNull(string $column)**\n\n    Adds a WHERE IS NOT NULL clause.\n    ```php\n    DB::table('users')-\u003ewhereNotNull('email')\n    ```\n    **Parameters:**\n    - `$column`: The column to filter by.\n\n  - **andWhereNull(string $column)**\n\n    Adds an AND WHERE IS NULL clause.\n    ```php\n    DB::table('users')-\u003ewhere('active', '=', 1)-\u003eandWhereNull('deleted_at')\n    ```\n    **Parameters:**\n    - `$column`: The column to filter by.\n\n  - **orIsNull(string $column)**\n\n    Adds an OR WHERE IS NULL clause.\n    ```php\n    DB::table('users')-\u003ewhere('active', '=', 1)-\u003eorIsNull('deleted_at')\n    ```\n    **Parameters:**\n    - `$column`: The column to filter by.\n\n  - **orderByDesc(string $column)**\n\n    Orders results by a column in descending order.\n    ```php\n    DB::table('users')-\u003eorderByDesc('created_at')\n    ```\n    **Parameters:**\n    - `$column`: The column to order by.\n\n  - **orderByAsc(string $column)**\n\n    Orders results by a column in ascending order.\n    ```php\n    DB::table('users')-\u003eorderByAsc('name')\n    ```\n    **Parameters:**\n    - `$column`: The column to order by.\n\n  - **orWhereNotNull(string $column)**\n\n    Adds an OR WHERE IS NOT NULL clause.\n    ```php\n    DB::table('users')-\u003ewhere('active', '=', 1)-\u003eorWhereNotNull('email')\n    ```\n    **Parameters:**\n    - `$column`: The column to filter by.\n\n  - **join(string $table, string $firstColumn, string $operator, string $secondColumn, string $type = 'INNER')**\n\n    Adds a JOIN clause to the query.\n    ```php\n    DB::table('users')-\u003ejoin('posts', 'users.id', '=', 'posts.user_id')\n    ```\n    **Parameters:**\n    - `$table`: The table to join.\n    - `$firstColumn`: The first column to join on.\n    - `$operator`: The operator to use in the join.\n    - `$secondColumn`: The second column to join on.\n    - `$type`: The type of join to use.\n\n  - **limit(int $limit)**\n\n    Limits the number of results returned.\n    ```php\n    DB::table('users')-\u003elimit(10)\n    ```\n    **Parameters:**\n    - `$limit`: The number of results to return.\n\n  - **offset(int $offset)**\n\n    Sets the offset for the results.\n    ```php\n    DB::table('users')-\u003eoffset(10)\n    ```\n    **Parameters:**\n    - `$offset`: The offset to set for the results.\n  - **get()**\n\n    Executes the query and returns all results.\n    ```php\n    DB::table('users')-\u003eget()\n    ```\n\n  - **first()**\n\n    Gets the first result from the query.\n    ```php\n    DB::table('users')-\u003efirst()\n    ```\n\n  - **count()**\n\n    Counts the number of results.\n    ```php\n    DB::table('users')-\u003ecount()\n    ```\n\n  - **paginate(int $perPage = 15)**\n\n    Paginates the results.\n    ```php\n    DB::table('users')-\u003epaginate(20)\n    ```\n    **Parameters:**\n    - `$perPage`: The number of results to return per page.\n\n  - **insert(string $table, array $columns)**\n\n    Inserts a new record.\n    ```php\n    DB::insert('users',\n    [\n      'name' =\u003e 'John',\n      'email' =\u003e 'john@example.com'\n    ]);\n    ```\n    **Parameters:**\n    - `$table`: The table to insert the record into.\n    - `$columns`: An array of columns to insert into the table.\n\n  - **update(string $table, array $sets, array $condition)**\n\n    Updates existing records.\n    ```php\n    DB::update('users',\n    [\n      'name' =\u003e 'John',\n      'email' =\u003e 'johndoe@example.com'\n    ],\n    [\n      'id' =\u003e 1\n    ]);\n    ```\n    **Parameters:**\n    - `$table`: The table to update the record in.\n    - `$sets`: An array of columns to update.\n    - `$condition`: An array of conditions to update the record.\n\n  - **delete(string $table, array $condition)**\n\n    Soft deletes records (sets deleted_at).\n    ```php\n    DB::delete('users', ['id' =\u003e 1])\n    ```\n    **Parameters:**\n    - `$table`: The table to delete the record from.\n    - `$condition`: An array of conditions to delete the record.\n\n  - **forceDelete(string $table, array $condition)**\n\n    Permanently deletes records.\n    ```php\n    DB::forceDelete('users', ['id' =\u003e 1])\n    ```\n    **Parameters:**\n    - `$table`: The table to delete the record from.\n    - `$condition`: An array of conditions to delete the record.\n\n  - **transaction(callable $callback)**\n\n    Executes queries within a transaction.\n    ```php\n    DB::transaction(function() use($request) {\n      // Insert a post\n      $post = DB::insert('posts', [\n        'user_id' =\u003e 1,\n        'title' =\u003e $request-\u003epost('title'),\n        'body' =\u003e $request-\u003epost('body'),\n      ]);\n\n      // Insert a comment\n      DB::insert('comments', [\n        'post_id' =\u003e $post-\u003eid,\n        'body' =\u003e $request-\u003epost('body'),\n      ]);\n    })\n    ```\n    **Parameters:**\n    - `$callback`: A callback function to execute the queries.\n\n## Error Handling and Exceptions\nBy default, Pocketframe will display a generic error message for any unhandled exceptions. However, you can customize the error handling behavior by creating a custom error handler.\n\n### Some of the built-in error handlers include:\n- **DatabaseException**: Handles database-related errors.\n- **AuthenticationException**: Handles authentication-related errors.\n- **CacheException**: Handles cache-related errors.\n- **ValidationException**: Handles validation-related errors.\n- **ConfigurationException**: Handles configuration-related errors.\n- **FileSystemException**: Handles file system-related errors.\n- **HTTP Exception**: Handles HTTP-related errors.\n- **MiddlewareException**: Handles middleware-related errors.\n\n### Creating a Custom Error Handler\nYou can also create your own custom error handler by extending the `PocketframeException` class.\n\n**Example:**\n```php\n\u003c?php\n\nnamespace Pocketframe\\Exceptions\\HTTP;\n\nuse Pocketframe\\Exceptions\\PocketframeException;\n\nclass CustomException extends PocketframeException\n{\n  public function __construct($message = \"Custom error message\")\n  {\n    parent::__construct($message, 403);\n  }\n}\n```\n\n## Logging\nPocketframe provides a simple logging system that allows you to log messages to a file or the console.\n\n\n## Views\nPocketframe has a simple and powerful view system that is called **Pocket View**\n\nAs you develop your application, you'll often need to display data to the user. Pocketframe provides a powerful view system that allows you to create and render views to your users. The views will not be mixed with the rest of your code, making it easy to manage and maintain your application. They usually separates your logic from your presentation.\n\n\n```html\n\u003c!-- views/welcome.view.php --\u003e\n\n\u003chtml\u003e\n  \u003chead\u003e\n    \u003ctitle\u003ePocketframe\u003c/title\u003e\n  \u003c/head\u003e\n  \u003cbody\u003e\n    \u003ch1\u003eWelcome to {{ $name }}!\u003c/h1\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\nYour views are stored in the `resources/views` directory of your application. You can create as many views as you need, and they will be automatically loaded by Pocketframe when you render them. You can also create subdirectories within the `resources/views` directory to organize your views into logical groups.\n\n\u003e [!TIP]\n\u003e Pocket View has an extension of **.view.php** and compiled into PHP files.\n\n### Creating and Rendering Views\nTo create a view, you can simply run a command in your terminal:\n```bash\nphp pocket view:create welcome\n```\nThis will create a new view file in the `resources/views` directory. You can then render the view by return a response in your controller:\n```php\n\u003c?php\nnamespace App\\Controllers;\n\nuse Pocketframe\\Http\\Request;\nuse Pocketframe\\Http\\Response;\n\nclass WelcomeController\n{\n  public function index(Request $request)\n  {\n    return Response::view('welcome', ['name' =\u003e 'Pocketframe']);\n  }\n}\n```\n\n### Passing Data to Views\nYou can pass data to your views by passing an array of data to the view function:\n```php\nreturn Response::view('welcome', ['name' =\u003e 'Pocketframe']);\n```\n\n## Pocket View Template Engine\n\n### Introduction\nPocket View uses a simple and powerful template engine that allows you to easily create and render views to your users. It provides a clean and intuitive syntax for creating dynamic views, with features like template inheritance, reusable components, caching, and more. The engine is designed to be easy to use and understand, making it a great choice for building dynamic and interactive web applications. Pocket View has greatly been inspired by Laravel's Blade template engine.\n\n### Basic Syntax\nThe template engine uses a custom syntax that is easy to read and write. Below are the basic directives and their usage.\n\n| Directive                          | Example                                                                          | Use Case                   |\n| ---------------------------------- | -------------------------------------------------------------------------------- | -------------------------- |\n| `@layout`                          | `@layout('app')`                                                                 | Specify parent template    |\n| `@block`/`@endblock`               | `@block('content')...@endblock`                                                  | Define template sections   |\n| `@insert`                          | `@insert('sidebar')`                                                             | Insert block content       |\n| `@if`/`elseif`/`@else`/`@endif`    | `@if($condition)...@endif`                                                       | Conditional statements     |\n| `@foreach`/`@endforeach`           | `@foreach(...)...@endforeach`                                                    | Loop through items         |\n| `@each`/ `@endeach`                | `@each($items, $item, empty)...@endeach`                                         | Loop through items         |\n| `@include`                         | `@include('partial')`                                                            | Include partial templates  |\n| `@component`                       | `@component('button')`                                                           | Create reusable components |\n| `@embed`                           | `@embed('button', ['text' =\u003e 'Submit'])`                                         | Embed components           |\n| `@csrf`                            | `@csrf`                                                                          | CSRF token field           |\n| `@method`                          | `@method('PUT')`                                                                 | HTTP method spoofing       |\n| `@error`/`@enderror`               | `@error('field')...@enderror`                                                    | Display validation errors  |\n| `@cache`/`@endcache`               | `@cache('key', 60)...@endcache`                                                  | Fragment caching           |\n| `{{ }}`/`{{! }}`/`{{js  }}`/`@{ }` | `{{ $var }}` `{{! $html }}` `{{js $name  }}` `@{ json: $user, hydrate: 'User' }` | Escaped/raw output         |\n\n### Template Inheritance\nThe engine supports template inheritance, which allows you to create a base template that other templates can extend. This makes it easy to create consistent layouts and styles across your application.\n\n### Base Template\nThe framework provides a base template that you can extend in your views. The base template is located in the `resources/views/layouts` directory.\n```html\n\u003c!-- resources/views/layouts/app.view.php --\u003e\n\n \u003c!DOCTYPE html\u003e\n \u003chtml\u003e\n  \u003chead\u003e\n    \u003cmeta charset=\"utf-8\"\u003e\n    \u003cmeta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"\u003e\n    \u003ctitle\u003e@insert('title)\u003c/title\u003e\n    \u003cmeta name=\"description\" content=\"\"\u003e\n    \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1\"\u003e\n    \u003clink rel=\"stylesheet\" href=\"\"\u003e\n  \u003c/head\u003e\n  \u003cbody\u003e\n      \u003cdiv class=\"container\"\u003e\n        @insert('content')\n      \u003c/div\u003e\n  \u003c/body\u003e\n \u003c/html\u003e\n\n  ```\n\n### Child Template (`home.view.php`)\n\n```php\n@layout('layout/app')\n\n@block('title')\n    Home Page\n@endblock\n\n@block('content')\n    \u003cp\u003eThis is the home page content.\u003c/p\u003e\n@endblock\n```\n\n### Components\nComponents allow you to define and reuse blocks of content. You can either create a class based component or an inline component. To create a component, use a pocket command `pocket component:create \u003cname\u003e`\n\n#### Class Based Component\n\nClass based components are components that have both the component class and the component view. To create a class based component, use a pocket command\n\n```bash\nphp pocket component:create ButtonComponent\n```\n\nThis will create a new component class and a new component view. The component class will be located in the `app/View/Components` directory and the component view will be located in the `resources/views/components` directory.\n\n\u003e [!IMPORTANT]\n\u003e When creating a component, always follow a name pattern of `ComponentName` which is known as **PascalCase**. If you use a different name pattern you may get wrong file names.\n\n#### Example of Class Based Component\n\n```php\n\u003c?php\n\nnamespace App\\View\\Components;\n\nclass ButtonComponent\n{\n    public array $props = [];\n\n    public function __construct(array $props = [])\n    {\n        $this-\u003eprops = $props;\n    }\n\n    /**\n     * Returns the view path for this component.\n     *\n     * @return string\n     */\n    public function render(): string\n    {\n        return view('button-component', get_object_vars($this));\n    }\n}\n\n```\n\nThe component class will return the view path for the component view. The `get_object_vars()` function is used to pass the properties of the component to the view. Once properties are added to the component, they will be available to the render method automatically will be passed to the view. However you can still define variables within the render method and merge them with the properties of the component.\n\n#### Example\n\n```php\n\u003c?php\n\nnamespace App\\View\\Components;\n\nclass ButtonComponent\n{\n    public array $props = [];\n\n    public function __construct(array $props = [])\n    {\n        $this-\u003eprops = $props;\n    }\n\n    /**\n     * Returns the view path for this component.\n     *\n     * @return string\n     */\n    public function render(): string\n    {\n      $class = 'btn';\n      return view('button-component',array_merge(\n            get_object_vars($this),\n            [\n                'class' =\u003e $class\n            ]\n        ));\n    }\n}\n```\n\n#### Component View example\n\n```php\n\u003cbutton class=\"\u003c?= $class ?\u003e\"\u003e\u003c?= $text ?\u003e\u003c/button\u003e\n```\n\n\n#### Inline Component\n\nInline components are components that do not have a component class. They are defined directly in the view. To create an inline component, use a pocket command\n\n```bash\npocket component:create Alert --inline\n```\n\nThis will create a new component view. The view will be stored in `resources/views/components` directory.\n\n\nPocket View provide you with a syntax \u003cx-... \u003e whichis more like XML. For example the above component can be written as:\n\n```php\n\u003cbutton class=\"bg-green-500 text-white rounded-lg shadow hover:bg-green-600 transition-colors duration-200 inline-flex items-center p-2\"\u003e\n  \u003c?= $slot ?\u003e\n\u003c/button\u003e\n```\n\n```php\n\u003cx-button text=\"Submit\" /\u003e\n```\n\n\u003e [!IMPORTANT]\n\u003e When you create a component and you want to pass data to it, always add slots by using `\u003c?= $slot ?\u003e`. If you use `{{ $slot }}` you will get an error or the component will fail to render.\n\n#### Example\n\n```php\n// resources/views/components/alert.inline.view.php\n\n\u003cdiv class=\"alert alert-{{ $type }}\"\u003e\n    \u003c?= $message ?\u003e\n\u003c/div\u003e\n```\n\n#### Usage\n\n```php\n\u003cdiv\u003e\n\n    \u003cx-alert type=\"success\" message=\"This is a success message\" /\u003e\n\n    \u003cx-alert type=\"danger\" message=\"This is a danger message\" /\u003e\n\n \u003c/div\u003e\n ```\n\n```php\n@component('button')\n    \u003cbutton class=\"\u003c?= $class ?\u003e\"\u003e\u003c?= $text ?\u003e\u003c/button\u003e\n@endcomponent\n\n@component('alert')\n    \u003cdiv class=\"alert alert-\u003c?= $type ?\u003e\"\u003e\n        \u003c?= $message ?\u003e\n    \u003c/div\u003e\n@endcomponent\n```\n\n#### Using a Component\n\n```php\n@layout('layouts/app')\n\n@block('content')\n    \u003cdiv\u003e\n        @embed('button', ['text' =\u003e 'Submit'])\n        @embed('button', ['text' =\u003e 'Cancel'])\n\n        @embed('alert', [\n            'type' =\u003e 'success',\n            'message' =\u003e 'Operation completed successfully!'\n        ])\n    \u003c/div\u003e\n@endblock\n```\n\n#### Partials\n\nPartials are reusable pieces of code that can be included in other views. To create a partial, use a pocket command.\n\n```bash\nphp pocket partial:create \u003cname\u003e\n```\n\nThis will create a new partial view. The view will be stored in `resources/views/partials` directory.\n\n#### Example\n\n```php\n// resources/views/partials/header.view.php\n\n\u003cheader\u003e\n    \u003ch1\u003e\u003c?= $title ?\u003e\u003c/h1\u003e\n\u003c/header\u003e\n```\n\n#### Usage\n\n```php\n@layout('layouts/app')\n\n@block('content')\n    @include('partials/header', ['title' =\u003e 'Home'])\n@endblock\n```\n\n### Control Structures\nThe template engine supports common control structures like if, foreach, and each.\n\n#### If Statement\n\n```php\n@if ($condition)\n    \u003cp\u003eCondition is true\u003c/p\u003e\n@elseif ($condition2)\n    \u003cp\u003eCondition 2 is true\u003c/p\u003e\n@else\n    \u003cp\u003eCondition is false\u003c/p\u003e\n@endif\n```\n\n#### Foreach Loop\n\n```php\n@foreach ($items as $item)\n    \u003cp\u003e{{ $item }}\u003c/p\u003e\n@endforeach\n```\n\n#### Each Loop\n\nEach loop is a version of foreach loop that is used to iterate over an array of items. It is similar to foreach loop but it is used when you want to display a message automatically when no record is found in the database.\n\n```php\n@each($items, item, empty)\n    \u003cp\u003e{{ $item }}\u003c/p\u003e\n@endeach\n```\n\n#### Example\n\n```php\n@each($users, user, No users found)\n    \u003cp\u003e{{ $user['name'] }}\u003c/p\u003e\n@endeach\n```\n\n#### The `$loop` variable\n\nThe `$loop` variable is available inside the loop and provides information about the current iteration.\n\n#### Example\n\n```php\n@foreach ($items as $item)\n    \u003cp\u003e{{ $loop-\u003eiteration }}\u003c/p\u003e\n@endforeach\n```\n\n#### The `$loop` variable properties\n\n| Property    | Description                                    |\n| ----------- | ---------------------------------------------- |\n| `iteration` | The current iteration number                   |\n| `first`     | Whether the current iteration is the first one |\n| `last`      | Whether the current iteration is the last one  |\n| `index`     | The current iteration index                    |\n| `count`     | The total number of iterations                 |\n|             |\n\n### Rendering and displaying data\nYou can render and display data in your views by using the following syntax:\n```php\nreturn Response::view('welcome', ['name' =\u003e 'Pocketframe']);\n```\n```php\n\u003cp\u003e{{ $name }}\u003c/p\u003e\n```\nThe `{{  }}` syntax is used to display data in your views. These are called echo statements which automatically escape the data by using PHP's built-in `htmlspecialchars` function to prevent XSS attacks.\n\n### Displaying unescaped data\nIf you want to display unescaped data in your views, you can use the following syntax:\n```php\n\u003cp\u003e{{! $name }}\u003c/p\u003e\n```\n\n\u003e [!WARNING]\n\u003e You should use this syntax with caution as it can lead to security vulnerabilities if not used properly.\n\n### Javascript escaping\nYou can escape javascript code in your views by using the following syntax:\n\n```js\n\u003cscript\u003e\n  const name = {{js $name }};\n\u003c/script\u003e\n```\n\n### Caching\nCaching allows you to store rendered template fragments for improved performance.\n\n#### Cache a Block\n\n```php\n@cache('user_list', 60)\n    \u003cul\u003e\n        @foreach($users as $user)\n            \u003cli\u003e{{ $user['name'] }}\u003c/li\u003e\n        @endforeach\n    \u003c/ul\u003e\n@endcache\n```\n\n### Error Handling\nDisplay validation errors for form fields.\n\n#### Error Block\n\n```php\n@error('field')\n    \u003cp\u003e{{ $message }}\u003c/p\u003e\n@enderror\n```\n\n### Debugging\nEnable debugging to display debug information in development environments.\n\n#### Debug Block\n\n```php\n@debug\n    \u003cp\u003e{{ $message }}\u003c/p\u003e\n@enddebug\n```\n\n#### Dump\n\nYou can dump data in your views by using the following syntax:\n\n```php\n@dd($data)\n```\n\n### Lazy Loading\nLazy load content to improve page performance.\n\n#### Lazy Load Content\n\n```php\n@lazy('/path/to/content')\n```\n\n### CSRF Protection\nGenerate a CSRF token for forms.\n\n```php\n\u003cform method=\"POST\"\u003e\n    @csrf\n    \u003cbutton type=\"submit\"\u003eSubmit\u003c/button\u003e\n\u003c/form\u003e\n```\n\n### JavaScript Hydration\nHydrate JavaScript with data from the server.\n\n#### Hydration Example\n\n```php\n\u003cscript\u003e\n   @{ json: $user, hydrate: 'User' }\n\u003c/script\u003e\n```\n\n### Comments\nAdd comments to your templates that will not be rendered in the output.\n\n#### Template Comments\n\n```php\n{#  #}\n```\n\n### Method spoofing\nYou can spoof HTTP methods in forms by using the following syntax:\n\n```php\n// method spoofing\n\n@method('DELETE')\n```\n\n\n### Custom PHP Code\nExecute custom PHP code within templates.\n\n```php\n@php\n    $timestamp = time();\n@endphp\n\n\u003cp\u003eCurrent timestamp: {{ $timestamp }}\u003c/p\u003e\n```\n\n### Advanced Features\n\n#### Dynamic Components\n\nDynamically include components based on a variable.\n\n```php\n@embed($componentName, $componentData)\n```\n\n\n## Session\nPocketframe provides a simple and easy-to-use session management system that allows you to store and retrieve data between requests.\nPocketframe provides a simple and easy-to-use session management system that allows you to store and retrieve data between requests.\n\n## Validation\nPocketframe comes packed with a powerful validation system that allows you to validate user input and ensure that it meets the required criteria.\n\n### How validators work\nTo learn how validation works in Pocketframe, let's create a simple application that allows us to create a new post.\n\n### Defining the route\nFirst, we need to define a route in `web.php` that will handle the creation of a new post. We can do this by adding the following code to our routes file:\n\n```php\n\u003c?php\nuse App\\Controllers\\PostController;\n\nRoute::get('/posts/create', [PostController::class, 'create']);\nRoute::post('/posts', [PostController::class, 'store']);\n```\nThe `get` method is used to define a route that will be accessible via a GET request, while the `post` method is used to define a route that will be accessible via a POST request.\n\n### Creating the controller\nNext, we need to create a controller that will handle the creation of a new post. We can do this by creating a new file called `PostController.php` in the `app/Controllers` directory and adding the following code to it:\n\n```php\n\u003c?php\nnamespace App\\Controllers;\n\nuse Pocketframe\\Http\\Request;\nuse Pocketframe\\Http\\Response;\n\nclass PostController\n{\n  public function create()\n  {\n    return Response::view('posts.create');\n  }\n\n  public function store(Request $request)\n  {\n    // Logic goes here\n\n    return Response::redirect('/posts');\n  }\n}\n```\n\nAdding valiadation\nNow that we have defined the route and created the controller, we can add validation to the `store` method. We can do this by adding the following code to the `store` method:\n\n```php\nuse Pocketframe\\Masks\\Validator;\n\npublic function store(Request $request)\n{\n   Validator::validate(\n      $request-\u003eall(), [\n        'title' =\u003e ['required', 'string'],\n        'body'  =\u003e ['required'],\n      ])\n      -\u003efailed();\n\n  ....\n\n  return Response::redirect('/posts');\n}\n```\n\nIn this example, we are using the `Validator` mask to validate the input data. You should import this **mask**  `Pocketframe\\Masks\\Validator;` for you to able to use it We are passing the request data and an array of validation rules to the `validate` method. The `validate` method will return a `Validator` instance, which we can use to check if the validation failed or not.\n\n### Defining validation errors\nIf the incoming request fails validation, we can display the validation errors to the user.\n\n```html\n\u003c-- /resources/views/post/create.view.php --\u003e\n\n\u003cform method=\"POST\" action=\"{{ route('posts.store') }}\"\u003e\n  \u003cdiv\u003e\n    \u003clabel for=\"title\"\u003ePost Title\u003c/label\u003e\n    \u003cinput id=\"title\" type=\"text\" name=\"title\" /\u003e\n    {{! display_errors('title') }}\n  \u003c/div\u003e\n\u003c/form\u003e\n```\n\n### Repopulating the form\nIf the validation fails, we can repopulate the form with the user's input by adding the following code in the form input.\n\n```html\n\u003c!-- /resources/views/post/create.view.php --\u003e\n \u003cinput id=\"title\" type=\"text\" name=\"title\" value=\"{{ old('title') }}\"/\u003e\n ```\n\n ### Displaying customem error messages\n You can also display custom error messages for specific fields by calling a message method on the validator instance.\n\n ```php\n use Pocketframe\\Masks\\Validator;\n\nValidator::validate(\n    $request-\u003eall(), [\n        'title' =\u003e ['required', 'string'],\n        'body'  =\u003e ['required'],\n      ]\n    )\n      -\u003emessage([\n        'title.required' =\u003e 'You need to fill this',\n        'body.required'  =\u003e 'Body cannot be empty'\n      ])\n      -\u003efailed();\n```\n\n### Available validation rules\nPocketframe provides a set of built-in validation rules that you can use to validate user input. Here are some of the most commonly used rules:\n\n- `required`: This rule ensures that the field is not empty.\n  **Example**:\n  ```php\n  'name' =\u003e ['required']\n  ```\n- `string`: This rule ensures that the field contains only strings.\n  **Example**:\n  ```php\n  'name' =\u003e ['string']\n  ```\n- `email`: This rule ensures that the field contains a valid email address.\n  **Example**:\n  ```php\n  'email' =\u003e ['email']\n  ```\n- `numeric`: This rule ensures that the field contains only numeric values.\n  **Example**:\n  ```php\n  'age' =\u003e ['numeric']\n  ```\n- `min`: This rule ensures that the field contains a minimum number of characters.\n\n  **Example**:\n  ```php\n  'password' =\u003e ['min:8']\n  ```\n- `max`: This rule ensures that the field contains a maximum number of characters.\n\n  **Example**:\n  ```php\n  'username' =\u003e ['max:20']\n  ```\n- `Unique`: This rule ensures that the field contains a unique value.\n\n  **Example**:\n  ```php\n  use Pocketframe\\Validation\\Rules\\Unique;\n\n  'email' =\u003e [new Unique('users', 'email')]\n  ```\n\n- `date`: This rule ensures that the field contains a valid date.\n\n  **Example**:\n  ```php\n  'date_of_birth' =\u003e ['date']\n  ```\n\n- `image`: This rule ensures that the field contains a valid image file.\n\n  **Example**:\n  ```php\n  'avatar' =\u003e ['image']\n  ```\n- `nullable`: This rule allows the field to be empty.\n\n  **Example**:\n  ```php\n  'bio' =\u003e ['nullable']\n  ```\n\n- `lowercase`: This rule ensures that the field contains only lowercase characters.\n\n  **Example**:\n  ```php\n  'username' =\u003e ['lowercase']\n  ```\n\n- `uppercase`: This rule ensures that the field contains only uppercase characters.\n\n  **Example**:\n  ```php\n  'username' =\u003e ['uppercase']\n  ```\n\n- `sometime`: This rule ensures that the field contains only alphanumeric characters.\n-\n  **Example**:\n  ```php\n  'username' =\u003e ['sometime', 'required']\n  ```\n\n- `file`: This rule ensures that the field contains a valid file.\n\n  **Example**:\n   ```php\n   'avatar' =\u003e ['file']\n   ```\n\n\n## CLI\nPocketframe provides a command-line interface (CLI) that allows you to perform various tasks, such as start the serve, creating new controllers, clearing cache, and more.\n\n### Starting the server\nTo start the server, use the `serve` command:\n```bash\nphp pocket serve\n```\n\n### Creating a new controller\nTo create a new controller, use the `controller:create` command:\n```bash\nphp pocket controller:create PostController\n```\nThe generated controller will be placed in the app/Controllers Web or API directory.\n\n### Creating a middleware\nTo create a new middleware, use the `middleware:create` command:\n```bash\nphp pocket middleware:create AuthMiddleware\n```\nThe generated middleware will be placed in the app/Middleware directory.\n\n### Clear Views\nTo clear the views cache, use the `clear:views` command:\n```bash\nphp pocket clear:views\n```\nThis will clear the views cache, which can be useful if you have made changes to your views and want to see the changes immediately.\n\n### store:link\nTo create a symbolic link to the storage directory, use the `store:link` command:\n```bash\nphp pocket store:link\n```\nThis will create a symbolic link to the storage directory.\n\n### add:key\nTo add a new key to the .env file, use the `add:key` command:\n\n```bash\nphp pocket add:key\n```\n\n\n### Helper Functions\n\nPocketframe includes several helper functions to simplify common tasks, such as base_path(), config_path(), and routes_path().\n\n**Available Helper Functions:**\n\n- **base_path()**\n\n  Returns the absolute path from the base directory by appending the given path to the base path.\n  ```php\n  base_path('path/to/file');\n  ```\n  **Parameters:**\n  - `$path`: The path to append to the base path.\n\n- **urlIs()**\n\n  Checks if the current URL matches a given path.\n  ```php\n  urlIs('/about');\n  ```\n  **Parameters:**\n  - `$path`: The path to check if the current URL matches.\n\n- **abort()**\n\n  Aborts the request with an error page.\n  ```php\n  abort(404);\n  ```\n  **Parameters:**\n  - `$code`: The HTTP status code to abort the request with.\n\n- **authorize()**\n\n  Checks a condition and aborts with an error if the condition is false.\n  ```php\n  authorize($user-\u003eisAdmin());\n  ```\n  **Parameters:**\n  - `$condition`: The condition to check.\n\n- **redirect()**\n\n  Redirects to another URL path.\n  ```php\n  redirect('/login');\n  ```\n  **Parameters:**\n  - `$url`: The URL to redirect to.\n\n- **old()**\n\n  Retrieves an old input value from the session.\n  ```php\n  old('email');\n  ```\n  **Parameters:**\n  - `$key`: The key to retrieve the old input value from.\n\n- **env()**\n\n  Retrieves an environment variable from the server environment.\n  ```php\n  env('APP_NAME');\n  ```\n  **Parameters:**\n  - `$key`: The key to retrieve the environment variable from.\n\n- **numberToWords()**\n\n  Converts a number to words using the NumberFormatter class.\n  ```php\n  numberToWords(42);\n  ```\n  **Parameters:**\n  - `$number`: The number to convert to words.\n\n- **asset()**\n\n  Returns the full path to an asset by appending the asset path to the base path.\n  ```php\n  asset('css/app.css');\n  ```\n  **Parameters:**\n  - `$path`: The path to the asset.\n\n- **sanitize()**\n\n  Sanitizes a string by converting special characters to HTML entities.\n  ```php\n  sanitize($userInput);\n  ```\n  **Parameters:**\n  - `$string`: The string to sanitize.\n\n- **method()**\n\n  Generates a method field for HTML forms.\n  ```php\n  method('PUT');\n  ```\n  **Parameters:**\n  - `$method`: The method to generate the method field for.\n\n- **csrf_token()**\n\n  Generates a CSRF field for HTML forms.\n  ```php\n  csrf_token();\n  ```\n\n- **config_path()**\n\n  Returns the full path to a configuration file.\n  ```php\n  config_path('app');\n  ```\n  **Parameters:**\n  - `$path`: The path to the configuration file.\n\n- **config()**\n\n  Retrieves a configuration value from the configuration file.\n  ```php\n  config('app.name');\n  ```\n  **Parameters:**\n  - `$key`: The key to retrieve the configuration value from.\n\n- **routes_path()**\n\n  Returns the full path to a routes file.\n  ```php\n  routes_path('web');\n  ```\n  **Parameters:**\n  - `$path`: The path to the routes file.\n\n- **load_env()**\n\n  Loads environment variables from a file into $_ENV array.\n  ```php\n  load_env('.env');\n  ```\n  **Parameters:**\n  - `$path`: The path to the environment file.\n\n- **error_report()**\n\n  Configures error reporting settings.\n  ```php\n  error_report();\n  ```\n\n---\n\n### Contributing\n\nContributions to Pocketframe are welcome.\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpocketframe%2Fdocs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpocketframe%2Fdocs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpocketframe%2Fdocs/lists"}